Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
OpenGEODE
Commits
e7046b04
Commit
e7046b04
authored
Oct 31, 2015
by
Maxime Perrotin
Browse files
Synchronize parall states when they return
parent
d6e5d09a
Changes
5
Hide whitespace changes
Inline
Side-by-side
opengeode/AdaGenerator.py
View file @
e7046b04
...
...
@@ -205,6 +205,9 @@ LD_LIBRARY_PATH=. taste-gui -l
(
name
for
name
in
process
.
mapping
.
iterkeys
()
if
not
name
.
endswith
(
u
'START'
))))
reduced_statelist
=
{
s
for
s
in
full_statelist
if
s
not
in
parallel_states
}
if
parallel_states
:
# Parallel states in a state aggregation may terminate
full_statelist
.
add
(
u
'{}finished'
.
format
(
UNICODE_SEP
))
if
full_statelist
:
process_level_decl
.
append
(
u
'type States is ({});'
...
...
@@ -2015,17 +2018,42 @@ def _transition(tr, **kwargs):
# TODO
elif
tr
.
terminator
.
kind
==
'return'
:
string
=
''
aggregate
=
False
if
tr
.
terminator
.
substate
:
# XXX add to C generator
aggregate
=
True
# within a state aggregation, a return means that one
# of the parallel states becomes disabled, but it does
# not mean that the whole state aggregation can be
# exited. We must set this substate to a "finished"
# state until all the substates are returned. Then only
# call the overall state aggregation exit procedures.
code
.
append
(
u
'{ctxt}.{sub}{sep}state := {sep}finished;'
.
format
(
ctxt
=
LPREFIX
,
sub
=
tr
.
terminator
.
substate
,
sep
=
UNICODE_SEP
))
cond
=
u
'{ctxt}.{sib}{sep}state = {sep}finished'
conds
=
[
cond
.
format
(
sib
=
sib
,
ctxt
=
LPREFIX
,
sep
=
UNICODE_SEP
)
for
sib
in
tr
.
terminator
.
siblings
if
sib
.
lower
()
!=
tr
.
terminator
.
substate
.
lower
()]
code
.
append
(
u
'if {} then'
.
format
(
' and '
.
join
(
conds
)))
if
tr
.
terminator
.
next_id
==
-
1
:
if
tr
.
terminator
.
return_expr
:
stmts
,
string
,
local
=
expression
(
tr
.
terminator
.
return_expr
)
code
.
extend
(
stmts
)
local_decl
.
extend
(
local
)
code
.
append
(
'return{};'
code
.
append
(
u
'return{};'
.
format
(
' '
+
string
if
string
else
''
))
else
:
code
.
append
(
'trId := '
+
str
(
tr
.
terminator
.
next_id
)
+
';'
)
code
.
append
(
'goto next_transition;'
)
code
.
append
(
u
'trId := '
+
str
(
tr
.
terminator
.
next_id
)
+
';'
)
code
.
append
(
u
'goto next_transition;'
)
if
aggregate
:
code
.
append
(
u
'else'
)
code
.
append
(
u
'trId := -1;'
)
code
.
append
(
u
'goto next_transition;'
)
code
.
append
(
u
'end if;'
)
if
empty_transition
:
# If transition does not have any statement, generate an Ada 'null;'
code
.
append
(
'null;'
)
...
...
opengeode/Helper.py
View file @
e7046b04
...
...
@@ -49,13 +49,15 @@ def state_aggregations(process):
# { aggregate_name : [list of parallel states] }
aggregates
=
defaultdict
(
list
)
def
do_composite
(
comp
,
aggregate
=
''
):
''' Recursively find all state aggregations in order to create
variables to store the state of each parallel state '''
for
each
in
comp
.
composite_states
:
# CHECKME
pre
=
comp
.
statename
if
isinstance
(
comp
,
ogAST
.
StateAggregation
)
\
''' Recursively find all state aggregations in order to allow code
generator backends to store the state of each parallel state '''
pre
=
comp
.
statename
if
isinstance
(
comp
,
ogAST
.
StateAggregation
)
\
else
''
for
each
in
comp
.
composite_states
:
do_composite
(
each
,
pre
)
if
isinstance
(
each
,
ogAST
.
StateAggregation
):
# substate of the current state is a state aggregation
# -> set a flag in each terminator of the current state
for
term
in
comp
.
terminators
:
if
term
.
inputString
.
lower
()
==
each
.
statename
.
lower
():
term
.
next_is_aggregation
=
True
...
...
@@ -73,6 +75,14 @@ def state_aggregations(process):
for
each
in
process
.
terminators
:
if
each
.
inputString
.
lower
()
in
aggregates
:
each
.
next_is_aggregation
=
True
for
name
,
comp
in
aggregates
.
viewitems
():
# for each state aggregation. update the terminators
# of each parallel state with the name of all sibling states
# useful for backends to handle parallel state termination (return)
# since they have to synchronize with the sibling states
siblings
=
[
sib
.
statename
for
sib
in
comp
]
for
term
in
[
terms
for
sib
in
comp
for
terms
in
sib
.
terminators
]:
term
.
siblings
=
siblings
return
aggregates
...
...
opengeode/ogAST.py
View file @
e7046b04
...
...
@@ -466,6 +466,10 @@ class Terminator(object):
self
.
composite
=
None
# Flag to indicate if the nextstate is a state aggregation
self
.
next_is_aggregation
=
False
# List of sibling states if terminator is within a state aggregation
# (list of strings with all parallel states of the aggregation)
# Used by backend to synchronise parallel state terminations
self
.
siblings
=
[]
# If this terminator is within a state aggregation, store the name
# of the parallel substate (set by Helper.state_aggregations)
self
.
substate
=
''
...
...
opengeode/ogParser.py
View file @
e7046b04
...
...
@@ -2996,7 +2996,7 @@ def connect_part(root, parent, context):
# Ignore missing parent/statelist to allow local syntax check
statename
=
''
id_token
=
[]
# Keep track of the number of terminator statements follow the input
# Keep track of the number of terminator statements follow
ing
the input
# useful if we want to render graphs from the SDL model
terms
=
len
(
context
.
terminators
)
# Retrieve composite state
...
...
@@ -3046,16 +3046,34 @@ def connect_part(root, parent, context):
id_token
[
-
1
].
getTokenStopIndex
())
for
exitp
in
conn
.
connect_list
:
if
exitp
!=
''
and
not
exitp
in
nested
.
state_exitpoints
:
errors
.
append
([
'Exit point {ep} not defined in state {st}'
errors
.
append
([
u
'Exit point {ep} not defined in state {st}'
.
format
(
ep
=
exitp
,
st
=
statename
),
[
conn
.
pos_x
or
0
,
conn
.
pos_y
or
0
],
[]])
terminators
=
[
term
for
term
in
nested
.
terminators
if
term
.
kind
==
'return'
and
term
.
inputString
.
lower
()
==
exitp
]
if
not
terminators
:
errors
.
append
([
'No {rs} return statement in nested state {st}'
.
format
(
rs
=
exitp
,
st
=
statename
),
[
conn
.
pos_x
or
0
,
conn
.
pos_y
or
0
],
[]])
def
check_terminators
(
comp
):
terminators
=
[
term
for
term
in
comp
.
terminators
if
term
.
kind
==
'return'
and
term
.
inputString
.
lower
()
==
exitp
]
if
not
terminators
:
errors
.
append
([
u
'No {rs} return statement in nested state {st}'
.
format
(
rs
=
exitp
,
st
=
comp
.
statename
.
lower
()),
[
conn
.
pos_x
or
0
,
conn
.
pos_y
or
0
],
[]])
return
terminators
if
not
isinstance
(
nested
,
ogAST
.
StateAggregation
):
terminators
=
check_terminators
(
nested
)
else
:
# State aggregation: we must check that all parallel states
# contain indeed a return statement of the given name
def
siblings
(
aggregate
):
for
comp
in
aggregate
.
composite_states
:
if
not
isinstance
(
comp
,
ogAST
.
StateAggregation
):
yield
comp
else
:
for
each
in
siblings
(
comp
()):
yield
each
all_terms
=
map
(
check_terminators
,
siblings
(
nested
))
terminators
=
[]
map
(
terminators
.
extend
,
all_terms
)
for
each
in
terminators
:
# Set next transition, exact id to be found in postprocessing
each
.
next_trans
=
trans
...
...
tests/regression/test-aggregation2/og.pr
View file @
e7046b04
...
...
@@ -27,33 +27,6 @@ exit_aggreg;
PROCESS og;
STATE AGGREGATION wait;
SUBSTRUCTURE
STATE b;
SUBSTRUCTURE
/* CIF START (146, 55), (70, 35) */
START;
/* CIF PROCEDURECALL (77, 105), (208, 35) */
CALL writeln('[b] startup');
/* CIF NEXTSTATE (146, 155), (70, 35) */
NEXTSTATE b1;
/* CIF STATE (392, 144), (70, 35) */
STATE b2;
/* CIF INPUT (388, 199), (79, 35) */
INPUT for_b;
/* CIF PROCEDURECALL (308, 249), (239, 35) */
CALL writeln('[b] Going to b1');
/* CIF NEXTSTATE (392, 299), (70, 35) */
NEXTSTATE b1;
ENDSTATE;
/* CIF STATE (146, 155), (70, 35) */
STATE b1;
/* CIF INPUT (138, 210), (80, 35) */
INPUT for_b;
/* CIF PROCEDURECALL (58, 260), (239, 35) */
CALL writeln('[b] Going to b2');
/* CIF NEXTSTATE (143, 310), (70, 35) */
NEXTSTATE b2;
ENDSTATE;
ENDSUBSTRUCTURE;
STATE a;
SUBSTRUCTURE
in (hehe);
...
...
@@ -88,8 +61,8 @@ exit_aggreg;
INPUT reset_all(x);
/* CIF PROCEDURECALL (407, 158), (260, 35) */
CALL writeln('Reset_all from substate a2');
/* CIF
NEXTSTATE
(50
3
, 208), (
70
, 35) */
NEXTSTATE a2
;
/* CIF
RETURN
(5
2
0, 208), (
35
, 35) */
RETURN
;
ENDSTATE;
/* CIF STATE (0, 157), (70, 35) */
STATE a1;
...
...
@@ -101,12 +74,39 @@ exit_aggreg;
NEXTSTATE a2;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF STATE (170, 50), (70, 35) */
STATE a;
ENDSTATE;
STATE b;
SUBSTRUCTURE
/* CIF START (85, 55), (70, 35) */
START;
/* CIF PROCEDURECALL (16, 105), (208, 35) */
CALL writeln('[b] startup');
/* CIF NEXTSTATE (85, 155), (70, 35) */
NEXTSTATE b1;
/* CIF STATE (392, 144), (70, 35) */
STATE b2;
/* CIF INPUT (388, 199), (79, 35) */
INPUT for_b;
/* CIF PROCEDURECALL (267, 249), (321, 35) */
CALL writeln('[b] got for_b in b2, exiting state b...');
/* CIF RETURN (410, 299), (35, 35) */
RETURN ;
ENDSTATE;
/* CIF STATE (85, 155), (70, 35) */
STATE b1;
/* CIF INPUT (77, 210), (80, 35) */
INPUT for_b;
/* CIF PROCEDURECALL (-1, 260), (239, 35) */
CALL writeln('[b] Going to b2');
/* CIF NEXTSTATE (82, 310), (70, 35) */
NEXTSTATE b2;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF STATE (170, 160), (70, 35) */
STATE b;
ENDSTATE;
/* CIF STATE (170, 50), (70, 35) */
STATE a;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF TEXT (997, 328), (289, 140) */
-- Text area for declarations and comments
...
...
@@ -117,23 +117,29 @@ dcl x myInteger;
START;
/* CIF NEXTSTATE (0, 299), (70, 35) */
NEXTSTATE wait;
/* CIF STATE (649, 303), (87, 35) */
STATE the_end;
/* CIF INPUT (640, 358), (107, 35) */
INPUT reset_all(x);
/* CIF PROCEDURECALL (543, 408), (300, 35) */
CALL writeln('Entering again aggregation');
/* CIF NEXTSTATE (658, 458), (70, 35) */
NEXTSTATE wait;
ENDSTATE;
/* CIF STATE (390, 307), (67, 35) */
STATE wait;
/* CIF INPUT (
368
, 362), (110, 35) */
/* CIF INPUT (
202
, 362), (110, 35) */
INPUT exit_aggreg;
/* CIF PROCEDURECALL (
325
, 412), (195, 34) */
/* CIF PROCEDURECALL (
159
, 412), (195, 34) */
CALL writeln('got exit_aggreg');
/* CIF NEXTSTATE (
379
, 461), (87, 35) */
/* CIF NEXTSTATE (
213
, 461), (87, 35) */
NEXTSTATE the_end;
/* CIF CONNECT (506, 362), (0, 35) */
CONNECT ;
/* CIF PROCEDURECALL (365, 412), (281, 34) */
CALL writeln('Synchronous return from wait');
/* CIF NEXTSTATE (462, 461), (87, 35) */
NEXTSTATE the_end;
ENDSTATE;
/* CIF STATE (781, 303), (87, 35) */
STATE the_end;
/* CIF INPUT (772, 358), (107, 35) */
INPUT reset_all(x);
/* CIF PROCEDURECALL (676, 408), (300, 35) */
CALL writeln('Entering again aggregation');
/* CIF NEXTSTATE (791, 458), (70, 35) */
NEXTSTATE wait;
ENDSTATE;
ENDPROCESS og;
ENDBLOCK;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment