Commit b7d1ce87 authored by Maxime Perrotin's avatar Maxime Perrotin

Use the proper list of states in 1st-level switch-case

parent 7c1d739d
......@@ -184,12 +184,13 @@ LD_LIBRARY_PATH=. taste-gui -l
# Process State aggregations (Parallel states)
# Get list of parallel states to be added to the global list of states,
# and list of their inner substates
#aggregates, substates = Helper.state_aggregations(process)
# Find recursively in the AST all state aggregations
# Format: {'aggregation_name' : [list of ogAST.CompositeState]
aggregates = Helper.state_aggregations(process)
# End debug
# Extract the list of parallel states names inside the composite states
# of state aggregations XXX add to C generator
parallel_states = Helper.parallel_states(aggregates)
# Make an maping {input: {state: transition...}} in order to easily
# generate the lookup tables for the state machine runtime
......@@ -199,18 +200,20 @@ LD_LIBRARY_PATH=. taste-gui -l
process_level_decl = []
# Establish the list of states (excluding START states)
statelist = ', '.join(chain(aggregates.viewkeys(), (name for name in
if not name.endswith(u'START')))) or 'No_State'
if statelist:
states_decl = u'type States is ({});'.format(statelist)
# Establish the list of states (excluding START states) XXX update C backend
full_statelist = list(chain(aggregates.viewkeys(),
(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 full_statelist:
process_level_decl.append(u'type States is ({});'
.format(u', '.join(full_statelist) or u'No_State'))
# Generate the code to declare process-level context
process_level_decl.extend(['type {}_Ty is'.format(LPREFIX), 'record'])
if statelist:
if full_statelist:
process_level_decl.append('state : States;')
# State aggregation: add list of substates (XXX to be added in C generator)
......@@ -218,7 +221,7 @@ LD_LIBRARY_PATH=. taste-gui -l
for substates in aggregates.viewvalues():
for each in substates:
process_level_decl.append(u'{}{}state: States;'
.format(each, UNICODE_SEP))
.format(each.statename, UNICODE_SEP))
for var_name, (var_type, def_value) in process.variables.viewitems():
if def_value:
......@@ -253,7 +256,8 @@ LD_LIBRARY_PATH=. taste-gui -l
aggreg_start_proc.extend([u'{} is'.format(proc_name),
.format(sub=subname, sep=UNICODE_SEP)
for subname in substates)
#Following done in the transition, not needed here
#aggreg_start_proc.append(u'{ctxt}.state := {name};'
......@@ -408,7 +412,7 @@ package {process_name} is'''.format(process_name=process_name,
taste_template.append('case {ctxt}.state is'.format(ctxt=LPREFIX))
for state in process.mapping.viewkeys():
for state in reduced_statelist: #process.mapping.viewkeys(): XXX C Backend
if state.endswith(u'START'):
taste_template.append(u'when {state} =>'.format(state=state))
......@@ -14,7 +14,8 @@
sorted_fields(SEQ/CHOICE) : returns the ordered list of fields
of an ASN.1 SEQUENCE or CHOICE type
state_aggregations: enrich AST with state aggregation flags,
and return list of substates and parallel states
and return the list of substates of aggregations
parallel_states: return a list of strings naming all parallel states
Copyright (c) 2012-2015 European Space Agency
......@@ -35,17 +36,22 @@ import ogAST
LOG = logging.getLogger(__name__)
__all__ = ['flatten', 'rename_everything', 'inner_labels_to_floating',
'map_input_state', 'sorted_fields', 'state_aggregations']
'map_input_state', 'sorted_fields', 'state_aggregations',
def state_aggregations(process):
''' Return the list of state aggregations and substates '''
''' Explore recursively the AST to find all state aggregations, and
return the composite states inside them
input: ogAST.Process element
output: {state_aggregation: {list of ogAST.CompositeState}
# { 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:
for each in comp.composite_states: # CHECKME
pre = comp.statename if isinstance(comp, ogAST.StateAggregation) \
else ''
do_composite(each, pre)
......@@ -55,7 +61,7 @@ def state_aggregations(process):
term.next_is_aggregation = True
if aggregate and not isinstance(comp, ogAST.StateAggregation):
# Composite state inside a state aggregation
# Here, all the terminators inside the composite states must
# be flagged with the name of the substate so that the NEXTSTATE
# will not be using the main "context.state" variable but will
......@@ -70,6 +76,17 @@ def state_aggregations(process):
return aggregates
def parallel_states(aggregates):
''' Given a mapping obtained with state_aggregation(process), extract
all parallel states and return a list of state names '''
parallel_states = []
for name, comp in aggregates.viewitems():
for each in comp:
parallel_states.extend(name for name in each.mapping.viewkeys()
if not name.endswith(u'START'))
return parallel_states
def map_input_state(process):
''' Create a mapping dict {input1: {state1: transition, ...}, ...} '''
mapping = defaultdict(dict)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment