Commit e3146a5e authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Work on state aggregation

parent a3b9ef9f
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
import logging import logging
import traceback import traceback
import os import os
from itertools import chain
from singledispatch import singledispatch from singledispatch import singledispatch
import ogAST import ogAST
...@@ -181,22 +182,13 @@ LD_LIBRARY_PATH=. taste-gui -l ...@@ -181,22 +182,13 @@ LD_LIBRARY_PATH=. taste-gui -l
# In case model has nested states, flatten everything # In case model has nested states, flatten everything
Helper.flatten(process, sep=UNICODE_SEP) Helper.flatten(process, sep=UNICODE_SEP)
# Debug: # Process State aggregations (Parallel states)
# After flattening, display all states, recursively. We need to find the
# composite states internal to state aggregations.
def do_composite(comp, aggregate=''):
for each in comp.composite_states:
pre = comp.statename if isinstance(comp, ogAST.StateAggregation) \
else ''
do_composite(each, pre)
if isinstance(comp, ogAST.StateAggregation):
print 'State Aggregation:', comp.statename.encode('utf-8')
if aggregate:
print 'In aggregation:', aggregate.encode('utf-8'), comp.statename.encode('utf-8')
for each in process.composite_states:
do_composite(each)
# 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)
for each in substates:
print '{}{}state'.format(each.encode('utf-8'), UNICODE_SEP.encode('utf-8'))
# End debug # End debug
...@@ -209,8 +201,9 @@ LD_LIBRARY_PATH=. taste-gui -l ...@@ -209,8 +201,9 @@ LD_LIBRARY_PATH=. taste-gui -l
process_level_decl = [] process_level_decl = []
# Establish the list of states (excluding START states) # Establish the list of states (excluding START states)
statelist = ', '.join(name for name in process.mapping.iterkeys() statelist = ', '.join(chain(aggregates, (name for name in
if not name.endswith(u'START')) or 'No_State' process.mapping.iterkeys()
if not name.endswith(u'START')))) or 'No_State'
if statelist: if statelist:
states_decl = u'type States is ({});'.format(statelist) states_decl = u'type States is ({});'.format(statelist)
process_level_decl.append(states_decl) process_level_decl.append(states_decl)
...@@ -221,6 +214,11 @@ LD_LIBRARY_PATH=. taste-gui -l ...@@ -221,6 +214,11 @@ LD_LIBRARY_PATH=. taste-gui -l
if statelist: if statelist:
process_level_decl.append('state : States;') process_level_decl.append('state : States;')
# State aggregation: add list of substates (XXX to be added in C generator)
for each in substates:
process_level_decl.append(u'{}{}state: States;'
.format(each, UNICODE_SEP))
for var_name, (var_type, def_value) in process.variables.viewitems(): for var_name, (var_type, def_value) in process.variables.viewitems():
if def_value: if def_value:
# Expression must be a ground expression, i.e. must not # Expression must be a ground expression, i.e. must not
......
...@@ -13,8 +13,10 @@ ...@@ -13,8 +13,10 @@
input-state-transition input-state-transition
sorted_fields(SEQ/CHOICE) : returns the ordered list of fields sorted_fields(SEQ/CHOICE) : returns the ordered list of fields
of an ASN.1 SEQUENCE or CHOICE type of an ASN.1 SEQUENCE or CHOICE type
state_aggregations: enrich AST with state aggregation flags,
and return list of substates and parallel states
Copyright (c) 2012-2014 European Space Agency Copyright (c) 2012-2015 European Space Agency
Designed and implemented by Maxime Perrotin Designed and implemented by Maxime Perrotin
...@@ -33,7 +35,40 @@ import ogAST ...@@ -33,7 +35,40 @@ import ogAST
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
__all__ = ['flatten', 'rename_everything', 'inner_labels_to_floating', __all__ = ['flatten', 'rename_everything', 'inner_labels_to_floating',
'map_input_state', 'sorted_fields'] 'map_input_state', 'sorted_fields', 'state_aggregations']
def state_aggregations(process):
''' Return the list of state aggregations and substates '''
aggregates, substates = [], []
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:
pre = comp.statename if isinstance(comp, ogAST.StateAggregation) \
else ''
do_composite(each, pre)
if isinstance(each, ogAST.StateAggregation):
for term in comp.terminators:
if term.inputString.lower() == each.statename.lower():
each.next_is_aggregation = True
if isinstance(comp, ogAST.StateAggregation):
aggregates.append(comp.statename)
elif aggregate: # Elif: no state for an inner state aggregation
# Composite state inside a state aggregation
substates.append(comp.statename)
# 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
# use the parallel substate name when generating code.
for each in comp.terminators:
each.substate = comp.statename
for each in process.composite_states:
do_composite(each)
for each in process.terminators:
if each.inputString.lower() in aggregates:
each.next_is_aggregation = True
return aggregates, substates
def map_input_state(process): def map_input_state(process):
......
...@@ -463,6 +463,11 @@ class Terminator(object): ...@@ -463,6 +463,11 @@ class Terminator(object):
self.possible_states = [] self.possible_states = []
# optional composite state content (type CompositeState) # optional composite state content (type CompositeState)
self.composite = None self.composite = None
# Flag to indicate if the nextstate is a state aggregation
self.is_aggregation = False
# If this terminator is within a state aggregation, store the name
# of the parallel substate (set by Helper.state_aggregations)
self.substate = ''
def trace(self): def trace(self):
''' Debug output for terminators ''' ''' Debug output for terminators '''
......
...@@ -144,7 +144,7 @@ state'; ...@@ -144,7 +144,7 @@ state';
/* CIF LABEL (929, 366), (88, 35) */ /* CIF LABEL (929, 366), (88, 35) */
nslabel: nslabel:
/* CIF NEXTSTATE (938, 416), (70, 35) */ /* CIF NEXTSTATE (938, 416), (70, 35) */
NEXTSTATE hello; NEXTSTATE AggregNextToHello;
/* CIF LABEL (512, 472), (141, 35) */ /* CIF LABEL (512, 472), (141, 35) */
CONNECTION another_floating: CONNECTION another_floating:
/* CIF PROCEDURECALL (526, 522), (113, 35) */ /* CIF PROCEDURECALL (526, 522), (113, 35) */
...@@ -175,6 +175,8 @@ result := 33; ...@@ -175,6 +175,8 @@ result := 33;
/* CIF JOIN (24, 229), (35, 35) */ /* CIF JOIN (24, 229), (35, 35) */
JOIN to_label; JOIN to_label;
ENDSTATE; ENDSTATE;
state AggregNextToHello;
endstate;
ENDSUBSTRUCTURE; ENDSUBSTRUCTURE;
/* CIF TEXT (51, 0), (298, 56) */ /* CIF TEXT (51, 0), (298, 56) */
-- This system tests nested states -- This system tests nested states
......
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