Commit 7263b97c authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Complete support of exported procedures

parent 6de76b32
......@@ -124,6 +124,9 @@ The background pattern was downloaded from www.subtlepatterns.com
Changelog
=========
**3.4.1 (03/2021)**
- Fix support of remote synchronous calls
**3.4.0 (03/2021)**
- Support exported/reference procedures (allowing remote synchronous calls)
......
......@@ -712,13 +712,9 @@ package body {process_name}_RI is''']
pi_header = procedure_header(proc)
ads_template.append(f'{pi_header};')
if not proc.external and not generic:
if not proc.exported:
ads_template.append(
f'pragma Export (C, p{SEPARATOR}{proc.inputString}, "_{proc.inputString}");')
else:
# Export for TASTE as a synchronous PI
ads_template.append(
f'pragma Export (C, p{SEPARATOR}{proc.inputString}, "{process_name.lower()}_PI_{proc.inputString}");')
# Export for TASTE as a synchronous PI
ads_template.append(
f'pragma Export (C, p{SEPARATOR}{proc.inputString}, "{process_name.lower()}_PI_{proc.inputString}");')
# Generate the code for the process-level variable declarations
taste_template.extend(process_level_decl)
......@@ -1523,10 +1519,10 @@ def _call_external_function(output, **kwargs):
code.append(u'{tmp}.Length := {app_len};'
.format(tmp=tmp_id, app_len=app_len))
else:
code.append(u'{} := {};'.format(tmp_id, p_id))
code.append(f'{tmp_id} := {p_id};')
list_of_params.append(u"{}{}"
.format(tmp_id,
u", {}'Size".format(tmp_id)
f", {tmp_id}'Size"
if is_out_sig else ""))
else:
# Output parameters/local variables
......@@ -3096,7 +3092,8 @@ def procedure_header(proc):
typename = type_name(fpar['type'])
params.append(u'{name}: in{out} {ptype}'.format(
name=fpar.get('name'),
out=' out' if fpar.get('direction') == 'out' else '',
# out: exported procedures always use in out for taste (C code) compatibility
out=' out' if (fpar.get('direction') == 'out' or proc.exported) else '',
ptype=typename))
pi_header += ';'.join(params)
pi_header += ')'
......@@ -3138,10 +3135,8 @@ def _inner_procedure(proc, **kwargs):
# Inner procedures declared external by the user: pragma import
# the C symbol with the same name. Overrules the pragma import from
# taste for required interfaces.
local_decl.append(u'pragma import(C, p{sep}{proc_name}, '
u'"{proc_name}");'
.format(sep=SEPARATOR,
proc_name=proc.inputString))
local_decl.append(f'pragma Import (C, p{SEPARATOR}{proc.inputString}, '
f'"{proc.inputString}");')
else:
# Generate the code for the procedure itself
# local variables and code of the START transition
......
......@@ -79,10 +79,12 @@ def _block(ast, scene):
param=('(' + sig['type'].ReferencedTypeName.replace('-', '_') + ')')
if 'type' in sig else '')
for sig in ast.parent.signals]
procedures = ["procedure {proc.inputString};\n{optfpar}external;\n"
procedures = ["{exported}procedure {proc.inputString};\n{optfpar}{external};\n"
.format(proc=proc,
optfpar="fpar\n " + u",\n ".join
([u"{direc} {fp[name]} {asn1}"
exported="exported " if proc.exported else "",
external="referenced" if proc.referenced else "external",
optfpar="fpar\n " + ",\n ".join
(["{direc} {fp[name]} {asn1}"
.format(fp=fpar,
direc="in"
if fpar['direction']=='in'
......
......@@ -840,8 +840,6 @@ class Procedure:
self.transitions = []
# Determine if a procedure is externally defined
self.external = False
# Determine if a procedure is a remote procedure
self.exported = False
# Determine if a procedure only has a textual definition
self.textual_procedure = False
# Optional comment
......
......@@ -2996,6 +2996,7 @@ def check_duplicate_procedures(ctxt, proc, errors=[]):
Procedure named "entry" and "exit" are ignored
'''
name = proc.inputString.lower()
#breakpoint()
if not isinstance(ctxt, ogAST.System) and ctxt.parent != None:
check_duplicate_procedures(ctxt.parent, proc, errors)
if isinstance(ctxt, ogAST.AST):
......@@ -5480,7 +5481,27 @@ def pr_file(root):
ast.process_types.extend(p_types)
for child in processes:
# process definition at root level (can be a process type)
process, err, warn = process_definition(child, parent=ast)
# parse the process name to find the scope in which it is declared
for node in child.getChildren():
if node.type == lexer.ID:
processName = node.text
def rec_find_process_parent(block, proc_name : str):
# to define the parent of the process, find the block where it is
# specified with a "referenced" flag.
res = None
for nested in block.blocks:
res = rec_find_process_parent(nested, proc_name)
if res:
return nested
for proc in block.processes:
if proc.processName.lower() == proc_name.lower():
return block
proc_parent = ast
for system in ast.systems:
proc_parent = rec_find_process_parent(system, processName)
if proc_parent:
break
process, err, warn = process_definition(child, parent=proc_parent)
# check if the process was declared as referenced with FPAR
for each in ref_p_with_fpar:
if each.processName == process.processName:
......
......@@ -141,7 +141,7 @@ except ImportError:
__all__ = ['opengeode', 'SDL_Scene', 'SDL_View', 'parse']
__version__ = '3.4.0'
__version__ = '3.4.1'
if hasattr(sys, 'frozen'):
# Detect if we are running on Windows (py2exe-generated)
......
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