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

Added unary expressions nodes

parent 0d5c683e
...@@ -723,8 +723,7 @@ def _primary_variable(prim): ...@@ -723,8 +723,7 @@ def _primary_variable(prim):
''' Single variable reference ''' ''' Single variable reference '''
sep = u'l_' if find_var(prim.value[0]) else u'' sep = u'l_' if find_var(prim.value[0]) else u''
string = u'{sep}{name}'.format(sep=sep, name=prim.value[0]) ada_string = u'{sep}{name}'.format(sep=sep, name=prim.value[0])
ada_string = unary(prim, string)
if prim.exprType.__name__ == 'for_range': if prim.exprType.__name__ == 'for_range':
# Ada iterator in FOR loops is an Integer - we must cast to 64 bits # Ada iterator in FOR loops is an Integer - we must cast to 64 bits
...@@ -896,7 +895,6 @@ def _prim_path(primary_id): ...@@ -896,7 +895,6 @@ def _prim_path(primary_id):
ada_string += ', '.join(list_of_params) ada_string += ', '.join(list_of_params)
ada_string += ')' ada_string += ')'
sep = '.' sep = '.'
ada_string = unary(primary_id, ada_string)
return stmts, ada_string, local_decl return stmts, ada_string, local_decl
...@@ -924,7 +922,6 @@ def _basic_operators(expr): ...@@ -924,7 +922,6 @@ def _basic_operators(expr):
code.extend(right_stmts) code.extend(right_stmts)
local_decl.extend(left_local) local_decl.extend(left_local)
local_decl.extend(right_local) local_decl.extend(right_local)
ada_string = unary(expr, ada_string)
return code, ada_string, local_decl return code, ada_string, local_decl
...@@ -964,7 +961,18 @@ def _bitwise_operators(expr): ...@@ -964,7 +961,18 @@ def _bitwise_operators(expr):
code.extend(right_stmts) code.extend(right_stmts)
local_decl.extend(left_local) local_decl.extend(left_local)
local_decl.extend(right_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 return code, ada_string, local_decl
...@@ -1090,8 +1098,11 @@ def _choice_determinant(primary): ...@@ -1090,8 +1098,11 @@ def _choice_determinant(primary):
@expression.register(ogAST.PrimReal) @expression.register(ogAST.PrimReal)
def _integer(primary): def _integer(primary):
''' Generate code for a raw numerical value ''' ''' 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 = primary.value[0]
ada_string = unary(primary, ada_string)
return [], ada_string, [] return [], ada_string, []
...@@ -1099,7 +1110,6 @@ def _integer(primary): ...@@ -1099,7 +1110,6 @@ def _integer(primary):
def _integer(primary): def _integer(primary):
''' Generate code for a raw boolean value ''' ''' Generate code for a raw boolean value '''
ada_string = primary.value[0] ada_string = primary.value[0]
ada_string = unary(primary, ada_string)
return [], ada_string, [] return [], ada_string, []
...@@ -1514,25 +1524,6 @@ def _inner_procedure(proc): ...@@ -1514,25 +1524,6 @@ def _inner_procedure(proc):
return code, local_decl 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): def find_basic_type(a_type):
''' Return the ASN.1 basic type of a_type ''' ''' Return the ASN.1 basic type of a_type '''
basic_type = a_type basic_type = a_type
......
...@@ -127,6 +127,14 @@ class ExprRem(Expression): ...@@ -127,6 +127,14 @@ class ExprRem(Expression):
operand = 'rem' operand = 'rem'
class ExprNot(Expression):
operand = 'not'
class ExprNeg(Expression):
operand = '-'
class ExprAssign(Expression): class ExprAssign(Expression):
operand = ':=' operand = ':='
...@@ -157,16 +165,12 @@ class Primary(Expression): ...@@ -157,16 +165,12 @@ class Primary(Expression):
self.inputString = primary.inputString self.inputString = primary.inputString
self.line = primary.line self.line = primary.line
self.charPositionInLine = primary.charPositionInLine self.charPositionInLine = primary.charPositionInLine
self.op_not = primary.op_not
self.op_minus = primary.op_minus
self.value = primary.value self.value = primary.value
self.exprType = primary.exprType self.exprType = primary.exprType
else: else:
self.inputString = inputString self.inputString = inputString
self.line = line self.line = line
self.charPositionInLine = charPositionInLine self.charPositionInLine = charPositionInLine
self.op_not = False
self.op_minus = False
self.value = None self.value = None
self.exprType = None self.exprType = None
......
...@@ -61,6 +61,8 @@ OPKIND = {lexer.PLUS: ogAST.ExprPlus, ...@@ -61,6 +61,8 @@ OPKIND = {lexer.PLUS: ogAST.ExprPlus,
lexer.APPEND: ogAST.ExprAppend, lexer.APPEND: ogAST.ExprAppend,
lexer.IN: ogAST.ExprIn, lexer.IN: ogAST.ExprIn,
lexer.REM: ogAST.ExprRem, lexer.REM: ogAST.ExprRem,
lexer.NOT: ogAST.ExprNot,
lexer.NEG: ogAST.ExprNeg,
lexer.PRIMARY: ogAST.Primary} lexer.PRIMARY: ogAST.Primary}
# Insert current path in the search list for importing modules # Insert current path in the search list for importing modules
...@@ -861,8 +863,28 @@ def find_type(path, context): ...@@ -861,8 +863,28 @@ def find_type(path, context):
return result 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): 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): if isinstance(expr, ogAST.Primary):
return return
...@@ -1249,14 +1271,9 @@ def primary(root, context): ...@@ -1249,14 +1271,9 @@ def primary(root, context):
''' Process a primary (-/NOT value) ''' ''' Process a primary (-/NOT value) '''
warnings = [] warnings = []
errors = [] errors = []
op_not, op_minus = False, False
prim = None prim = None
for child in root.getChildren(): for child in root.getChildren():
if child.type == lexer.NOT: if child.type == lexer.PRIMARY_ID:
op_not = True
elif child.type == lexer.MINUS:
op_minus = True
elif child.type == lexer.PRIMARY_ID:
# Variable reference, indexed values, or ASN.1 value notation # Variable reference, indexed values, or ASN.1 value notation
prim, err, warn = primary_value(child, context=context) prim, err, warn = primary_value(child, context=context)
errors.extend(err) errors.extend(err)
...@@ -1292,10 +1309,6 @@ def primary(root, context): ...@@ -1292,10 +1309,6 @@ def primary(root, context):
prim.inputString = get_input_string(root) prim.inputString = get_input_string(root)
prim.line = root.getLine() prim.line = root.getLine()
prim.charPositionInLine = root.getCharPositionInLine() prim.charPositionInLine = root.getCharPositionInLine()
if op_not:
prim.op_not = True
if op_minus:
prim.op_minus = True
return prim, errors, warnings return prim, errors, warnings
...@@ -1325,7 +1338,7 @@ def expression(root, context): ...@@ -1325,7 +1338,7 @@ def expression(root, context):
root.children.pop(idx) root.children.pop(idx)
break break
# Binary expressions
if root.type in (lexer.PLUS, if root.type in (lexer.PLUS,
lexer.ASTERISK, lexer.ASTERISK,
lexer.DASH, lexer.DASH,
...@@ -1374,6 +1387,15 @@ def expression(root, context): ...@@ -1374,6 +1387,15 @@ def expression(root, context):
format(expr.inputString, str(report))) format(expr.inputString, str(report)))
expr = new_expr 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, if root.type in (lexer.EQ,
lexer.NEQ, lexer.NEQ,
lexer.GT, lexer.GT,
...@@ -1414,7 +1436,6 @@ def expression(root, context): ...@@ -1414,7 +1436,6 @@ def expression(root, context):
errors.append('Check that all your numerical data types have ' errors.append('Check that all your numerical data types have '
'a range constraint') 'a range constraint')
elif root.type in (lexer.OR, lexer.AND, lexer.XOR): elif root.type in (lexer.OR, lexer.AND, lexer.XOR):
# in the case of bitwise operators, if both sides are arrays, # in the case of bitwise operators, if both sides are arrays,
# then the result is an array too # then the result is an array too
...@@ -1425,15 +1446,22 @@ def expression(root, context): ...@@ -1425,15 +1446,22 @@ def expression(root, context):
else: else:
expr.exprType = expr.left.exprType expr.exprType = expr.left.exprType
elif root.type in (lexer.PLUS, elif root.type == lexer.NOT:
lexer.ASTERISK, basic = find_basic_type(expr.expr.exprType)
lexer.DASH, if basic.kind == 'BooleanType':
lexer.DIV, expr.exprType = BOOLEAN
lexer.APPEND, else:
lexer.REM, expr.exprType = expr.expr.exprType
lexer.MOD):
elif root.type == lexer.APPEND:
expr.exprType = expr.left.exprType 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: if root.type == lexer.PRIMARY:
expr, err, warn = primary(root, context) expr, err, warn = primary(root, context)
if not expr: if not expr:
......
...@@ -89,7 +89,7 @@ tokens { ...@@ -89,7 +89,7 @@ tokens {
VARIABLES; VARIABLES;
SORT; SORT;
DCL; DCL;
MINUS; NEG;
GROUND; GROUND;
TEXTAREA; TEXTAREA;
TEXTAREA_CONTENT; TEXTAREA_CONTENT;
...@@ -795,18 +795,28 @@ variable ...@@ -795,18 +795,28 @@ variable
field_selection field_selection
: (('!'|'.') field_name); : (('!'|'.') field_name);
expression : operand0 ( IMPLIES^ operand0)* ; expression
operand0 : operand1 (( (OR^ ELSE?) | XOR^ ) operand1)*; : operand0 ( IMPLIES^ operand0)* ;
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);
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 below covers all cases including ASN.1 Value Notation
primary primary
...@@ -869,12 +879,6 @@ namedValue ...@@ -869,12 +879,6 @@ namedValue
: ID expression; : ID expression;
primary_qualifier
: DASH
-> ^(MINUS)
| NOT;
primary_params primary_params
: '(' expression_list ')' : '(' expression_list ')'
-> ^(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 import sys
from antlr3 import * from antlr3 import *
...@@ -11,12 +11,12 @@ HIDDEN = BaseRecognizer.HIDDEN ...@@ -11,12 +11,12 @@ HIDDEN = BaseRecognizer.HIDDEN
# token types # token types
NUMBER_OF_INSTANCES=24 NUMBER_OF_INSTANCES=24
COMMENT2=211 COMMENT2=211
MANTISSA=169 MANTISSA=170
ROUTE=93 ROUTE=93
MOD=156 MOD=156
GROUND=76 GROUND=76
PARAM=83 PARAM=83
NOT=172 NOT=158
SEQOF=13 SEQOF=13
TEXTAREA_CONTENT=78 TEXTAREA_CONTENT=78
EOF=-1 EOF=-1
...@@ -68,10 +68,10 @@ Y=184 ...@@ -68,10 +68,10 @@ Y=184
X=200 X=200
FI=65 FI=65
Z=213 Z=213
MINUS_INFINITY=165 MINUS_INFINITY=166
WS=210 WS=210
OUT=129 OUT=129
FloatingPointLiteral=166 FloatingPointLiteral=167
NONE=130 NONE=130
INPUT_NONE=27 INPUT_NONE=27
CONSTANT=44 CONSTANT=44
...@@ -113,11 +113,10 @@ SIGNALROUTE=116 ...@@ -113,11 +113,10 @@ SIGNALROUTE=116
ENDSYNTYPE=101 ENDSYNTYPE=101
SORT=73 SORT=73
SET=36 SET=36
MINUS=75
TEXT=53 TEXT=53
SEMI=124 SEMI=124
TEXTAREA=77 TEXTAREA=77
StringLiteral=162 StringLiteral=163
BLOCK=94 BLOCK=94
CIF=66 CIF=66
START=122 START=122
...@@ -128,12 +127,12 @@ STRING=19 ...@@ -128,12 +127,12 @@ STRING=19
INPUTLIST=69 INPUTLIST=69
EXTERNAL=85 EXTERNAL=85
LT=142 LT=142
EXPONENT=171 EXPONENT=172
TRANSITION=25 TRANSITION=25
ENDBLOCK=115 ENDBLOCK=115
RESET=37 RESET=37
ENDNEWTYPE=103 ENDNEWTYPE=103
BitStringLiteral=158 BitStringLiteral=159
SIGNAL_LIST=30 SIGNAL_LIST=30
ENDTEXT=22 ENDTEXT=22
CONNECTION=92 CONNECTION=92
...@@ -141,7 +140,7 @@ SYSTEM=88 ...@@ -141,7 +140,7 @@ SYSTEM=88
CONNECT=99 CONNECT=99
L_PAREN=132 L_PAREN=132
PROCEDURE_CALL=34 PROCEDURE_CALL=34
BASE=170 BASE=171
COMMENT=9 COMMENT=9
SYNONYM=109 SYNONYM=109
ENDALTERNATIVE=136 ENDALTERNATIVE=136
...@@ -153,7 +152,7 @@ OCTSTR=18 ...@@ -153,7 +152,7 @@ OCTSTR=18
VIEW=175 VIEW=175
EMPTYSTR=14 EMPTYSTR=14
ENDCHANNEL=112 ENDCHANNEL=112
NULL=163 NULL=164
ANSWER=41 ANSWER=41
PRIMARY=61 PRIMARY=61
TASK=79 TASK=79
...@@ -165,16 +164,16 @@ PRIORITY=131 ...@@ -165,16 +164,16 @@ PRIORITY=131
SPECIFIC=177 SPECIFIC=177
OR=150 OR=150
COMPOSITE_STATE=98 COMPOSITE_STATE=98
OctetStringLiteral=159 OctetStringLiteral=160
FIELD=108 FIELD=108
USE=89 USE=89
FROM=113 FROM=113
ENDPROCEDURE=120 ENDPROCEDURE=120
FALSE=161 FALSE=162
OUTPUT=50 OUTPUT=50
SYNONYM_LIST=110 SYNONYM_LIST=110
APPEND=154 APPEND=154
L_BRACKET=167 L_BRACKET=168
PRIMARY_ID=62 PRIMARY_ID=62
DIGITS=21 DIGITS=21
HYPERLINK=67 HYPERLINK=67
...@@ -207,8 +206,8 @@ STRUCT=106 ...@@ -207,8 +206,8 @@ STRUCT=106
SAVE=28 SAVE=28
FIELDS=107 FIELDS=107
REM=157 REM=157
TRUE=160 TRUE=161
R_BRACKET=168 R_BRACKET=169
PROCEDURE=35 PROCEDURE=35
JOIN=55 JOIN=55
R_PAREN=133 R_PAREN=133
...@@ -217,10 +216,11 @@ NEQ=140 ...@@ -217,10 +216,11 @@ NEQ=140
ANY=138 ANY=138
QUESTION=81 QUESTION=81
LABEL=7 LABEL=7
PLUS_INFINITY=164 PLUS_INFINITY=165
PARAMNAMES=95 PARAMNAMES=95
ASN1=96 ASN1=96
KEEP=176 KEEP=176
NEG=75
ASSIGN=52 ASSIGN=52
VARIABLES=72 VARIABLES=72
ALTERNATIVE=40 ALTERNATIVE=40
...@@ -450,11 +450,11 @@ class sdl92Lexer(Lexer): ...@@ -450,11 +450,11 @@ class sdl92Lexer(Lexer):
_type = BitStringLiteral _type = BitStringLiteral
_channel = DEFAULT_CHANNEL _channel = DEFAULT_CHANNEL
# sdl92.g:848:9: ( '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B' ) # sdl92.g:858:9: ( '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B' )
# sdl92.g:848:17: '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B' # sdl92.g:858:17: '\"' ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* '\"B'
pass pass
self.match(34) self.match(34)
# sdl92.g:848:21: ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )* # sdl92.g:858:21: ( '0' | '1' | ' ' | '\\t' | '\\r' | '\\n' )*
while True: #loop1 while True: #loop1
alt1 = 2 alt1 = 2
LA1_0 = self.input.LA(1) LA1_0 = self.input.LA(1)
...@@ -499,11 +499,11 @@ class sdl92Lexer(Lexer): ...@@ -499,11 +499,11 @@ class sdl92Lexer(Lexer):
_type = OctetStringLiteral _type = OctetStringLiteral
_channel = DEFAULT_CHANNEL _channel = DEFAULT_CHANNEL
# sdl92.g:852:9: ( '\"' ( '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:852:17: '\"' ( '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 pass
self.match(34) 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 while True: #loop2
alt2 = 2 alt2 = 2
LA2_0 = self.input.LA(1) LA2_0 = self.input.LA(1)
...@@ -548,8 +548,8 @@ class sdl92Lexer(Lexer): ...@@ -548,8 +548,8 @@ class sdl92Lexer(Lexer):