Commit 444184c6 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Added partial support for num() predefined operator (but Ada backend

cannot fully support it)
parent 6b4aba86
......@@ -789,6 +789,19 @@ def _prim_call(prim):
local_decl.extend(local_var)
ada_string += ('asn1Scc{t}_Kind({e})'.format(
t=exp_typename, e=param_str))
elif ident == 'num':
# User wants to get an enumerated corresponding integer value
exp = params[0]
exp_type = find_basic_type(exp.exprType)
# Get the ASN.1 type name as it is needed to build the Ada expression
exp_typename = \
(getattr(exp.exprType, 'ReferencedTypeName', None)
or exp.exprType.kind).replace('-', '_')
param_stmts, param_str, local_var = expression(exp)
stmts.extend(param_stmts)
local_decl.extend(local_var)
ada_string += ("asn1Scc{t}'Pos({e})".format(t=exp_typename,
e=param_str))
else:
ada_string += '('
# Take all params and join them with commas
......
......@@ -98,6 +98,7 @@ CHOICE = type('ChoiceType', (object,), {'kind': 'ChoiceType'})
BOOLEAN = type('BooleanType', (object,), {'kind': 'BooleanType'})
RAWSTRING = type('RawString', (object,), {'kind': 'StandardStringType'})
OCTETSTRING = type('OctetString', (object,), {'kind': 'OctetStringType'})
ENUMERATED = type('EnumeratedType', (object,), {'kind': 'EnumeratedType'})
UNKNOWN_TYPE = type('UnknownType', (object,), {'kind': 'UnknownType'})
......@@ -110,6 +111,7 @@ SPECIAL_OPERATORS = {'length': [LIST],
'set_timer': [INTEGER, TIMER],
'reset_timer': [TIMER],
'abs': [NUMERICAL],
'num': [ENUMERATED],
'float': [NUMERICAL],
'fix': [NUMERICAL],
'power': [NUMERICAL, INTEGER]}
......@@ -354,7 +356,7 @@ def is_constant(var):
def fix_special_operators(op_name, expr_list, context):
''' Verify/fix type of special operators parameters '''
if op_name.lower() in ('length', 'present', 'abs', 'float', 'fix'):
if op_name.lower() in ('length', 'present', 'abs', 'float', 'fix', 'num'):
if len(expr_list) != 1:
raise AttributeError('Only one parameter for the {} operator'
.format(op_name))
......@@ -372,6 +374,8 @@ def fix_special_operators(op_name, expr_list, context):
and not is_numeric(basic):
raise TypeError('"{}" operator needs a numerical parameter'.format(
op_name))
elif op_name.lower() == 'num' and basic.kind != 'EnumeratedType':
raise TypeError('Num operaror works only with enumerations')
elif op_name.lower() == 'power':
if len(expr_list) != 2:
raise AttributeError('The "power" operator takes two parameters')
......@@ -1342,8 +1346,19 @@ def primary_call(root, context):
'Max': str(max(float(params_bty[0].Max), 0))
})
except AttributeError:
msg = 'Type Error, check the parameter'
errors.append(error(root, '"Abs" parameter type has no range'))
elif ident == 'num':
try:
enum_values = [int(each.IntValue)
for each in params_bty[0].EnumValues.viewvalues()]
node.exprType = type('Num', (INTEGER,), {
'Min': str(min(enum_values)),
'Max': str(max(enum_values))
})
except AttributeError:
msg = 'Type Error, check the parameter'
errors.append(error(root, '"Num" parameter error'))
return node, errors, warnings
......@@ -3263,6 +3278,8 @@ def task_body(root, context):
else:
warnings.append('Unsupported child type in task body: ' +
str(child.type))
if not body:
body = ogAST.TaskAssign()
return body, errors, warnings
......
......@@ -25,7 +25,7 @@ MyInteger ::= T-UInt8
MyReal ::= REAL (0.0 .. 1000.0)
LargerReal ::= REAL (0.0 .. 1000000000)
MyEnum ::= ENUMERATED { hello, world, howareyou }
MyEnum ::= ENUMERATED { hello(12), world(13), howareyou(111) }
MySeq ::= SEQUENCE {
a MyInteger,
......
......@@ -18,6 +18,7 @@ Hello!
-2 is FALSE
2 2 1
FALSE TRUE
1 2
OK
[C] result_data: 6
Hello Toto 5
......
/* CIF PROCESS (200, 143), (150, 75) */
PROCESS myfunction;
/* CIF TEXT (0, 17), (296, 428) */
/* CIF TEXT (0, 17), (296, 458) */
-- Timers defined in the interface view
-- Use SET_TIMER (value, timer name)
-- and RESET_TIMER (timer name) in a
......@@ -29,6 +29,8 @@ dcl variable_str String := 'Hello!';
dcl other String := 'World';
dcl bar SeqInt := { 1,1 };
dcl testenum MyEnum := world;
/* CIF ENDTEXT */
/* CIF PROCEDURE (1172, 490), (91, 35) */
PROCEDURE factorial;
......@@ -114,61 +116,72 @@ should display FALSE';
COMMENT 'test op_not with variable';
/* CIF TASK (480, 820), (321, 35) */
TASK someInt := if someint = 0 then someint else 0 fi;
/* CIF DECISION (504, 870), (273, 87) */
/* CIF TASK (542, 870), (197, 35) */
TASK otherint := num(testenum);
/* CIF PROCEDURECALL (513, 920), (256, 35) */
CALL writeln(otherint, num(testenum)+1)
/* CIF COMMENT (789, 890), (401, 98) */
COMMENT 'Will display 1 2 with the Ada generator
* even if the ASN.1 model specifies explicit values *
because Ada has no operator to get the explicit value,
even if it is set as representation clause. Enumerated values
are logical states, not integers in Ada - as in ASN.1
';
/* CIF DECISION (504, 996), (273, 87) */
DECISION someint /=0 and then (10 / someInt > 0)
or else someint = 0
/* CIF COMMENT (793, 879), (179, 68) */
/* CIF COMMENT (793, 1005), (179, 68) */
COMMENT 'Using "and else" is the
short-circuit form. The
second part should not
be evaluated.';
/* CIF ANSWER (561, 977), (70, 23) */
/* CIF ANSWER (561, 1103), (70, 23) */
(true):
/* CIF TASK (541, 1015), (110, 35) */
/* CIF TASK (541, 1141), (110, 35) */
TASK someInt := 2;
/* CIF PROCEDURECALL (537, 1065), (117, 38) */
/* CIF PROCEDURECALL (537, 1191), (117, 38) */
CALL writeln('OK');
/* CIF ANSWER (664, 977), (70, 23) */
/* CIF ANSWER (664, 1103), (70, 23) */
(false):
ENDDECISION;
/* CIF NEXTSTATE (608, 1118), (65, 33) */
/* CIF NEXTSTATE (608, 1244), (65, 33) */
NEXTSTATE Wait;
/* CIF STATE (608, 1118), (65, 33) */
/* CIF STATE (608, 1244), (65, 33) */
STATE Wait;
/* CIF INPUT (865, 1171), (89, 33) */
/* CIF INPUT (865, 1297), (89, 33) */
INPUT mytimer;
/* CIF PROCEDURECALL (818, 1219), (182, 33) */
/* CIF PROCEDURECALL (818, 1345), (182, 33) */
CALL writeln('timer expired');
/* CIF PROCEDURECALL (829, 1267), (160, 33) */
/* CIF PROCEDURECALL (829, 1393), (160, 33) */
CALL factorial(3, someint);
/* CIF NEXTSTATE (877, 1315), (65, 33) */
/* CIF NEXTSTATE (877, 1441), (65, 33) */
NEXTSTATE Wait;
/* CIF INPUT (421, 1171), (181, 33) */
/* CIF INPUT (421, 1297), (181, 33) */
INPUT start_something (toto);
/* CIF OUTPUT (376, 1219), (270, 33) */
/* CIF OUTPUT (376, 1345), (270, 33) */
OUTPUT result_data((toto+1) mod 2147483647);
/* CIF PROCEDURECALL (436, 1267), (150, 48) */
/* CIF PROCEDURECALL (436, 1393), (150, 48) */
CALL writeln
('Hello Toto', toto);
/* CIF PROCEDURECALL (413, 1330), (196, 33) */
/* CIF PROCEDURECALL (413, 1456), (196, 33) */
CALL set_timer(1000, myTimer);
/* CIF TASK (346, 1378), (330, 35) */
/* CIF TASK (346, 1504), (330, 35) */
TASK largeReal := power(someReal, 2);
/* CIF PROCEDURECALL (282, 1428), (458, 35) */
/* CIF PROCEDURECALL (282, 1554), (458, 35) */
CALL writeln(someReal, ' ** 2' , ' == ', largeReal, ' (should be 2.25 )');
/* CIF TASK (411, 1478), (201, 35) */
/* CIF TASK (411, 1604), (201, 35) */
TASK someReal := float(someInt);
/* CIF TASK (391, 1528), (241, 35) */
/* CIF TASK (391, 1654), (241, 35) */
TASK someInt := fix(someReal) mod 255;
/* CIF TASK (435, 1578), (152, 35) */
/* CIF TASK (435, 1704), (152, 35) */
TASK opnot := not opnot;
/* CIF TASK (430, 1628), (163, 35) */
/* CIF TASK (430, 1754), (163, 35) */
TASK 'someint := -someint'
/* CIF COMMENT (613, 1628), (196, 35) */
/* CIF COMMENT (613, 1754), (196, 35) */
COMMENT 'XXX should raise an error!';
/* CIF TASK (429, 1678), (164, 35) */
/* CIF TASK (429, 1804), (164, 35) */
TASK someint := (-8) mod 5;
/* CIF NEXTSTATE (480, 1728), (63, 33) */
/* CIF NEXTSTATE (480, 1854), (63, 33) */
NEXTSTATE wait;
ENDSTATE;
ENDPROCESS myfunction;
\ No newline at end of file
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