Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-esa committed Nov 19, 2023
2 parents e4c652e + fce141d commit ed5d584
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 10 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ The background pattern was downloaded from www.subtlepatterns.com

Changelog
=========
**4.1.20 (11/2023)**
- Fix code generation when combinining a history nextstate trying to go back
to a nested state that contains no inner state (just a start transition ending
with a RETURN).

**4.1.19 (11/2023)**
- Improve the management of temporary folders/files, and fix Windows support

Expand Down
31 changes: 23 additions & 8 deletions opengeode/AdaGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3197,27 +3197,42 @@ def _transition(tr, **kwargs):
# and "nextstate -*" to return to the previous state
# (parallel states only, not composite states at the moment
# as the previous state is not stored)
# TODO update C backend
code.append('-- Go back to the previous state')
if ns != "-*" and any(next_id
for next_id in tr.terminator.candidate_id.keys()
if next_id != -1):
code.append(f'case {LPREFIX}.State is')
done = []
for nid, sta in tr.terminator.candidate_id.items():
if nid != -1:
if tr.terminator.next_is_aggregation:
statement = ns != '-*' and f'{nid};' or 'trId := -1;'
else:
statement = f'trId := {nid};'
states_prefix = (f"{ASN1SCC}{s}" for s in sta)
done.extend(s.split(SEPARATOR)[0] for s in sta)
joined_states = " | ".join(states_prefix)
code.extend(
[f'when {joined_states} =>',
statement])

code.extend(['when others =>',
'trId := -1;',
'end case;'])
else:
if joined_states:
# There is a case where there is no state:
# if it is a nested state without any
# inner state (just a start stransition
# and ending with a return at the end). In
# that case it is not possible to be in
# this state when reaching the history
# nextstate.
code.extend(
[f'when {joined_states} =>',
statement])
remaining = (s for s in tr.terminator.candidate_id[-1]
if s not in done)
code.append(f'when others =>')
if remaining:
code.append('-- ' + " | ".join(remaining))
code.append('trId := -1;')
code.append('end case;')
else:
code.append('trId := -1; -- No change of state')
#code.append('goto Continuous_Signals;')
if not MONITORS:
code.append('goto Continuous_Signals;')
Expand Down
14 changes: 13 additions & 1 deletion opengeode/Helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,11 @@ def update_terminator(context, term, process):
for comp in context.composite_states:
if each.lower() == comp.statename.lower():
if isinstance(comp, ogAST.StateAggregation):
# parallel states
term.next_is_aggregation = True
term.candidate_id[each + sep + 'START'] = [each]
else:
# nested states
term.candidate_id[each + sep + 'START'] = \
[st for st in process.mapping.keys()
if st.startswith(each)
Expand Down Expand Up @@ -270,7 +272,7 @@ def update_composite_state(state, process):
entryproc = f'{prefix}entry'
call_entry.output = [{'outputName': entryproc,
'params': [], 'tmpVars': []}]

try:
process.transitions[each].actions.insert(0, call_entry)
except IndexError:
Expand Down Expand Up @@ -405,6 +407,16 @@ def set_transition_states(context, prefix=''):
propagate_inputs(each, process)
#del process.mapping[each.statename]

# If the terminator is a join (goto) we must propagate its possible state
# list to the terminators that follow the corresponding label.
for each in process.terminators:
if each.kind == 'join':
# find the corresponding label
for lab in process.labels:
if each.inputString.lower().strip() == lab.inputString.lower().strip():
for t in lab.terminators:
t.possible_states.extend(each.possible_states)

# Update terminators at process level
for each in process.terminators:
if each.kind == 'next_state':
Expand Down
1 change: 1 addition & 0 deletions opengeode/ogAST.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ def __init__(self, defName=''):
self.next_trans = None
# List of State that can lead to this terminator
# There can be several if terminator follows a floating label
# or a star state.
# Note, this field is updated by the Helper.flatten function
self.possible_states = []
# optional composite state content (type CompositeState)
Expand Down
3 changes: 3 additions & 0 deletions opengeode/ogParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3602,6 +3602,7 @@ def composite_state(root, parent=None, context=None):
errors.extend(err)
warnings.extend(warn)
comp.content.floating_labels.append(lab)
comp.labels.append(lab)
for proc, content in inner_proc:
# parse content of procedures - all scopes are set
err, warn = procedure_post(proc, content, context=comp)
Expand Down Expand Up @@ -3849,6 +3850,7 @@ def procedure_post(proc, content, parent=None, context=None):
errors.extend(err)
warnings.extend(warn)
proc.content.floating_labels.append(lab)
proc.labels.append(lab)
for new_proc, content in inner_proc:
# parse content of procedures
err, warn = procedure_post(new_proc, content, context=proc)
Expand Down Expand Up @@ -5025,6 +5027,7 @@ def process_definition(root, parent=None, context=None):
errors.extend(err)
warnings.extend(warn)
process.content.floating_labels.append(lab)
process.labels.append(lab)
elif child.type in (lexer.COMPOSITE_STATE, lexer.STATE_AGGREGATION):
comp, err, warn = composite_state(child,
parent=None,
Expand Down
2 changes: 1 addition & 1 deletion opengeode/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
#
# later on we use: version['__version__']
#
__version__ = '4.1.19'
__version__ = '4.1.20'
52 changes: 52 additions & 0 deletions tests/testsuite/test-nextstate/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
include ../shared.mk

ROOT_MODEL=og.pr

all: test-ada test-llvm

edit:
$(OPENGEODE) og.pr

test-parse:
$(OPENGEODE) og.pr --check

test-qgen-parse:
$(TESTQGEN_PARSE) $(ROOT_MODEL)

test-qgen-ada:
$(TESTQGEN_ADA) $(ROOT_MODEL)

test-qgen-c:
$(TESTQGEN_C) $(ROOT_MODEL)

test-qgen-gt-ada:
$(TESTQGEN_GT_ADA) $(ROOT_MODEL)

test-qgen-gt-c:
$(TESTQGEN_GT_C) $(ROOT_MODEL)

test-ada:
#make -f Makefile.og
$(OPENGEODE) *.pr --toAda
$(ASN1SCC) -Ada -typePrefix asn1Scc -equal *.asn
gnat make test_ada.ada && ./test_ada | diff expected -

test-c:
$(OPENGEODE) og.pr --toC
$(ASN1SCC) -c -typePrefix asn1Scc -renamePolicy 3 -equal -fp AUTO *.asn
$(CC) -O$(O) *.c -o test_c && ./test_c | diff expected -

test-if:
sdl2if og.pr


test-llvm:
$(OPENGEODE) og.pr --llvm -O$(O)
$(LLC) *.ll
$(CC) -O$(O) -c *.s


coverage:
coverage run -p $(OPENGEODE) og.pr --toAda

.PHONY: all edit test-parse test-ada test-llvm coverage
36 changes: 36 additions & 0 deletions tests/testsuite/test-nextstate/dataview-uniq.asn
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
TASTE-Dataview DEFINITIONS ::=


BEGIN

MyChoice ::= CHOICE {
a CHOICE {
b CHOICE {
c BOOLEAN,
d BOOLEAN
},
e BOOLEAN
},
f BOOLEAN
}

Some-Thing ::= MyInteger

MyInteger ::= INTEGER (0..255)

My-OctStr ::= OCTET STRING (SIZE (0..20))

SeqOf ::= SEQUENCE (SIZE(0..100)) OF MyInteger

Type1 ::= INTEGER(0..1)
Type2 ::= BOOLEAN

Toto ::= SEQUENCE { elem-1 Type1, elem-2 Type2 }

SeqBool ::= SEQUENCE(SIZE(1..5)) OF BOOLEAN
Enum-T ::= ENUMERATED {enum1}

default-seqof SeqOf ::= {4,7,9}
default-str My-OctStr ::= 'DEADBEEF'H

END
9 changes: 9 additions & 0 deletions tests/testsuite/test-nextstate/expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
enter wait
leave wait for run
enter and leave run
enter gone
leave gone 1
enter gone
leave gone 2
enter and leave go
enter gone
157 changes: 157 additions & 0 deletions tests/testsuite/test-nextstate/og.pr
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
system og;
/* CIF Keep Specific Geode Partition 'default' */
/* CIF TEXT (159, 221), (267, 140) */
-- Text area for declarations and comments

use dv comment 'dataview-uniq.asn';

signal dd; signal foo;
/* CIF ENDTEXT */
channel c
from env to og with dd,
foo;
endchannel;
block og;
signalroute r
from env to og with dd,
foo;
connect c and r;
/* CIF PROCESS (251, 59), (150, 75) */
process og;
state wait;
substructure
/* CIF procedure (15, 7), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
procedure entry;
/* CIF START (291, 152), (70, 35) */
START;
/* CIF PROCEDURECALL (254, 207), (142, 35) */
call writeln('enter wait');
/* CIF return (308, 262), (35, 35) */
return ;
endprocedure;
/* CIF START (260, 157), (70, 35) */
START;
/* CIF NEXTSTATE (260, 212), (70, 35) */
NEXTSTATE in_wait;
/* CIF state (115, 108), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state in_wait;
endstate;
endsubstructure;
state go;
substructure
/* CIF START (245, 254), (70, 35) */
START;
/* CIF PROCEDURECALL (184, 309), (190, 35) */
call writeln('enter and leave go');
/* CIF return (262, 364), (35, 35) */
return ;
endsubstructure;
state run;
substructure
/* CIF START (318, 129), (70, 35) */
START;
/* CIF PROCEDURECALL (255, 183), (195, 35) */
call writeln('enter and leave run');
/* CIF return (335, 238), (35, 35) */
return ;
endsubstructure;
state went;
substructure
out (e2,e1);
/* CIF START (210, 90), (70, 35) */
START;
/* CIF PROCEDURECALL (171, 145), (146, 35) */
call writeln('enter gone');
/* CIF NEXTSTATE (210, 195), (70, 35) */
NEXTSTATE gone;
/* CIF state (512, 90), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state gone;
endstate;
/* CIF state (210, 195), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state gone;
/* CIF input (87, 250), (70, 35) */
input dd;
/* CIF PROCEDURECALL (43, 305), (156, 35) */
call writeln('leave gone 1');
/* CIF return (104, 355), (35, 35) */
return e1;
/* CIF input (255, 250), (70, 35) */
input foo;
/* CIF PROCEDURECALL (211, 305), (156, 35) */
call writeln('leave gone 2');
/* CIF return (272, 360), (35, 35) */
return e2;
endstate;
endsubstructure;
/* CIF START (159, 174), (70, 35) */
START;
/* CIF NEXTSTATE (159, 229), (70, 35) */
NEXTSTATE wait;
/* CIF label (721, 628), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
connection hello:
/* CIF NEXTSTATE (721, 683), (70, 35) */
NEXTSTATE -;
/* CIF End Label */
endconnection;
/* CIF state (511, 173), (99, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state *(wait, went);
/* CIF input (528, 228), (70, 35) */
input dd;
/* CIF NEXTSTATE (528, 283), (70, 35) */
NEXTSTATE -;
endstate;
/* CIF state (223, 520), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state run;
/* CIF connect (223, 575), (70, 35) */
connect ;
/* CIF NEXTSTATE (223, 630), (70, 35) */
NEXTSTATE went;
endstate;
/* CIF state (455, 488), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state go
/* CIF comment (545, 486), (94, 38) */
comment 'in theory:
Infinite loop';
/* CIF connect (455, 543), (70, 35) */
connect ;
/* CIF join (472, 598), (35, 35) */
join hello;
endstate;
/* CIF state (278, 186), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state wait;
/* CIF input (278, 241), (70, 35) */
input dd;
/* CIF label (278, 296), (70, 35) */
blue:
/* CIF PROCEDURECALL (220, 346), (184, 35) */
call writeln('leave wait for run');
/* CIF NEXTSTATE (278, 396), (70, 35) */
NEXTSTATE run;
endstate;
/* CIF state (695, 395), (70, 35) */
/* CIF Keep Specific Geode Partition 'default' */
state went
/* CIF comment (785, 395), (111, 38) */
comment 'should not be
an infinite loop';
/* CIF connect (650, 450), (70, 35) */
connect e1;
/* CIF join (667, 505), (35, 35) */
join hello;
/* CIF connect (740, 450), (70, 35) */
connect e2;
/* CIF NEXTSTATE (740, 505), (70, 35) */
NEXTSTATE go;
endstate;
endprocess og;
endblock;
endsystem;
Loading

0 comments on commit ed5d584

Please sign in to comment.