Commit 0ebeef6e authored by dbarbera's avatar dbarbera
Browse files

Added unary expressions nodes

parent 0d5c683e
......@@ -723,8 +723,7 @@ def _primary_variable(prim):
''' Single variable reference '''
sep = u'l_' if find_var(prim.value[0]) else u''
string = u'{sep}{name}'.format(sep=sep, name=prim.value[0])
ada_string = unary(prim, string)
ada_string = u'{sep}{name}'.format(sep=sep, name=prim.value[0])
if prim.exprType.__name__ == 'for_range':
# Ada iterator in FOR loops is an Integer - we must cast to 64 bits
......@@ -896,7 +895,6 @@ def _prim_path(primary_id):
ada_string += ', '.join(list_of_params)
ada_string += ')'
sep = '.'
ada_string = unary(primary_id, ada_string)
return stmts, ada_string, local_decl
......@@ -924,7 +922,6 @@ def _basic_operators(expr):
code.extend(right_stmts)
local_decl.extend(left_local)
local_decl.extend(right_local)
ada_string = unary(expr, ada_string)
return code, ada_string, local_decl
......@@ -964,7 +961,18 @@ def _bitwise_operators(expr):
code.extend(right_stmts)
local_decl.extend(left_local)
local_decl.extend(right_local)
ada_string = unary(expr, ada_string)
return code, ada_string, local_decl
@expression.register(ogAST.ExprNot)
@expression.register(ogAST.ExprNeg)
def _unary_operator(expr):
''' Generate the code for an unary expression '''
code, local_decl = [], []
expr_stmts, expr_str, expr_local = expression(expr.expr)
ada_string = u'({op} {expr})'.format(op=expr.operand, expr=expr_str)
code.extend(expr_stmts)
local_decl.extend(expr_local)
return code, ada_string, local_decl
......@@ -1090,8 +1098,11 @@ def _choice_determinant(primary):
@expression.register(ogAST.PrimReal)
def _integer(primary):
''' Generate code for a raw numerical value '''
if float(primary.value[0]) < 0:
# Parentesize negative integers for maintaining the precedence in the generated code
ada_string = '({})'.format(primary.value[0])
else:
ada_string = primary.value[0]
ada_string = unary(primary, ada_string)
return [], ada_string, []
......@@ -1099,7 +1110,6 @@ def _integer(primary):
def _integer(primary):
''' Generate code for a raw boolean value '''
ada_string = primary.value[0]
ada_string = unary(primary, ada_string)
return [], ada_string, []
......@@ -1514,25 +1524,6 @@ def _inner_procedure(proc):
return code, local_decl
# A few helper functions needed by the Ada backend
def unary(expr, string):
''' Check for NOT or MINUS unary operators and add them to the string '''
op_minus = getattr(expr, 'op_minus', False)
op_not = getattr(expr, 'op_not', False)
try:
float_val = float(string)
except ValueError:
float_val = 1
if op_minus and float_val > 0:
string = u'(-{})'.format(string)
elif float_val <= 0:
string = u'({})'.format(string)
if op_not:
string = u'not {}'.format(string)
return string
def find_basic_type(a_type):
''' Return the ASN.1 basic type of a_type '''
basic_type = a_type
......
......@@ -127,6 +127,14 @@ class ExprRem(Expression):
operand = 'rem'
class ExprNot(Expression):
operand = 'not'
class ExprNeg(Expression):
operand = '-'
class ExprAssign(Expression):
operand = ':='
......@@ -157,16 +165,12 @@ class Primary(Expression):
self.inputString = primary.inputString
self.line = primary.line
self.charPositionInLine = primary.charPositionInLine
self.op_not = primary.op_not
self.op_minus = primary.op_minus
self.value = primary.value
self.exprType = primary.exprType
else:
self.inputString = inputString
self.line = line
self.charPositionInLine = charPositionInLine
self.op_not = False
self.op_minus = False
self.value = None
self.exprType = None
......
......@@ -61,6 +61,8 @@ OPKIND = {lexer.PLUS: ogAST.ExprPlus,
lexer.APPEND: ogAST.ExprAppend,
lexer.IN: ogAST.ExprIn,
lexer.REM: ogAST.ExprRem,
lexer.NOT: ogAST.ExprNot,
lexer.NEG: ogAST.ExprNeg,
lexer.PRIMARY: ogAST.Primary}
# Insert current path in the search list for importing modules
......@@ -861,8 +863,28 @@ def find_type(path, context):
return result
def fix_expression_type(expr, context):
''' Check/ensure type consistency in unary expressions '''
if expr.expr.exprType == UNKNOWN_TYPE \
and isinstance(expr.expr, ogAST.PrimPath) \
and len(expr.expr.value) == 1:
try:
exprType = find_variable(expr.expr.value[0], context)
# Differentiate DCL and FPAR variables
use_type = ogAST.PrimVariable
if isinstance(context, ogAST.Procedure):
for each in context.fpar:
if each['name'].lower() == expr.expr.value[0].lower():
use_type = ogAST.PrimFPAR
break
expr.expr = use_type(primary=expr.expr)
expr.expr.exprType = exprType
except AttributeError:
pass
def fix_expression_types(expr, context):
''' Check/ensure type consistency in expressions having two sides '''
''' Check/ensure type consistency in binary expressions '''
if isinstance(expr, ogAST.Primary):
return
......@@ -1249,14 +1271,9 @@ def primary(root, context):
''' Process a primary (-/NOT value) '''
warnings = []
errors = []
op_not, op_minus = False, False
prim = None
for child in root.getChildren():
if child.type == lexer.NOT:
op_not = True
elif child.type == lexer.MINUS:
op_minus = True
elif child.type == lexer.PRIMARY_ID:
if child.type == lexer.PRIMARY_ID:
# Variable reference, indexed values, or ASN.1 value notation
prim, err, warn = primary_value(child, context=context)
errors.extend(err)
......@@ -1292,10 +1309,6 @@ def primary(root, context):
prim.inputString = get_input_string(root)
prim.line = root.getLine()
prim.charPositionInLine = root.getCharPositionInLine()
if op_not:
prim.op_not = True
if op_minus:
prim.op_minus = True
return prim, errors, warnings
......@@ -1325,7 +1338,7 @@ def expression(root, context):
root.children.pop(idx)
break
# Binary expressions
if root.type in (lexer.PLUS,
lexer.ASTERISK,
lexer.DASH,
......@@ -1374,6 +1387,15 @@ def expression(root, context):
format(expr.inputString, str(report)))
expr = new_expr
# Unary expressions
elif root.type in (lexer.NOT, lexer.NEG):
child = root.getChildren()[0]
expr.expr, err_expr, warn_expr = expression(child, context)
errors.extend(err_expr)
warnings.extend(warn_expr)
fix_expression_type(expr, context)
if root.type in (lexer.EQ,
lexer.NEQ,
lexer.GT,
......@@ -1414,7 +1436,6 @@ def expression(root, context):
errors.append('Check that all your numerical data types have '
'a range constraint')
elif root.type in (lexer.OR, lexer.AND, lexer.XOR):
# in the case of bitwise operators, if both sides are arrays,
# then the result is an array too
......@@ -1425,15 +1446,22 @@ def expression(root, context):
else:
expr.exprType = expr.left.exprType
elif root.type in (lexer.PLUS,
lexer.ASTERISK,
lexer.DASH,
lexer.DIV,
lexer.APPEND,
lexer.REM,
lexer.MOD):
elif root.type == lexer.NOT:
basic = find_basic_type(expr.expr.exprType)
if basic.kind == 'BooleanType':
expr.exprType = BOOLEAN
else:
expr.exprType = expr.expr.exprType
elif root.type == lexer.APPEND:
expr.exprType = expr.left.exprType
elif root.type == lexer.NEG:
basic = find_basic_type(expr.expr.exprType)
attrs = {'Min': str(-float(basic.Max)),
'Max': str(-float(basic.Min))}
expr.exprType = type('Neg', (basic,), attrs)
if root.type == lexer.PRIMARY:
expr, err, warn = primary(root, context)
if not expr:
......
......@@ -89,7 +89,7 @@ tokens {
VARIABLES;
SORT;
DCL;
MINUS;
NEG;
GROUND;
TEXTAREA;
TEXTAREA_CONTENT;
......@@ -795,18 +795,28 @@ variable
field_selection
: (('!'|'.') field_name);
expression : operand0 ( IMPLIES^ operand0)* ;
operand0 : operand1 (( (OR^ ELSE?) | XOR^ ) operand1)*;
operand1 : operand2 ( AND^ THEN? operand2)*;
operand2 : operand3
(( EQ^ | NEQ^ | GT^ | GE^ | LT^ | LE^ | IN^ )
operand3)*;
operand3 : operand4 (( PLUS^ | DASH^ | APPEND^ ) operand4)*;
operand4 : operand5
(( ASTERISK^ | DIV^ | MOD^ | REM^ ) operand5)*;
operand5 : primary_qualifier? primary
-> ^(PRIMARY primary_qualifier? primary);
expression
: operand0 ( IMPLIES^ operand0)* ;
operand0
: operand1 (( (OR^ ELSE?) | XOR^ ) operand1)*;
operand1
: operand2 ( AND^ THEN? operand2)*;
operand2
: operand3 (( EQ^ | NEQ^ | GT^ | GE^ | LT^ | LE^ | IN^ ) operand3)*;
operand3
: operand4 (( PLUS^ | DASH^ | APPEND^ ) operand4)*;
operand4
: operand5 (( ASTERISK^ | DIV^ | MOD^ | REM^ ) operand5)*;
operand5
: primary -> ^(PRIMARY primary)
| NOT^ operand5
| DASH operand5 -> ^(NEG operand5);
// primary below covers all cases including ASN.1 Value Notation
primary
......@@ -869,12 +879,6 @@ namedValue
: ID expression;
primary_qualifier
: DASH
-> ^(MINUS)
| NOT;
primary_params
: '(' expression_list ')'
-> ^(PARAMS expression_list)
......
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-07-02 08:11:12
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-07-07 18:45:53
import sys
from antlr3 import *
......@@ -11,12 +11,12 @@ HIDDEN = BaseRecognizer.HIDDEN
# token types
NUMBER_OF_INSTANCES=24
COMMENT2=211
MANTISSA=169
MANTISSA=170
ROUTE=93
MOD=156
GROUND=76
PARAM=83
NOT=172
NOT=158
SEQOF=13
TEXTAREA_CONTENT=78
EOF=-1
......@@ -68,10 +68,10 @@ Y=184
X=200
FI=65
Z=213
MINUS_INFINITY=165
MINUS_INFINITY=166
WS=210
OUT=129
FloatingPointLiteral=166
FloatingPointLiteral=167
NONE=130
INPUT_NONE=27
CONSTANT=44
......@@ -113,11 +113,10 @@ SIGNALROUTE=116
ENDSYNTYPE=101
SORT=73
SET=36
MINUS=75
TEXT=53
SEMI=124
TEXTAREA=77
StringLiteral=162
StringLiteral=163
BLOCK=94
CIF=66
START=122
......@@ -128,12 +127,12 @@ STRING=19
INPUTLIST=69
EXTERNAL=85
LT=142
EXPONENT=171
EXPONENT=172
TRANSITION=25
ENDBLOCK=115
RESET=37
ENDNEWTYPE=103
BitStringLiteral=158
BitStringLiteral=159
SIGNAL_LIST=30
ENDTEXT=22
CONNECTION=92
......@@ -141,7 +140,7 @@ SYSTEM=88
CONNECT=99
L_PAREN=132
PROCEDURE_CALL=34
BASE=170
BASE=171
COMMENT=9
SYNONYM=109
ENDALTERNATIVE=136
......@@ -153,7 +152,7 @@ OCTSTR=18
VIEW=175
EMPTYSTR=14
ENDCHANNEL=112
NULL=163
NULL=164
ANSWER=41
PRIMARY=61
TASK=79
......@@ -165,16 +164,16 @@ PRIORITY=131
SPECIFIC=177
OR=150
COMPOSITE_STATE=98
OctetStringLiteral=159
OctetStringLiteral=160
FIELD=108
USE=89
FROM=113
ENDPROCEDURE=120
FALSE=161
FALSE=162
OUTPUT=50
SYNONYM_LIST=110
APPEND=154
L_BRACKET=167
L_BRACKET=168
PRIMARY_ID=62
DIGITS=21
HYPERLINK=67
......@@ -207,8 +206,8 @@ STRUCT=106
SAVE=28
FIELDS=107
REM=157
TRUE=160
R_BRACKET=168
TRUE=161
R_BRACKET=169
PROCEDURE=35
JOIN=55
R_PAREN=133
......@@ -217,10 +216,11 @@ NEQ=140
ANY=138
QUESTION=81
LABEL=7
PLUS_INFINITY=164
PLUS_INFINITY=165
PARAMNAMES=95
ASN1=96
KEEP=176
NEG=75
ASSIGN=52
VARIABLES=72
ALTERNATIVE=40
......@@ -450,11 +450,11 @@ class sdl92Lexer(Lexer):
_type = BitStringLiteral
_channel = DEFAULT_CHANNEL
# sdl92.g:848:9: ( '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B' )
# sdl92.g:848:17: '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B'
# sdl92.g:858:9: ( '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B' )
# sdl92.g:858:17: '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B'
pass
self.match(34)
# sdl92.g:848:21: ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )*
# sdl92.g:858:21: ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )*
while True: #loop1
alt1 = 2
LA1_0 = self.input.LA(1)
......@@ -499,11 +499,11 @@ class sdl92Lexer(Lexer):
_type = OctetStringLiteral
_channel = DEFAULT_CHANNEL
# sdl92.g:852:9: ( '\"' ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )* '\"H' )
# sdl92.g:852:17: '\"' ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )* '\"H'
# sdl92.g:862:9: ( '\"' ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )* '\"H' )
# sdl92.g:862:17: '\"' ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )* '\"H'
pass
self.match(34)
# sdl92.g:852:21: ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )*
# sdl92.g:862:21: ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | ' ' | '\\t' | '\\r' | '\\n' )*
while True: #loop2
alt2 = 2
LA2_0 = self.input.LA(1)
......@@ -548,8 +548,8 @@ class sdl92Lexer(Lexer):
_type = ASSIG_OP
_channel = DEFAULT_CHANNEL
# sdl92.g:1158:17: ( ':=' )
# sdl92.g:1158:25: ':='
# sdl92.g:1162:17: ( ':=' )
# sdl92.g:1162:25: ':='
pass
self.match(":=")
......@@ -573,8 +573,8 @@ class sdl92Lexer(Lexer):
_type = L_BRACKET
_channel = DEFAULT_CHANNEL
# sdl92.g:1159:17: ( '{' )
# sdl92.g:1159:25: '{'
# sdl92.g:1163:17: ( '{' )
# sdl92.g:1163:25: '{'
pass
self.match(123)
......@@ -598,8 +598,8 @@ class sdl92Lexer(Lexer):
_type = R_BRACKET
_channel = DEFAULT_CHANNEL
# sdl92.g:1160:17: ( '}' )
# sdl92.g:1160:25: '}'
# sdl92.g:1164:17: ( '}' )
# sdl92.g:1164:25: '}'
pass
self.match(125)
......@@ -623,8 +623,8 @@ class sdl92Lexer(Lexer):
_type = L_PAREN
_channel = DEFAULT_CHANNEL
# sdl92.g:1161:17: ( '(' )
# sdl92.g:1161:25: '('
# sdl92.g:1165:17: ( '(' )
# sdl92.g:1165:25: '('
pass
self.match(40)
......@@ -648,8 +648,8 @@ class sdl92Lexer(Lexer):
_type = R_PAREN
_channel = DEFAULT_CHANNEL
# sdl92.g:1162:17: ( ')' )
# sdl92.g:1162:25: ')'
# sdl92.g:1166:17: ( ')' )
# sdl92.g:1166:25: ')'
pass
self.match(41)
......@@ -673,8 +673,8 @@ class sdl92Lexer(Lexer):
_type = COMMA
_channel = DEFAULT_CHANNEL
# sdl92.g:1163:17: ( ',' )
# sdl92.g:1163:25: ','
# sdl92.g:1167:17: ( ',' )
# sdl92.g:1167:25: ','
pass
self.match(44)
......@@ -698,8 +698,8 @@ class sdl92Lexer(Lexer):
_type = SEMI
_channel = DEFAULT_CHANNEL
# sdl92.g:1164:17: ( ';' )
# sdl92.g:1164:25: ';'
# sdl92.g:1168:17: ( ';' )
# sdl92.g:1168:25: ';'
pass
self.match(59)
......@@ -723,8 +723,8 @@ class sdl92Lexer(Lexer):
_type = DASH
_channel = DEFAULT_CHANNEL
# sdl92.g:1165:17: ( '-' )
# sdl92.g:1165:25: '-'
# sdl92.g:1169:17: ( '-' )
# sdl92.g:1169:25: '-'
pass
self.match(45)
......@@ -748,8 +748,8 @@ class sdl92Lexer(Lexer):
_type = ANY
_channel = DEFAULT_CHANNEL
# sdl92.g:1166:17: ( A N Y )
# sdl92.g:1166:25: A N Y
# sdl92.g:1170:17: ( A N Y )
# sdl92.g:1170:25: A N Y
pass
self.mA()
self.mN()
......@@ -775,8 +775,8 @@ class sdl92Lexer(Lexer):
_type = ASTERISK
_channel = DEFAULT_CHANNEL
# sdl92.g:1167:17: ( '*' )
# sdl92.g:1167:25: '*'
# sdl92.g:1171:17: ( '*' )
# sdl92.g:1171:25: '*'
pass
self.match(42)
......@@ -800,8 +800,8 @@ class sdl92Lexer(Lexer):
_type = DCL
_channel = DEFAULT_CHANNEL
# sdl92.g:1168:17: ( D C L )
# sdl92.g:1168:25: D C L
# sdl92.g:1172:17: ( D C L )
# sdl92.g:1172:25: D C L
pass
self.mD()
self.mC()
......@@ -827,8 +827,8 @@ class sdl92Lexer(Lexer):
_type = END
_channel = DEFAULT_CHANNEL
# sdl92.g:1169:17: ( E N D )
# sdl92.g:1169:25: E N D
# sdl92.g:1173:17: ( E N D )
# sdl92.g:1173:25: E N D
pass
self.mE()
self.mN()
......@@ -854,8 +854,8 @@ class sdl92Lexer(Lexer):
_type = KEEP
_channel = DEFAULT_CHANNEL
# sdl92.g:1170:17: ( K E E P )
# sdl92.g:1170:25: K E E P
# sdl92.g:1174:17: ( K E E P )
# sdl92.g:1174:25: K E E P
pass
self.mK()
self.mE()
......@@ -882,8 +882,8 @@ class sdl92Lexer(Lexer):
_type = PARAMNAMES
_channel = DEFAULT_CHANNEL
# sdl92.g:1171:17: ( P A R A M N A M E S )
# sdl92.g:1171:25: P A R A M N A M E S
# sdl92.g:1175:17: ( P A R A M N A M E S )
# sdl92.g:1175:25: P A R A M N A M E S
pass
self.mP()
self.mA()
......@@ -916,8 +916,8 @@ class sdl92Lexer(Lexer):
_type = SPECIFIC
_channel = DEFAULT_CHANNEL
# sdl92.g:1172:17: ( S P E C I F I C )
# sdl92.g:1172:25: S P E C I F I C
# sdl92.g:1176:17: ( S P E C I F I C )
# sdl92.g:1176:25: S P E C I F I C
pass
self.mS()
self.mP()
......@@ -948,8 +948,8 @@ class sdl92Lexer(Lexer):
_type = GEODE
_channel = DEFAULT_CHANNEL
# sdl92.g:1173:17: ( G E O D E )
# sdl92.g:1173:25: G E O D E
# sdl92.g:1177:17: ( G E O D E )
# sdl92.g:1177:25: G E O D E
pass
self.mG()
self.mE()
......@@ -977,8 +977,8 @@ class sdl92Lexer(Lexer):
_type = HYPERLINK
_channel = DEFAULT_CHANNEL
# sdl92.g:1174:17: ( H Y P E R L I N K )
# sdl92.g:1174:25: H Y P E R L I N K
# sdl92.g:1178:17: ( H Y P E R L I N K )
# sdl92.g:1178:25: H Y P E R L I N K
pass
self.mH()
self.mY()
......@@ -1010,8 +1010,8 @@ class sdl92Lexer(Lexer):
_type = ENDTEXT
_channel = DEFAULT_CHANNEL
# sdl92.g:1175:17: ( E N D T E X T )
# sdl92.g:1175:25: E N D T E X T
# sdl92.g:1179:17: ( E N D T E X T )
# sdl92.g:1179:25: E N D T E X T
pass
self.mE()
self.mN()
......@@ -1041,8 +1041,8 @@ class sdl92Lexer(Lexer):
_type = RETURN
_channel = DEFAULT_CHANNEL