Commit c3d1e678 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Support RETURNS statement in external procedures

parent 37c1a76b
......@@ -148,6 +148,11 @@ The fonts are the fonts from Ubuntu, check licence in file FONT-LICENSE.TXT
Changelog
=========
1.3.6 (11/2015)
- Support external procedures having a return statement
this allows to import math functions from the libmath without having
to provide manual code. see test-math
1.3.5 (11/2015)
- Better support for continous signals
......
......@@ -2169,14 +2169,12 @@ def _inner_procedure(proc, **kwargs):
# Build the procedure signature (function if it can return a value)
ret_type = type_name(proc.return_type) if proc.return_type else None
pi_header = u'{kind} {sep}{proc_name}{ret}'.format(kind='procedure'
pi_header = u'{kind} {sep}{proc_name}'.format(kind='procedure'
if not proc.return_type
else 'function',
sep=(u'p' + UNICODE_SEP)
if not proc.external else '',
proc_name=proc.inputString,
ret=(' return '+ret_type)
if ret_type else '')
proc_name=proc.inputString)
if proc.fpar:
pi_header += '('
......@@ -2189,6 +2187,8 @@ def _inner_procedure(proc, **kwargs):
ptype=typename))
pi_header += ';'.join(params)
pi_header += ')'
if ret_type:
pi_header += ' return {}'.format(ret_type)
local_decl.append(pi_header + ';')
# Remote procedures need to be exported with a C calling convention
......@@ -2198,6 +2198,9 @@ def _inner_procedure(proc, **kwargs):
.format(sep=UNICODE_SEP, proc_name=proc.inputString))
if proc.external:
# 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, {});'.format(proc.inputString))
else:
# Generate the code for the procedure itself
......
......@@ -2,7 +2,7 @@
 
# Resource object code
#
# Created: Wed Dec 2 15:36:15 2015
# Created: Wed Dec 2 16:22:57 2015
# by: The Resource Compiler for PySide (Qt v4.8.6)
#
# WARNING! All changes made in this file will be lost!
......@@ -785,6 +785,8 @@ class Procedure(object):
self.fpar = []
# return type (ASN.1)
self.return_type = None
# when procedure has a RETURN it can also contain a variable name
self.return_var = None
# start, terminators, text areas, floating_labels (see Process)
#self.start = None
#self.states = []
......
......@@ -599,6 +599,13 @@ def check_call(name, params, context):
'Max': str(math.trunc(float(param_btys[0].Max)))
})
else:
# check if procedure is declared to return a type
for inner_proc in context.procedures:
proc_name = inner_proc.inputString
if proc_name.lower() == name.lower() and inner_proc.return_type:
return inner_proc.return_type
return UNKNOWN_TYPE
......@@ -2069,17 +2076,34 @@ def procedure_pre(root, parent=None, context=None):
errors.extend(err)
warnings.extend(warn)
proc.fpar = params
elif child.type == lexer.RETURNS:
try:
proc.return_type, proc.return_var = procedure_returns(child)
except TypeError as err:
errors.append(str(err))
if proc.return_var:
warnings.append('Procedure return variable not supported')
elif child.type in (lexer.PROCEDURE, lexer.START,
lexer.STATE, lexer.FLOATING_LABEL):
content.append(child)
else:
warnings.append(
'Unsupported construct in procedure, type: ' +
str(child.type) + ' - line ' + str(child.getLine()) +
' - string: ' + str(proc.inputString))
sdl92Parser.tokenNames[child.type] +
' - line ' + str(child.getLine()) +
' - in procedure ' + str(proc.inputString))
return proc, content, errors, warnings
def procedure_returns(root):
''' Returns the (optional) variable name and the sort of the return '''
if len(root.children) == 1:
return sdl_to_asn1(root.getChild(0).getChild(0).text), None
else:
return sdl_to_asn1(root.getChild(1).getChild(0).text),\
root.getChild(0).text
def procedure_post(proc, content, parent=None, context=None):
''' Parse the content of a procedure '''
errors = []
......@@ -2381,6 +2405,14 @@ def text_area_content(root, ta_ast, context):
ta_ast.fpar = params
except AttributeError:
errors.append('Entity cannot have an FPAR section')
elif child.type == lexer.RETURNS:
try:
context.return_type, context.return_var =\
procedure_returns(child)
except TypeError as err:
errors.append(str(err))
if context.return_var:
warnings.append('Procedure return variable not supported')
elif child.type == lexer.TIMER:
timers = [timer.text.lower() for timer in child.children]
context.timers.extend(timers)
......
......@@ -116,7 +116,7 @@ except ImportError:
__all__ = ['opengeode', 'SDL_Scene', 'SDL_View', 'parse']
__version__ = '1.3.5'
__version__ = '1.3.6'
if hasattr(sys, 'frozen'):
# Detect if we are running on Windows (py2exe-generated)
......
This diff is collapsed.
This diff is collapsed.
......@@ -50,7 +50,7 @@ SDL_BLACKBOLD = ['\\b{word}\\b'.format(word=word) for word in (
'CHECKME', 'PROCEDURE', 'EXTERNAL', 'IN', 'OUT', 'TIMER',
'SET_TIMER', 'RESET_TIMER', 'VIA', 'ENTRY', 'EXIT', 'ANY',
'SYNTYPE', 'ENDSYNTYPE', 'CONSTANTS', 'ENDPROCEDURE',
'COMMENT', 'SIGNAL', 'SIGNALLIST', 'USE',
'COMMENT', 'SIGNAL', 'SIGNALLIST', 'USE', 'RETURNS'
'NEWTYPE', 'ENDNEWTYPE', 'ARRAY', 'STRUCT', 'SYNONYM')]
SDL_REDBOLD = ['\\b{word}\\b'.format(word=word) for word in (
......
......@@ -264,7 +264,7 @@ process_definition
pfpar
: FPAR parameters_of_sort
(',' parameters_of_sort)*
end
end?
-> ^(PFPAR parameters_of_sort+)
;
......@@ -301,7 +301,7 @@ procedure_result
fpar
: FPAR formal_variable_param
(',' formal_variable_param)*
end
end?
-> ^(FPAR formal_variable_param+)
;
......@@ -329,12 +329,13 @@ content
| use_clause
| signal_declaration
| fpar
| res=procedure_result
| timer_declaration
| syntype_definition
| newtype_definition
| variable_definition
| synonym_definition)*
-> ^(TEXTAREA_CONTENT fpar* procedure* variable_definition*
-> ^(TEXTAREA_CONTENT fpar* $res? procedure* variable_definition*
syntype_definition* newtype_definition* timer_declaration*
signal_declaration* use_clause* synonym_definition*)
;
......
include ../shared.mk
all: test-ada test-llvm
edit:
$(OPENGEODE) expressions.pr system_structure.pr
test-parse:
$(OPENGEODE) expressions.pr system_structure.pr --check
test-ada: expressions.ali dataview-uniq.o | test_ada.o
$(GNATBIND) -n expressions.ali
$(GNATLINK) test_ada.o expressions.ali -lgnat -lm -o test_ada
./test_ada
test-c: expressions.c test_c.o dataview-uniq.o
$(CC) expressions.c -c -o expressions.o
$(CC) test_c.o dataview-uniq.o expressions.o -lm -o test_c
./test_c
test-llvm: expressions.o dataview-uniq.o | test_llvm.o
$(CC) expressions.o dataview-uniq.o test_llvm.o -o test_llvm -lm
./test_llvm
test-vhdl : test-c
bambu expressions.c test_c.c dataview-uniq.c --experimental-setup=BAMBU -v4
coverage:
coverage run -p $(OPENGEODE) expressions.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage
TASTE-Dataview DEFINITIONS ::=
BEGIN
Boolean ::= BOOLEAN
Integer ::= INTEGER(-9223372036854775808..9223372036854775807)
Real ::= REAL (-100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 .. 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0)
CharString ::= OCTET STRING (SIZE(0..100))
FixSeqof ::= SEQUENCE (SIZE(3)) OF Integer
VarSeqof ::= SEQUENCE (SIZE(0..100)) OF Integer
Seq ::= SEQUENCE {
i Integer,
b Boolean,
f Real,
s CharString
}
NestedSeq ::= SEQUENCE {
a SEQUENCE {
b SEQUENCE {
c SEQUENCE {
d Integer
}
}
}
}
BoolSeqOf ::= SEQUENCE (SIZE(4)) OF Boolean
END
/* CIF PROCESS (144, 159), (150, 75) */
PROCESS expressions;
/* CIF TEXT (1105, 175), (303, 268) */
DCL i Integer;
DCL f Real;
DCL b Boolean;
DCL s CharString;
DCL fixSeqOf1 FixSeqof;
DCL fixSeqOf2 FixSeqof;
DCL varSeqOf1 VarSeqof;
DCL varSeqOf2 VarSeqof;
DCL seq Seq;
DCL nestedSeq NestedSeq;
DCL bs1 BoolSeqOf;
DCL bs2 BoolSeqOf;
DCL bs3 BoolSeqOf;
/* CIF ENDTEXT */
/* CIF TEXT (40, 150), (444, 168) */
-- Declare an external procedure that has a return type
-- Use this to get access to C libraries (eg. math lib)
-- without having to write manually external code
-- Just link your code with the SDL object.
procedure log;
fpar in par real;
returns real
external;
/* CIF ENDTEXT */
/* CIF START (530, 47), (70, 35) */
START;
/* CIF NEXTSTATE (530, 97), (70, 35) */
NEXTSTATE wait;
/* CIF STATE (530, 97), (70, 35) */
STATE wait;
/* CIF INPUT (525, 153), (81, 38) */
INPUT run;
/* CIF TASK (494, 206), (144, 35) */
TASK f := log(f);
/* CIF NEXTSTATE (516, 256), (100, 50) */
NEXTSTATE Wait;
ENDSTATE;
ENDPROCESS expressions;
\ No newline at end of file
/* CIF Keep Specific Geode ASNFilename 'dataview-uniq.asn' */
USE Datamodel;
SYSTEM expressions;
SIGNAL run;
PROCEDURE assert;
FPAR
IN res Boolean,
IN msg CharString;
EXTERNAL;
CHANNEL c
FROM ENV TO expressions WITH run;
ENDCHANNEL;
BLOCK expressions;
SIGNALROUTE r
FROM ENV TO expressions WITH run;
CONNECT c and r;
PROCESS expressions REFERENCED;
ENDBLOCK;
ENDSYSTEM;
#include <stdio.h>
#include <stdlib.h>
#include "dataview-uniq.h"
extern void adainit();
extern void expressions_run();
void expressions_RI_assert(asn1SccBoolean *res, asn1SccCharString *msg) {
if (!*res) {
fprintf(stderr, "%.*s\n", (int)msg->nCount, msg->arr);
exit(1);
}
}
int main() {
adainit();
expressions_run();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "dataview-uniq.h"
void expressions_RI_assert(asn1SccBoolean *res, asn1SccCharString *msg) {
if (!*res) {
printf("%.*s\n", (int)msg->nCount, msg->arr);
exit(1);
}
}
int main() {
runTransition(0);
run();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "dataview-uniq.h"
extern void expressions_startup();
extern void expressions_run();
void expressions_RI_assert(asn1SccBoolean *res, asn1SccCharString *msg) {
if (!*res) {
fprintf(stderr, "%.*s\n", (int)msg->nCount, msg->arr);
exit(1);
}
}
int main() {
expressions_startup();
expressions_run();
return 0;
}
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