Commit 54c5842b authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Progress on the String Template backend

parent 43573e2e
......@@ -76,6 +76,9 @@ def _process(process, simu=False, stgfile='ada_source.st', **kwargs):
process_template = STG.getInstanceOf("process")
process_template['name'] = process_name
# Set Simulation/DLL mode
process_template['simu'] = simu
TYPES = process.dataview
del OUT_SIGNALS[:]
del PROCEDURES[:]
......@@ -97,11 +100,13 @@ def _process(process, simu=False, stgfile='ada_source.st', **kwargs):
# Initialize array of strings containing all local declarations
process_decl = []
process_vars = []
# Generate the code to declare process-level variables
process_level_decl = []
for var_name, (var_type, def_value) in process.variables.viewitems():
dcl_template = STG.getInstanceOf("dcl")
dcl_template['simu'] = simu
if def_value:
# Expression must be a ground expression, i.e. must not
# require temporary variable to store computed result
......@@ -110,13 +115,15 @@ def _process(process, simu=False, stgfile='ada_source.st', **kwargs):
if varbty.kind in ('SequenceOfType', 'OctetStringType'):
dstr = array_content(def_value, dstr, varbty)
assert not dst and not dlocal, 'DCL: Expecting a ground expression'
dcl_template['var'] = var_name
dcl_template['sort'] = type_name(var_type)
var = {'name': var_name, 'sort': type_name(var_type)}
dcl_template['var'] = var
process_vars.append(var)
dcl_template['def_expr'] = dstr if def_value else ''
process_decl.append(str(dcl_template))
# Set the DCL declarations variable in the process template
process_template['decl'] = process_decl
process_template['vars'] = process_vars
# Set the list of SDL states
......@@ -140,57 +147,10 @@ def _process(process, simu=False, stgfile='ada_source.st', **kwargs):
for dv in process.asn1Modules)
except TypeError:
pass # No ASN.1 module
print str(process_template)
return
dll_api = []
if simu:
ads_template.append('-- DLL Interface')
dll_api.append('-- DLL Interface 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(state))) "
"with Export, Convention => C, "
'Link_Name => "{}_state";'
.format(process_name))
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))
dll_api.append("begin")
dll_api.append("state := States'Value(Value(new_state));")
dll_api.append("end set_state;")
dll_api.append("")
# Functions to get gobal variables (length and value)
for var_name, (var_type, _) in process.variables.viewitems():
# Getters for local variables
process_level_decl.append("function l_{name}_size return integer "
"is (l_{name}'Size/8) with Export, "
"Convention => C, "
'Link_Name => "{name}_size";'
.format(name=var_name))
process_level_decl.append("function l_{name}_value"
" return access {sort} "
"is (l_{name}'access) with Export, "
"Convention => C, "
'Link_Name => "{name}_value";'
.format(name=var_name,
sort=type_name(var_type)))
# Setters for local variables
setter_decl = "procedure dll_set_l_{name}(value: access {sort})"\
.format(name=var_name, sort=type_name(var_type))
ads_template.append('{};'.format(setter_decl))
ads_template.append('pragma export(C, dll_set_l_{name},'
' "_set_{name}");'.format(name=var_name))
dll_api.append('{} is'.format(setter_decl))
dll_api.append('begin')
dll_api.append('l_{} := value.all;'.format(var_name))
dll_api.append('end dll_set_l_{};'.format(var_name))
dll_api.append('')
# Generate the the code of the procedures
inner_procedures_code = []
for proc in process.content.inner_procedures:
......@@ -204,9 +164,6 @@ def _process(process, simu=False, stgfile='ada_source.st', **kwargs):
# Add the code of the procedures definitions
taste_template.extend(inner_procedures_code)
# Add the code of the DLL interface
taste_template.extend(dll_api)
# Generate the code for each input signal (provided interface) and timers
for signal in process.input_signals + [
{'name': timer.lower()} for timer in process.timers]:
......
......@@ -3,12 +3,13 @@ group adb;
/* top-level: template for the code of a process
* name: process name
* decl: list of local declarations
* vars: list of local variables and sort:dictionnary { name: str, sort: str })
* constants: list of start named start transitions (when using substates)
* states: list of states
* asn1_mod : list of ASN.1 modules
* simu, dll : flags set by the user for generation of optional code
*/
process(name, decl, constants, states, asn1_mod, simu, dll) ::= <<
process(name, decl, vars, constants, states, asn1_mod, simu, dll) ::= <<
-- This file was generated automatically: DO NOT MODIFY !
<if(asn1_mod)>
......@@ -37,21 +38,49 @@ use Interfaces;
-- Access to C compatible types when interacting with another language
with Interfaces.C.Strings;
use Interfaces.C.Strings;
<endif>
package body <name> is
-- Local variables declared in textboxes
<decl; separator="\n">
---------------------------------------------------------------------------
-- List of SDL states, and variable holding the current state
type States is (<states; separator=", ">);
state: States;
<if(simu)>
-- External API to get/set the SDL state from a remote C application
function get_state return chars_ptr is (New_String(States'Image(state)))
with Export, Convention => C, Link_Name => "<name>_state";
procedure set_state(new_state: chars_ptr);
pragma export(C, set_state, "_set_state");
---------------------------------------------------------------------------
<endif>
<if(constants)>
-- Constants holding substate identifier for the start transition
<constants; separator="\n">
---------------------------------------------------------------------------
<endif>
-- Declaration of the procedure executing transitions
procedure RunTransition(Id: Integer);
<if(simu)>
-- Implementation of the set_state procedure
procedure set_state(new_state: chars_ptr) is
begin
state := States'Value(Value(new_state));
end set_state;
-- Implementation of the variable setters for external C access
<vars: {each |
procedure dll_set_l_<each.name>(value: access <each.sort>) is
begin
l_<each.name> := value.all;
end dll_set_l_<each.name>;
}; separator="\n">
---------------------------------------------------------------------------
<endif>
-- Process initialization: execute the START transition)
begin
RunTransition(0);
......@@ -59,8 +88,16 @@ end <name>;
>>
/* Variable declaration (DCL var sort [:= def_expr]; */
dcl(var, sort, def_expr) ::= <<
l_<var> : aliased <sort><if(def_expr)> := <def_expr><endif>;
dcl(var, def_expr, simu) ::= <<
l_<var.name> : aliased <var.sort><if(def_expr)> := <def_expr><endif>;
<if(simu)>
function l_<var.name>_size return Integer is (l_<var.name>'Size/8)
with Export, Convention => C, Link_Name => "<var.name>_size";
function l_<var.name>_value return access <var.sort> is (l_<var.name>'access)
with Export, Convention => C, Link_Name => "<var.name>_value";
procedure dll_set_l_<var.name>(value: access <var.sort>);
pragma Export(C, dll_set_l_<var.name>, "_set_<var.name>");
<endif>
>>
/* Constant declaration */
......
Supports Markdown
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