Commit 6aac21a9 authored by Maxime Perrotin's avatar Maxime Perrotin

Support "x in {enum1Value1, enumValue2}" decisions

parent a5f381d3
......@@ -174,14 +174,16 @@ class Primary(Expression):
is_raw = True
def __init__(self, inputString='', line=-1, charPositionInLine=-1,
primary=None):
primary=None, debugLine=-1):
''' Initialize common primary attributes '''
self.debugLine = debugLine
if primary:
self.inputString = primary.inputString
self.line = primary.line
self.charPositionInLine = primary.charPositionInLine
self.value = primary.value
self.exprType = primary.exprType
self.debugLine = primary.debugLine
else:
self.inputString = inputString
self.line = line
......
......@@ -31,6 +31,7 @@ import math
import operator
import logging
import traceback
from inspect import currentframe, getframeinfo
import binascii
from textwrap import dedent
from itertools import chain, permutations, combinations
......@@ -168,6 +169,9 @@ new_ref_type = lambda refname: \
type_name = lambda t: \
t.kind if t.kind != 'ReferenceType' else t.ReferencedTypeName
# return the line number of this python module, useful for debugging
lineno = lambda : currentframe().f_back.f_lineno
# user may create SDL (non-asn1) types with the newtype keyword
# they are stored in a dedicated dictionary with the same structure
# as the ASN1SCC generated python AST
......@@ -686,7 +690,7 @@ def check_call(name, params, context):
for idx, param in enumerate(params):
warnings = []
expr = ogAST.ExprAssign()
expr.left = ogAST.PrimVariable()
expr.left = ogAST.PrimVariable(debugLine=lineno())
expr.left.exprType = sign[idx]['type']
expr.right = param
......@@ -1220,9 +1224,8 @@ def fix_enumerated_and_choice(expr_enum, context):
warnings = []
kind = find_basic_type(expr_enum.left.exprType).kind
if kind in ('EnumeratedType', 'StateEnumeratedType'):
prim = ogAST.PrimEnumeratedValue(primary=expr_enum.right)
elif kind == 'ChoiceEnumeratedType': # does not exist anymore, REMOVE
prim = ogAST.PrimChoiceDeterminant(primary=expr_enum.right)
prim = ogAST.PrimEnumeratedValue(primary=expr_enum.right,
debugLine=lineno())
try:
warnings.extend(check_type_compatibility(prim,
expr_enum.left.exprType,
......@@ -1262,7 +1265,7 @@ def fix_expression_types(expr, context): # type: -> [warnings]
asn_type = asn_type.type
for idx, elem in enumerate(value.value):
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.exprType = asn_type
check_expr.right = elem
warnings.extend(fix_expression_types(check_expr, context))
......@@ -1299,7 +1302,7 @@ def fix_expression_types(expr, context): # type: -> [warnings]
except AttributeError:
raise TypeError('Field not found: ' + field)
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.exprType = expected_type
check_expr.right = fd_expr
warnings.extend(fix_expression_types(check_expr, context))
......@@ -1320,7 +1323,7 @@ def fix_expression_types(expr, context): # type: -> [warnings]
except AttributeError:
raise TypeError('Field not found in CHOICE: ' + field)
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.exprType = expected_type
check_expr.right = expr.right.value['value']
warnings.extend(fix_expression_types(check_expr, context))
......@@ -1333,7 +1336,8 @@ def fix_expression_types(expr, context): # type: -> [warnings]
for det in ('then', 'else'):
# Recursively fix possibly missing types in the expression
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.inputString = expr.left.inputString # for debug
check_expr.left.exprType = expr.left.exprType
check_expr.right = expr.right.value[det]
warnings.extend(fix_expression_types(check_expr, context))
......@@ -1407,7 +1411,9 @@ def primary_variable(root, context):
elif is_fpar(name, context):
prim = ogAST.PrimFPAR()
else:
prim = ogAST.PrimVariable()
# We create a variable reference , but it may be a enumerated value,
# it will be replaced later during type resolution
prim = ogAST.PrimVariable(debugLine=lineno())
prim.value = [name]
prim.exprType = UNKNOWN_TYPE
......@@ -1793,7 +1799,7 @@ def relational_expression(root, context):
def in_expression(root, context):
''' In expression analysis '''
# Left and right are reversed for IN operator
# WARNING: Left and right are reversed for IN operator
root.children[0], root.children[1] = root.children[1], root.children[0]
expr, errors, warnings = binary_expression(root, context)
......@@ -1810,6 +1816,7 @@ def in_expression(root, context):
msg = 'IN expression: right part must be a list'
errors.append(error(root, msg))
return expr, errors, warnings
expr.left.exprType = ref_type
if find_basic_type(ref_type).kind == 'EnumeratedType':
......@@ -1817,6 +1824,24 @@ def in_expression(root, context):
expr.left.exprType = left_type
# if left is raw we must check each element with the type on the right
# in "foo in {enum1, enum2}" we must check that enum1 and enum2 are both
# of the same type as foo
if expr.left.is_raw and not expr.right.is_raw:
# we must check that all entries are compatible with ref_type
# and if they were variables, but are in fact raw enumerants, they
# must be changed from ogAST.PrimVariable to ogAST.PrimEnumeratedValue
for idx, value in enumerate(expr.left.value):
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.exprType = ref_type
check_expr.right = value
try:
warnings.extend(fix_expression_types(check_expr, context))
except TypeError as err:
errors.append(error(root, str(err)))
expr.left.value[idx] = check_expr.right
try:
warnings.extend(compare_types(expr.right.exprType, ref_type))
except TypeError as err:
......@@ -2394,7 +2419,7 @@ def variables(root, ta_ast, context):
errors.extend(err)
warnings.extend(warn)
expr = ogAST.ExprAssign()
expr.left = ogAST.PrimVariable()
expr.left = ogAST.PrimVariable(debugLine=lineno())
expr.left.inputString = var[-1]
expr.left.exprType = asn1_sort
expr.right = def_value
......@@ -2778,7 +2803,7 @@ def procedure_post(proc, content, parent=None, context=None):
[0, 0], []])
elif proc.return_type and each.return_expr:
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimVariable()
check_expr.left = ogAST.PrimVariable(debugLine=lineno())
check_expr.left.exprType = proc.return_type
check_expr.right = each.return_expr
try:
......
......@@ -30,6 +30,8 @@ Toto ::= SEQUENCE { elem-1 Type1, elem-2 Type2 }
SeqBool ::= SEQUENCE(SIZE(1..5)) OF BOOLEAN
Enum-T ::= ENUMERATED {enum1, enum2, enum3}
ForTheSakeOfIt ::= SEQUENCE (SIZE (2)) OF Enum-T
default-seqof SeqOf ::= {4,7,9}
default-str My-OctStr ::= 'DEADBEEF'H
......
......@@ -24,62 +24,68 @@ system og;
connect c and r;
/* CIF PROCESS (225, 49), (150, 75) */
process og;
/* CIF TEXT (57, 58), (290, 173) */
/* CIF TEXT (57, 58), (321, 173) */
dcl test Some_Thing := 4;
dcl someEnum Enum_T := enum2;
dcl somSeq Toto := {elem_1 1, elem_2 false};
dcl testincase ForTheSakeOfIt := {enum1, enum2};
/* CIF ENDTEXT */
/* CIF START (371, 221), (70, 35) */
/* CIF START (556, 221), (70, 35) */
START;
/* CIF decision (348, 276), (115, 50) */
/* CIF task (492, 276), (197, 35) */
task testincase := {enum1, enum2};
/* CIF decision (533, 326), (115, 50) */
decision test in { 1,2,3,4};
/* CIF ANSWER (287, 346), (70, 23) */
/* CIF ANSWER (472, 396), (70, 23) */
(true):
/* CIF PROCEDURECALL (266, 389), (112, 35) */
/* CIF PROCEDURECALL (451, 439), (112, 35) */
call writeln('OK 1');
/* CIF ANSWER (416, 346), (70, 23) */
/* CIF ANSWER (601, 396), (70, 23) */
(false):
/* CIF PROCEDURECALL (383, 389), (135, 35) */
/* CIF PROCEDURECALL (568, 439), (135, 35) */
call writeln('ERROR 1');
enddecision;
/* CIF decision (359, 439), (93, 50) */
/* CIF decision (544, 489), (93, 50) */
decision 3 in {1,2,3,4};
/* CIF ANSWER (293, 509), (70, 23) */
/* CIF ANSWER (478, 559), (70, 23) */
(true):
/* CIF PROCEDURECALL (268, 552), (119, 35) */
/* CIF PROCEDURECALL (453, 602), (119, 35) */
call writeln('OK 2');
/* CIF ANSWER (427, 509), (70, 23) */
/* CIF ANSWER (612, 559), (70, 23) */
(false):
/* CIF PROCEDURECALL (391, 552), (142, 35) */
/* CIF PROCEDURECALL (576, 602), (142, 35) */
call writeln('ERROR 2');
enddecision;
/* CIF decision (306, 602), (200, 50) */
/* CIF decision (491, 652), (200, 50) */
decision someEnum in {enum1, enum2};
/* CIF ANSWER (290, 672), (70, 23) */
/* CIF ANSWER (475, 722), (70, 23) */
(true):
/* CIF PROCEDURECALL (265, 715), (119, 35) */
/* CIF PROCEDURECALL (450, 765), (119, 35) */
call writeln('OK 3');
/* CIF ANSWER (430, 672), (70, 23) */
/* CIF ANSWER (615, 722), (70, 23) */
(false):
/* CIF PROCEDURECALL (394, 715), (142, 35) */
/* CIF PROCEDURECALL (579, 765), (142, 35) */
call writeln('ERROR 3');
enddecision;
/* CIF decision (203, 765), (406, 50) */
/* CIF decision (388, 815), (406, 50) */
decision 'someSeq in {{elem_1 1, elem_2 false}, {elem_1 0, elem_2 true}}'
/* CIF comment (629, 772), (226, 35) */
/* CIF comment (814, 822), (226, 35) */
comment 'cause bug in Ada backend: FIXME';
/* CIF ANSWER (290, 835), (70, 23) */
/* CIF ANSWER (475, 885), (70, 23) */
(true):
/* CIF PROCEDURECALL (265, 878), (119, 35) */
/* CIF PROCEDURECALL (450, 928), (119, 35) */
call writeln('OK 5');
/* CIF ANSWER (430, 835), (70, 23) */
/* CIF ANSWER (615, 885), (70, 23) */
(false):
/* CIF PROCEDURECALL (394, 878), (142, 35) */
/* CIF PROCEDURECALL (579, 928), (142, 35) */
call writeln('ERROR 5');
enddecision;
/* CIF NEXTSTATE (371, 928), (70, 35) */
/* CIF NEXTSTATE (556, 978), (70, 35) */
NEXTSTATE wait;
/* CIF state (826, 332), (70, 35) */
state wait;
......
[General]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\x3\xd3\0\0\0\xa3\0\0\t\xf3\0\0\x5\r\0\0\x3\xd5\0\0\0\xba\0\0\t\xf1\0\0\x5\v\0\0\0\0\0\0)
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\x3$\0\0\0\x63\0\0\tD\0\0\x4\xcd\0\0\x3&\0\0\0z\0\0\tB\0\0\x4\xcb\0\0\0\0\0\0)
windowState="@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x2\0\0\0\x1\0\0\x2,\0\0\x3\x65\xfc\x2\0\0\0\x1\xfc\0\0\0>\0\0\x3\x65\0\0\0\x9a\x1\0\0\x1a\xfa\0\0\0\0\x2\0\0\0\x2\xfb\0\0\0\x1c\0\x64\0\x61\0t\0\x61\0t\0y\0p\0\x65\0s\0_\0\x64\0o\0\x63\0k\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\x7f\0\xff\xff\xff\xfb\0\0\0\x1a\0\x64\0\x61\0t\0\x61\0\x64\0i\0\x63\0t\0_\0\x64\0o\0\x63\0k\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\x7f\0\xff\xff\xff\0\0\0\x3\0\0\x5\xea\0\0\0\x8c\xfc\x1\0\0\0\x1\xfb\0\0\0\xe\0m\0s\0g\0\x44\0o\0\x63\0k\x1\0\0\0\x33\0\0\x5\xea\0\0\0T\0\a\xff\xff\0\0\x3\xb8\0\0\x3\x65\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x2\0\0\0\0\0\0\0\x1\0\0\0\x16\0S\0\x44\0L\0 \0T\0o\0o\0l\0\x62\0\x61\0r\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x2\0\0\0\x1\0\0\0\x18\0\x46\0i\0l\0\x65\0 \0T\0o\0o\0l\0\x62\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\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