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
77140fd9
Commit
77140fd9
authored
Jul 23, 2020
by
Maxime Perrotin
Browse files
Merge branch 'feature_stateType'
parents
a493a3df
52ae9e35
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
77140fd9
...
...
@@ -175,8 +175,13 @@ The background pattern was downloaded from www.subtlepatterns.com
Changelog
=========
**3.1.3 (07/2020)**
-
Fix issue finding ASN.1 files when model loaded from another folder
**3.2.1 (07/2020)**
-
Fix issue with the "present" operator
-
Move the context declaration to the .ads
-
Always expose the Get_State function (returns char
*
to C)
**3.2.0 (07/2020)**
-
Add basic support for state type/instance
**3.1.2 (07/2020)**
-
Reinforce syntax error checking and reporting
...
...
opengeode/AdaGenerator.py
View file @
77140fd9
...
...
@@ -424,8 +424,9 @@ LD_LIBRARY_PATH=./lib:. opengeode-simulator
context_decl
.
append
(
u
'{ctxt}_bk: {ctxt}_Ty;'
.
format
(
ctxt
=
LPREFIX
))
if
not
simu
and
not
instance
:
process_level_decl
.
extend
(
context_decl
)
# Don't declare the context in the adb - declare it in the ads
#if not simu and not instance:
# process_level_decl.extend(context_decl)
aggreg_start_proc
=
[]
start_transition
=
[]
...
...
@@ -490,7 +491,7 @@ LD_LIBRARY_PATH=./lib:. opengeode-simulator
use {process_name}_newtypes;'''
.
format
(
process_name
=
process_name
)
\
if
process
.
user_defined_types
else
u
''
taste_template
=
[
u
'''
\
taste_template
=
[
f
'''
\
-- This file was generated automatically by OpenGEODE: DO NOT MODIFY IT !
with System.IO;
...
...
@@ -499,22 +500,7 @@ use System.IO;
with Ada.Unchecked_Conversion;
with Ada.Numerics.Generic_Elementary_Functions;
{dataview}
{custom_data_types}
with Interfaces;
use Interfaces;
{C}
{Context}
package body {process_name} is'''
.
format
(
process_name
=
process_name
,
dataview
=
asn1_modules
,
custom_data_types
=
include_custom_types
,
C
=
'with Interfaces.C.Strings;
\n
'
'use Interfaces.C.Strings;'
if
simu
else
''
,
Context
=
f
"with
{
import_context
}
; use
{
import_context
}
;"
if
import_context
else
''
)
package body
{
process_name
}
is'''
if
not
instance
else
u
"package body {} is"
.
format
(
process_name
)]
generic_spec
,
instance_decl
=
""
,
""
...
...
@@ -530,43 +516,51 @@ package body {process_name} is'''.format(
# FPAR could be set for Context Parameters. They are available here
# Generate the source file (.ads) header
ads_template
=
[
u
'''
\
# Stop conditions must import the SDL model they observe
imp_str
=
f
"with
{
import_context
}
; use
{
import_context
}
;"
\
if
import_context
else
''
ads_template
=
[
f
'''
\
-- This file was generated automatically by OpenGEODE: DO NOT MODIFY IT !
{dataview}
{C}
{instance}
{generic}
package {process_name} is'''
.
format
(
generic
=
generic_spec
,
instance
=
instance_decl
,
process_name
=
process_name
,
dataview
=
asn1_modules
,
C
=
'with Interfaces.C.Strings,
\n
'
' Ada.Characters.Handling;
\n
'
'use Interfaces.C.Strings,
\n
'
' Ada.Characters.Handling;'
if
simu
else
''
)]
with Interfaces,
Interfaces.C.Strings,
Ada.Characters.Handling;
use Interfaces,
Interfaces.C.Strings,
Ada.Characters.Handling;
{
asn1_modules
}
{
include_custom_types
}
{
imp_str
}
{
instance_decl
}
{
generic_spec
}
'''
.
strip
()
+
f
'''
package
{
process_name
}
with Elaborate_Body is'''
]
dll_api
=
[]
if
simu
:
if
not
instance
:
ads_template
.
extend
(
context_decl
)
if
not
generic
and
not
instance
:
# Add function allowing to trace current state as a string
ads_template
.
append
(
f
"function Get_State return chars_ptr "
f
"is (New_String (States'Image (
{
LPREFIX
}
.State)))"
f
" with Export, Convention => C, "
f
'Link_Name => "
{
process_name
.
lower
()
}
_state";'
)
if
simu
:
ads_template
.
append
(
'-- API for simulation via DLL'
)
dll_api
.
append
(
'-- API to remotely change internal data'
)
# Add function allowing to trace current state as a string
process_level_decl
.
append
(
"function Get_State return chars_ptr "
"is (New_String(states'Image({ctxt}.state)))"
" with Export, Convention => C, "
'Link_Name => "{name}_state";'
.
format
(
name
=
process_name
,
ctxt
=
LPREFIX
))
set_state_decl
=
"procedure Set_State(New_State : chars_ptr)"
ads_template
.
append
(
"{};"
.
format
(
set_state_decl
))
ads_template
.
append
(
'pragma Export(C, Set_State, "_set_state");'
)
dll_api
.
append
(
"{} is"
.
format
(
set_state_decl
))
set_state_decl
=
"procedure Set_State (New_State : chars_ptr)"
ads_template
.
append
(
f
'
{
set_state_decl
}
with Export, Convention => C, '
f
' Link_Name => "_set_state";'
)
dll_api
.
append
(
f
"
{
set_state_decl
}
is"
)
dll_api
.
append
(
"begin"
)
dll_api
.
append
(
"for S in States loop"
)
dll_api
.
append
(
"if To_Upper (Value (New_State))"
" = States'Image (S) then"
)
dll_api
.
append
(
"{}.state := S;"
.
format
(
LPREFIX
))
dll_api
.
append
(
f
"
{
LPREFIX
}
.State := S;"
)
dll_api
.
append
(
"end if;"
)
dll_api
.
append
(
"end loop;"
)
dll_api
.
append
(
"end Set_State;"
)
...
...
@@ -993,6 +987,11 @@ package {process_name} is'''.format(generic=generic_spec,
if
ri_inst
:
pkg_decl
+=
u
" ({})"
.
format
(
u
", "
.
join
(
ri_inst
))
ads_template
.
append
(
pkg_decl
+
u
";"
)
ads_template
.
append
(
f
"function Get_State return chars_ptr "
f
"is (New_String (
{
process_name
}
_Instance.
{
LPREFIX
}
.State'Img))"
f
" with Export, Convention => C, "
f
'Link_Name => "
{
process_name
.
lower
()
}
_state";'
)
has_cs
=
any
(
process
.
cs_mapping
.
values
())
...
...
opengeode/icons.py
View file @
77140fd9
This diff is collapsed.
Click to expand it.
opengeode/ogParser.py
View file @
77140fd9
...
...
@@ -703,6 +703,9 @@ def check_call(name, params, context):
# check that the list of enumerants are identical. unfortunately we
# cannot check the ordering, as it is an unordered dict
if
name
==
'to_selector'
:
# if the sort is a subtype, it may not have a -selection suffix
# and an exception may be raised. FIXME : check "present" operator
# as the issue is already fixed there
return_type
=
types
()[
sort
+
'-selection'
].
type
else
:
return_type
=
types
()[
sort
].
type
...
...
@@ -828,8 +831,21 @@ def check_call(name, params, context):
elif
name
==
'present'
:
p
,
=
params
sort
=
type_name
(
p
.
exprType
)
+
"-selection"
return
types
()[
sort
].
type
# When we get there, the parameter has been checked already and we
# know it is a CHOICE type.
# However it may be a subtype, and in the AST the choices are defined
# in the supertype, so we must find it and and the -selection suffix
# This suffix is added by the Asn1scc module.
sort
=
p
.
exprType
sort_name
=
type_name
(
sort
)
try
:
while
sort
.
kind
==
"ReferenceType"
:
sort_name
=
sort
.
ReferencedTypeName
sort
=
types
()[
sort
.
ReferencedTypeName
].
type
except
AttributeError
:
# Native choice types don't have the kind field here
pass
return
types
()[
sort_name
+
"-selection"
].
type
# choice_to_int: returns an integer corresponding to either the currently
# selected choice value (e.g. foo in CHOICE { foo INTEGER (..), ... } when
...
...
@@ -3857,13 +3873,13 @@ def state(root, parent, context):
state_def
.
charPositionInLine
=
child
.
getCharPositionInLine
()
state_def
.
statelist
=
[
state_def
.
inputString
]
inst_stop
=
child
.
getTokenStopIndex
()
via_stop
=
inst_stop
# in case there is also a via clause
elif
child
.
type
==
lexer
.
TYPE_INSTANCE
:
# Extract the complete string "state: instance"
start
=
inst_stop
stop
=
child
.
getTokenStopIndex
()
full_string
=
token_stream
(
root
).
toString
(
start
,
stop
)
state_def
.
inputString
,
state_def
.
instance_of
=
\
full_string
,
state_def
.
instance_of
state_def
.
inputString
=
token_stream
(
root
).
toString
(
start
,
stop
)
state_def
.
instance_of
=
child
.
getChild
(
0
).
toString
()
elif
child
.
type
==
lexer
.
STATELIST
:
# State name(state_def)
state_def
.
inputString
=
get_input_string
(
child
)
...
...
@@ -3911,7 +3927,12 @@ def state(root, parent, context):
'in substate "{}"'
.
format
(
each
,
comp
.
statename
.
lower
()))
try
:
for
statename
in
state_def
.
statelist
:
# Use the statelist unless the state is an instance
if
not
state_def
.
instance_of
:
statelist
=
state_def
.
statelist
else
:
statelist
=
[
state_def
.
instance_of
]
for
statename
in
statelist
:
# check that input is not already defined
existing
=
context
.
mapping
.
get
(
statename
.
lower
(),
[])
dupl
=
set
()
...
...
@@ -3926,8 +3947,11 @@ def state(root, parent, context):
.
format
(
each
,
statename
.
lower
()))
# then update the mapping state-input
context
.
mapping
[
statename
.
lower
()].
append
(
inp
)
except
KeyError
:
stwarn
.
append
(
'State definition missing'
)
except
KeyError
as
err
:
# missing state definition is caught at other places, no
# need to report here
pass
#stwarn.append(f'State definition missing - {str(err)}')
state_def
.
inputs
.
append
(
inp
)
if
inp
.
inputString
.
strip
()
==
'*'
:
if
asterisk_input
:
...
...
@@ -4675,7 +4699,7 @@ def decision(root, parent, context):
def
nextstate
(
root
,
context
):
''' Parse a NEXTSTATE [: type] [VIA State_Entry_Point]
''' Parse a NEXTSTATE [: type] [VIA State_Entry_Point]
detect various kinds of errors when trying to enter a nested state '''
next_state_id
,
via
,
entrypoint
,
instance_of
=
''
,
None
,
None
,
None
errors
=
[]
...
...
@@ -4689,24 +4713,6 @@ def nextstate(root, context):
via
=
get_input_string
(
root
).
replace
(
'NEXTSTATE'
,
''
,
1
).
strip
()
entrypoint
=
child
.
getChild
(
0
).
text
try
:
composite
,
=
(
comp
for
comp
in
context
.
composite_states
if
comp
.
statename
.
lower
()
==
next_state_id
.
lower
())
except
ValueError
:
errors
.
append
(
'State {} is not a composite state'
.
format
(
next_state_id
))
else
:
if
entrypoint
.
lower
()
not
in
composite
.
state_entrypoints
:
errors
.
append
(
'State {s} has no "{p}" entrypoint'
.
format
(
s
=
next_state_id
,
p
=
entrypoint
))
for
each
in
composite
.
content
.
named_start
:
if
each
.
inputString
==
entrypoint
.
lower
()
+
'_START'
:
break
else
:
errors
.
append
(
'Entrypoint {p} in state {s} is '
'declared but not defined'
.
format
(
s
=
next_state_id
,
p
=
entrypoint
))
else
:
errors
.
append
(
'"History" NEXTSTATE cannot have a "via" clause'
)
elif
child
.
type
==
lexer
.
TYPE_INSTANCE
:
...
...
@@ -4716,17 +4722,40 @@ def nextstate(root, context):
else
:
errors
.
append
(
'NEXTSTATE undefined construct: '
+
sdl92Parser
.
tokenNamesMap
[
child
.
type
])
if
not
via
:
# check that if the nextstate is nested, it has a START symbol
try
:
composite
,
=
(
comp
for
comp
in
context
.
composite_states
if
comp
.
statename
.
lower
()
==
next_state_id
.
lower
())
if
not
isinstance
(
composite
,
ogAST
.
StateAggregation
)
\
and
not
composite
.
content
.
start
:
errors
.
append
(
'Composite state "{}" has no unnamed '
'START symbol'
.
format
(
composite
.
statename
))
except
ValueError
:
# Checks on the NEXTSTATE
if
via
:
# instance and/or via clause
state_id
=
instance_of
or
next_state_id
try
:
composite
,
=
(
comp
for
comp
in
context
.
composite_states
if
comp
.
statename
.
lower
()
==
state_id
.
lower
())
except
ValueError
:
errors
.
append
(
f
'State
{
state_id
}
is not a composite state'
)
else
:
if
entrypoint
is
None
:
pass
elif
entrypoint
.
lower
()
not
in
composite
.
state_entrypoints
:
errors
.
append
(
f
'State
{
state_id
}
has no "
{
entrypoint
}
" entrypoint'
)
# The test below seems identical to the one just done
# for each in composite.content.named_start:
# if not entrypoint or \
# each.inputString == entrypoint.lower() + '_START':
# break
# else:
# errors.append(f'Entrypoint {entrypoint} in state'
# f' {state_id} is declared but not defined')
else
:
# not via and/or instance
# check that if the nextstate is nested, it has a START symbol
try
:
composite
,
=
(
comp
for
comp
in
context
.
composite_states
if
comp
.
statename
.
lower
()
==
next_state_id
.
lower
())
if
not
isinstance
(
composite
,
ogAST
.
StateAggregation
)
\
and
not
composite
.
content
.
start
:
errors
.
append
(
'Composite state "{}" has no unnamed '
'START symbol'
.
format
(
composite
.
statename
))
except
ValueError
:
pass
return
next_state_id
,
via
,
entrypoint
,
instance_of
,
errors
...
...
@@ -5447,6 +5476,18 @@ def parse_pr(files=None, string=None):
[
t_x
,
t_y
],
[
'PROCESS {}'
.
format
(
process
.
processName
)]])
# TODO: do the same with JOIN/LABEL
# Check that all floating state instances (foo:bar) have a correspoding
# nested state defined.
state_types
=
set
(
st
.
instance_of
.
lower
()
for
st
in
process
.
content
.
states
if
st
.
instance_of
)
comp_states
=
set
(
comp
.
statename
.
lower
()
for
comp
in
process
.
composite_states
)
for
missing
in
state_types
-
comp_states
:
errors
.
append
([
f
'Nested state definition missing :
{
missing
}
'
,
[
0
,
0
],
[
'PROCESS {}'
.
format
(
process
.
processName
)]])
return
og_ast
,
warnings
,
errors
...
...
opengeode/opengeode.py
View file @
77140fd9
...
...
@@ -140,7 +140,7 @@ except ImportError:
__all__
=
[
'opengeode'
,
'SDL_Scene'
,
'SDL_View'
,
'parse'
]
__version__
=
'3.
1.3
'
__version__
=
'3.
2.1
'
if
hasattr
(
sys
,
'frozen'
):
# Detect if we are running on Windows (py2exe-generated)
...
...
@@ -2323,14 +2323,21 @@ clean:
pr_raw
=
Pr
.
parse_scene
(
scene
,
full_model
=
True
if
not
self
.
readonly_pr
else
False
)
pr_data
=
str
(
'
\n
'
.
join
(
pr_raw
))
if
pr_data
:
ast
,
warnings
,
errors
=
ogParser
.
parse_pr
(
files
=
self
.
readonly_pr
,
string
=
pr_data
)
scene
.
semantic_errors
=
True
if
errors
else
False
log_errors
(
self
.
messages_window
,
errors
,
warnings
,
clearfirst
=
False
)
self
.
update_asn1_dock
.
emit
(
ast
)
return
"Done"
try
:
if
pr_data
:
ast
,
warnings
,
errors
=
ogParser
.
parse_pr
(
files
=
self
.
readonly_pr
,
string
=
pr_data
)
scene
.
semantic_errors
=
True
if
errors
else
False
log_errors
(
self
.
messages_window
,
errors
,
warnings
,
clearfirst
=
False
)
self
.
update_asn1_dock
.
emit
(
ast
)
return
"Done"
except
Exception
as
err
:
self
.
messages_window
.
addItem
(
"Opengeode bug, PLEASE REPORT: "
+
str
(
err
))
LOG
.
debug
(
str
(
traceback
.
format_exc
()))
return
"Syntax Errors"
def
show_item
(
self
,
item
):
'''
...
...
opengeode/sdl92Lexer.py
View file @
77140fd9
This diff is collapsed.
Click to expand it.
opengeode/sdl92Parser.py
View file @
77140fd9
This diff is collapsed.
Click to expand it.
opengeode/sdlSymbols.py
View file @
77140fd9
...
...
@@ -981,8 +981,9 @@ class State(VerticalSymbol):
@
property
def
allow_nesting
(
self
):
''' Redefinition - must be checked according to context '''
# nesting permitted only if single plain state
result
=
not
any
(
elem
in
str
(
self
).
lower
().
strip
()
for
elem
in
(
'-'
,
','
,
'*'
))
for
elem
in
(
'-'
,
','
,
'*'
,
':'
,
'via'
))
return
result
@
property
...
...
sdl92.g
View file @
77140fd9
...
...
@@ -478,16 +478,17 @@ floating_label
-> ^(FLOATING_LABEL cif? hyperlink? connector_name transition?)
;
// state is either a full state definition, or a
declaration of an
instance
// state is either a full state definition, or a
state
instance
state
: state_definition
| state_instance
;
// the "via" part is needed to allow the graphical merge with a nextstate
state_definition
: cif?
hyperlink?
STATE statelist via? (e=end | SEMI)
// "via" part may be in NEXTSTATE
STATE statelist via? (e=end | SEMI)
(state_part)*
ENDSTATE statename? f=end
-> ^(STATE cif? hyperlink? $e? statelist via? state_part*)
...
...
@@ -497,9 +498,10 @@ state_definition
state_instance
: cif?
hyperlink?
STATE statename ':' type_inst e=end
STATE statename ':' type_inst via? (e=end | SEMI)
(state_part)*
ENDSTATE statename? f=end
-> ^(STATE cif? hyperlink? $e? statename type_inst)
-> ^(STATE cif? hyperlink? $e? statename
via?
type_inst
state_part*
)
;
...
...
tests/testsuite/test-simu/test_ada.c
View file @
77140fd9
...
...
@@ -3,6 +3,10 @@
#include
"dataview-uniq.h"
extern
void
adainit
();
extern
void
orchestrator_startup
();
extern
void
orchestrator_PI_other
();
extern
void
orchestrator_PI_Paramless_TC
();
extern
char
*
orchestrator_state
();
void
orchestrator_RI_peek_list
(
void
*
_
)
{}
void
orchestrator_RI_peek_fixed
(
void
*
_
)
{}
void
orchestrator_RI_telemetry
(
void
*
_
){}
...
...
@@ -15,7 +19,13 @@ int main()
int
i
;
printf
(
"[C Code] Running test
\n
"
);
adainit
();
orchestrator_startup
();
toto
=
fixed_value
();
printf
(
"%s
\n
"
,
orchestrator_state
());
orchestrator_PI_other
();
printf
(
"%s
\n
"
,
orchestrator_state
());
orchestrator_PI_other
();
printf
(
"%s
\n
"
,
orchestrator_state
());
// size = fixed_size();
// printf("Size=%d\n", size);
// for (i = 0; i<size; i++) printf("%d", toto[i]);
...
...
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