Commit 38d82a13 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Preliminary support of nested states

parent 462ee1e0
......@@ -1245,6 +1245,13 @@ def _transition(tr):
elif tr.terminator.kind == 'stop':
pass
# TODO
elif tr.terminator.kind == 'return':
string = ''
if tr.terminator.return_expr:
stmts, string, local = generate(tr.terminator.return_expr)
code.extend(stmts)
local_decl.extend(local)
code.append('return{};'.format(' ' + string if string else ''))
if empty_transition:
# If transition does not have any statement, generate an Ada 'null;'
code.append('null;')
......
......@@ -287,7 +287,7 @@ def _terminator(ast, scene, parent, states):
scene=scene, parent=symbol, states=states)
elif ast.kind == 'join':
symbol = sdlSymbols.Join(parent, ast)
elif ast.kind == 'stop':
elif ast.kind in ('return', 'stop'):
symbol = sdlSymbols.ProcedureStop(parent, ast)
else:
raise TypeError('Unsupported terminator: ' + repr(ast))
......
......@@ -371,7 +371,7 @@ class ProcedureCall(Output):
class Terminator(object):
''' Terminator elements (join, nextstate, stop) '''
def __init__(self, defName='Wait'):
def __init__(self, defName=''):
''' Initialize terminator attributes '''
self.inputString = defName
self.pos_x = None
......@@ -380,7 +380,7 @@ class Terminator(object):
self.height = 35
self.line = None
self.charPositionInLine = None
# one of 'next_state' 'join' 'stop'
# one of 'next_state' 'join' 'stop', 'return'
self.kind = None
# optional comment symbol
self.comment = None
......@@ -388,6 +388,10 @@ class Terminator(object):
self.hyperlink = None
# optional Label instance (to be placed just before the terminator)
self.label = None
# Return expression
self.return_expr = None
# via clause, used for entering nested state with an entry point
self.via = None
def __repr__(self):
''' Debug output for terminators '''
......@@ -635,7 +639,9 @@ class Procedure(object):
# Formal parameters - list of dict:
# [{'name': str, 'direction': 'in'/'out', 'type': str}]
self.fpar = []
# start, states, terminators, text areas, floating_labels (see Process)
# return type (ASN.1)
self.return_type = None
# start, terminators, text areas, floating_labels (see Process)
#self.start = None
#self.states = []
self.terminators = []
......@@ -643,9 +649,9 @@ class Procedure(object):
# Keep a list of labels and floating labels - useful for backends
self.labels = []
#self.floating_labels = []
# Inherited procedures and operators XXX should be lists no?
self.procedures = {}
self.operators = {}
# Inherited procedures and operators
self.procedures = []
self.operators = []
# inner procedures and operators (see Process for format)
#self.inner_procedures = []
self.inner_operators = []
......
......@@ -1225,6 +1225,27 @@ def procedure(root, parent=None, context=None):
'Unsupported construct in procedure, type: ' +
str(child.type) + ' - line ' + str(child.getLine()) +
' - string: ' + str(proc.inputString))
for each in proc.terminators:
# check that RETURN statements type is correct
if not proc.return_type and each.return_expr:
errors.append('No return value expected in procedure '
+ proc.inputString)
elif proc.return_type and each.return_expr:
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimPath()
check_expr.left.exprType = proc.return_type
check_expr.right = each.return_expr
try:
fix_expression_types(check_expr, context)
except (TypeError, AttributeError) as err:
errors.append(str(err))
# Id of fd_expr may have changed (enumerated, choice)
each.return_expr = check_expr.right
elif proc.return_type and not each.return_expr:
errors.append('Missing return value in procedure '
+ proc.inputString)
else:
continue
return proc, errors, warnings
......@@ -1585,6 +1606,8 @@ def process_definition(root, parent=None):
errors.extend(err)
warnings.extend(warn)
process.content.floating_labels.append(lab)
elif child.type == lexer.COMPOSITE_STATE:
warnings.append('Composite state detected but not supported yet')
elif child.type == lexer.REFERENCED:
process.referenced = True
else:
......@@ -2045,6 +2068,27 @@ def decision(root, parent, context):
return dec, errors, warnings
def nextstate(root):
''' Parse a NEXTSTATE [VIA State_Entry_Point] '''
# TODO = check that the via clause leads to a defined nested state
# and entry point
next_state_id, via = '', None
for child in root.getChildren():
if child.type == lexer.ID:
next_state_id = child.text
elif child.type == lexer.DASH:
next_state_id = '-'
elif child.type == lexer.VIA:
if next_state_id.strip() != '-':
via = child.getChild(0).text
else:
raise TypeError('"History" NEXTSTATE'
' cannot have a "via" clause')
else:
raise TypeError('NEXTSTATE undefined construct')
return next_state_id, via
def terminator_statement(root, parent, context):
''' Parse a terminator (NEXTSTATE, JOIN, STOP) '''
errors = []
......@@ -2064,7 +2108,11 @@ def terminator_statement(root, parent, context):
lab.terminators = [t]
elif term.type == lexer.NEXTSTATE:
t.kind = 'next_state'
t.inputString = term.getChild(0).toString()
try:
t.inputString, t.via = nextstate(term)
except TypeError as err:
errors.append(str(err))
#t.inputString = term.getChild(0).toString()
t.line = term.getChild(0).getLine()
t.charPositionInLine = term.getChild(0).getCharPositionInLine()
# Add next state infos at process level
......@@ -2079,6 +2127,15 @@ def terminator_statement(root, parent, context):
elif term.type == lexer.STOP:
t.kind = 'stop'
context.terminators.append(t)
elif term.type == lexer.RETURN:
t.kind = 'return'
if term.children:
t.return_expr, err, warn = expression(
term.getChild(0), context)
t.inputString = t.return_expr.inputString
errors.extend(err)
warnings.extend(warn)
context.terminators.append(t)
elif term.type == lexer.COMMENT:
t.comment, _, _ = end(term)
elif term.type == lexer.HYPERLINK:
......
......@@ -1307,7 +1307,7 @@ class SDL_View(QtGui.QGraphicsView, object):
if type(error[0]) == list:
# should be fixed now, CHECKME - NO, NOT FULLY FIXED
# problem is in decision answers branches
error[0] = 'Internal error - ' + error[0][0]
error[0] = 'Internal error - ' + str(error[0])
LOG.error(error[0])
item = QtGui.QListWidgetItem(u'[ERROR] ' + error[0])
if len(error) == 2:
......@@ -1316,7 +1316,7 @@ class SDL_View(QtGui.QGraphicsView, object):
self.messages_window.addItem(item)
for warning in warnings:
LOG.warning(warning[0])
item = QtGui.QListWidgetItem(u'[WARNING] ' + warning[0])
item = QtGui.QListWidgetItem(u'[WARNING] ' + str(warning[0]))
if len(warning) == 2:
item.setData(Qt.UserRole, warning[1])
if self.messages_window:
......
/*
OpenGEODE
ANTLR 3.1.3 grammar for the SDL92 langage
Includes the following features from SDL2000+:
- FOR loops in TASKs
- Composite states
author: Maxime Perrotin
*/
......@@ -109,6 +112,7 @@ tokens {
PARAMNAMES;
ASN1;
FLOATING_LABEL;
COMPOSITE_STATE;
}
......@@ -199,14 +203,15 @@ process_definition
: PROCESS process_id number_of_instances? REFERENCED end
-> ^(PROCESS process_id number_of_instances? REFERENCED)
| PROCESS process_id number_of_instances? end
(text_area | procedure)*
(text_area | procedure | composite_state)*
processBody? ENDPROCESS process_id?
end
-> ^(PROCESS process_id number_of_instances?
text_area* procedure* processBody?);
text_area* procedure* composite_state* processBody?);
// procedure: missing the RETURNS statement (TODO)
// procedure: missing the RETURNS statement
// (TODO - but check new SDL2000 syntax that has no RETURNS token)
procedure
: cif?
PROCEDURE procedure_id end
......@@ -286,9 +291,9 @@ processBody
start
: cif?
hyperlink?
START end
START name=state_entry_point_name? end
transition?
-> ^(START cif? hyperlink? end? transition?);
-> ^(START cif? hyperlink? $name? end? transition?);
floating_label
......@@ -318,11 +323,36 @@ statelist
exception_state
:
'(' statename (',' statename)* ')'
: '(' statename (',' statename)* ')'
-> statename+;
composite_state
: STATE statename e=end
SUBSTRUCTURE
cnx=connection_points*
body=composite_state_body
ENDSUBSTRUCTURE statename? f=end
-> ^(COMPOSITE_STATE statename $cnx* $body $e?);
connection_points
: IN state_entry_exit_points e=end
-> ^(IN state_entry_exit_points $e?)
| OUT state_entry_exit_points f=end
-> ^(OUT state_entry_exit_points $f?);
state_entry_exit_points
: '(' statename (',' statename)* ')'
-> statename+;
composite_state_body
: (text_area | procedure | composite_state)*
start+ (state | floating_label)*;
state_part
: input_part
//| priority_input // Not supported
......@@ -347,7 +377,7 @@ enabling_condition
continuous_signal
: PROVIDED expression end
(PRIORITY integer_literal_name=INT end)?
(PRIORITY integer_literal_name=INT end)?
transition
-> ^(PROVIDED expression $integer_literal_name? transition);
......@@ -900,7 +930,7 @@ label
terminator
: nextstate | join | stop | return_stmt;
: nextstate | join | stop | return_stmt;
join
......@@ -922,10 +952,14 @@ nextstate
nextstatebody
: statename
: statename via?
| dash_nextstate;
via : VIA state_entry_point_name
-> ^(VIA state_entry_point_name);
end
: (cif? hyperlink? COMMENT StringLiteral)? SEMI
-> ^(COMMENT cif? hyperlink? StringLiteral)?;
......@@ -974,6 +1008,7 @@ symbolname
| PROCEDURE
| PROCEDURE_CALL
| STOP
| RETURN
| DECISION
| TEXT
| TASK
......@@ -1005,6 +1040,8 @@ dash_nextstate : DASH;
connector_name : ID;
signal_id : ID;
statename : ID;
state_entry_point_name
: ID;
variable_id : ID;
literal_id : ID | INT;
process_id : ID;
......@@ -1035,7 +1072,7 @@ view_id : ID;
sort_id : ID;
syntype_id : ID;
stimulus_id : ID;
ASSIG_OP : ':=';
ASSIG_OP : ':=';
L_BRACKET : '{';
R_BRACKET : '}';
L_PAREN : '(';
......@@ -1113,7 +1150,10 @@ PLUS : '+';
DOT : '.';
APPEND : '//';
IN : I N;
OUT : O U T;
INOUT : I N '/' O U T;
SUBSTRUCTURE : S U B S T R U C T U R E;
ENDSUBSTRUCTURE : E N D S U B S T R U C T U R E;
FPAR : F P A R;
PARAM : P A R A M;
EQ : '=';
......
This diff is collapsed.
This diff is collapsed.
......@@ -498,7 +498,7 @@ class ProcedureStop(Join, object):
redbold = SDL_REDBOLD
def __init__(self, parent=None, ast=None):
if not ast:
ast = ogAST.Terminator(defName='ret')
ast = ogAST.Terminator(defName='')
ast.pos_y = 0
ast.width = 35
ast.height = 35
......@@ -517,7 +517,7 @@ class ProcedureStop(Join, object):
path.moveTo(point1)
path.lineTo(point2)
path.moveTo(point3)
path.lineTo(point4)
path.lineTo(point4)
self.setPath(path)
# call Join superclass, otherwise symbol will take Join shape
super(Join, self).set_shape(circ, circ)
......@@ -525,9 +525,10 @@ class ProcedureStop(Join, object):
def __repr__(self):
''' Return the PR string for this symbol '''
pos = self.scenePos()
return('/* CIF STOP ({x}, {y}), ({w}, {h}) */\n'
return('/* CIF RETURN ({x}, {y}), ({w}, {h}) */\n'
'{hlink}'
'STOP;'.format(hlink=repr(self.text),
'RETURN {val};'.format(
val=str(self.text), hlink=repr(self.text),
x=int(pos.x()), y=int(pos.y()),
w=int(self.boundingRect().width()),
h=int(self.boundingRect().height())))
......
EXAMPLES=test1 test2 test3 test4 test5 test6 test7 test8 test9
EXAMPLES=test1 test2 test3 test4 test5 test6 test7 test8 test9 test10
all:
for v in $(EXAMPLES) ; do make -C $$v clean all || exit 1 ; done
......
......@@ -33,7 +33,7 @@ DCL fce_selected_counter Counter_ty;
-- Fig 6-7, FCE Stop control asserted
DCL FCE_Stop_Control Bool_ty;
DCL FCE_Stop_Control Bool_ty := false;
-- As defined in Figure 6-6
TIMER mmo_sep_check_delay;
......@@ -315,8 +315,8 @@ TASK fce_selected_counter := 0
COMMENT 'Used to count 2 consecutive checks
of FCE Selected and Arr_Dep=true
(cf. Fig 6-5)';
/* CIF NEXTSTATE (-739, -6), (100, 50) */
NEXTSTATE Ready;
/* CIF NEXTSTATE (-752, -6), (127, 50) */
NEXTSTATE Ready via toto;
/* CIF ANSWER (-1021, -286), (76, 35) */
(FALSE):
/* CIF NEXTSTATE (-1060, -231), (155, 50) */
......
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