Commit 0120930d authored by dbarbera's avatar dbarbera
Browse files

Refactor primary variable analysis

parent d081e56a
......@@ -866,51 +866,11 @@ 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 binary expressions '''
if isinstance(expr, ogAST.Primary):
return
for side in ('left', 'right'):
# Determine if the expression is a variable
uk_expr = getattr(expr, side)
if uk_expr.exprType == UNKNOWN_TYPE \
and isinstance(uk_expr, ogAST.PrimPath) \
and len(uk_expr.value) == 1:
try:
exprType = find_variable(uk_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() == uk_expr.value[0].lower():
use_type = ogAST.PrimFPAR
break
setattr(expr, side, use_type(primary=uk_expr))
getattr(expr, side).exprType = exprType
except AttributeError:
pass
# If a side of the expression is of Enumerated or Choice type, check if
# the other side is a literal of that sort, and change type accordingly
for side in permutations(('left', 'right')):
......@@ -1074,9 +1034,6 @@ def primary_path(root, context=None):
prim.inputString = get_input_string(root)
prim.tmpVar = tmp()
if len(root.children) == 1:
return prim, errors, warnings
proc_list = [proc.inputString.lower() for proc in context.procedures]
call = prim.value[0].lower() in (SPECIAL_OPERATORS.keys() + proc_list)
......@@ -1126,6 +1083,32 @@ def primary_path(root, context=None):
return prim, errors, warnings
def primary_variable(root, context):
''' Primary Variable analysis '''
lexeme = root.children[0].text
# Differentiate DCL and FPAR variables
Prim = ogAST.PrimVariable
if isinstance(context, ogAST.Procedure):
for each in context.fpar:
if each['name'].lower() == lexeme.lower():
Prim = ogAST.PrimFPAR
break
prim, errors, warnings = Prim(), [], []
prim.value = [root.children[0].text]
prim.exprType = UNKNOWN_TYPE
prim.inputString = get_input_string(root)
prim.tmpVar = tmp()
try:
prim.exprType = find_variable(lexeme, context)
except AttributeError:
pass
return prim, errors, warnings
def tmp():
''' Return a temporary variable name '''
global TMPVAR
......@@ -1379,8 +1362,6 @@ def not_expression(root, context):
''' Not expression analysis '''
expr, errors, warnings = unary_expression(root, context)
fix_expression_type(expr, context)
bty = find_basic_type(expr.expr.exprType)
if bty.kind in ('BooleanType', ):
expr.exprType = BOOLEAN
......@@ -1399,8 +1380,6 @@ def neg_expression(root, context):
''' Negative expression analysis '''
expr, errors, warnings = unary_expression(root, context)
fix_expression_type(expr, context)
basic = find_basic_type(expr.expr.exprType)
if not basic.kind in ('IntegerType', 'Integer32Type', 'RealType'):
msg = 'Negative expressions can only be applied to numeric types'
......@@ -1450,7 +1429,9 @@ def primary(root, context):
''' Literal expression analysis '''
prim, errors, warnings = None, [], []
if root.type == lexer.PATH:
if root.type == lexer.VARIABLE:
return primary_variable(root, context)
elif root.type == lexer.PATH:
return primary_path(root, context)
elif root.type == lexer.INT:
prim = ogAST.PrimInteger()
......@@ -3057,21 +3038,18 @@ def assign(root, context):
get_input_string(root), root.getLine(),
root.getCharPositionInLine())
expr.kind = 'assign'
for child in root.getChildren():
if child.type == lexer.VARIABLE:
# Left part of the assignation
prim, err, warn = primary_path(child, context)
prim.inputString = get_input_string(child)
prim.line = child.getLine()
prim.charPositionInLine = child.getCharPositionInLine()
warnings.extend(warn)
errors.extend(err)
expr.left = prim
else:
# Right part of the assignation
expr.right, err, warn = expression(child, context)
errors.extend(err)
warnings.extend(warn)
if root.children[0].type == lexer.PATH:
expr.left, err, warn = primary_path(root.children[0], context)
else:
expr.left, err, warn = primary_variable(root.children[0], context)
warnings.extend(warn)
errors.extend(err)
expr.right, err, warn = expression(root.children[1], context)
errors.extend(err)
warnings.extend(warn)
try:
fix_expression_types(expr, context)
except(AttributeError, TypeError) as err:
......@@ -3130,6 +3108,11 @@ def for_loop(root, context):
# Implicit variable declaration for the iterator
context_scope = dict(context.variables)
elif child.type == lexer.VARIABLE:
list_var, err, warn = primary_variable(child, context)
forloop['list'] = ogAST.PrimVariable(primary=list_var)
warnings.extend(warn)
errors.extend(err)
elif child.type == lexer.PATH:
list_var, err, warn = primary_path(child, context)
forloop['list'] = ogAST.PrimVariable(primary=list_var)
warnings.extend(warn)
......
......@@ -791,8 +791,9 @@ assignement_statement
// Variable: covers eg. toto(5)(4)!titi(3)!tutu!yoyo
variable
: variable_id primary_params*
-> ^(VARIABLE variable_id primary_params*);
: ID primary_params+ -> ^(PATH ID primary_params+)
| ID -> ^(VARIABLE ID);
field_selection
: (('!'|'.') field_name);
......@@ -836,7 +837,8 @@ primary
| INT^
| FLOAT^
| ID ':' expression -> ^(CHOICE ID expression)
| ID primary_params* -> ^(PATH ID primary_params*)
| ID primary_params+ -> ^(PATH ID primary_params+)
| ID -> ^(VARIABLE ID)
| '{' '}' -> ^(EMPTYSTR)
| '{'
MANTISSA mant=INT COMMA
......
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-07-11 20:14:50
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-07-13 22:58:35
import sys
from antlr3 import *
......@@ -448,8 +448,8 @@ class sdl92Lexer(Lexer):
_type = ASSIG_OP
_channel = DEFAULT_CHANNEL
# sdl92.g:1144:17: ( ':=' )
# sdl92.g:1144:25: ':='
# sdl92.g:1146:17: ( ':=' )
# sdl92.g:1146:25: ':='
pass
self.match(":=")
......@@ -473,8 +473,8 @@ class sdl92Lexer(Lexer):
_type = L_BRACKET
_channel = DEFAULT_CHANNEL
# sdl92.g:1145:17: ( '{' )
# sdl92.g:1145:25: '{'
# sdl92.g:1147:17: ( '{' )
# sdl92.g:1147:25: '{'
pass
self.match(123)
......@@ -498,8 +498,8 @@ class sdl92Lexer(Lexer):
_type = R_BRACKET
_channel = DEFAULT_CHANNEL
# sdl92.g:1146:17: ( '}' )
# sdl92.g:1146:25: '}'
# sdl92.g:1148:17: ( '}' )
# sdl92.g:1148:25: '}'
pass
self.match(125)
......@@ -523,8 +523,8 @@ class sdl92Lexer(Lexer):
_type = L_PAREN
_channel = DEFAULT_CHANNEL
# sdl92.g:1147:17: ( '(' )
# sdl92.g:1147:25: '('
# sdl92.g:1149:17: ( '(' )
# sdl92.g:1149:25: '('
pass
self.match(40)
......@@ -548,8 +548,8 @@ class sdl92Lexer(Lexer):
_type = R_PAREN
_channel = DEFAULT_CHANNEL
# sdl92.g:1148:17: ( ')' )
# sdl92.g:1148:25: ')'
# sdl92.g:1150:17: ( ')' )
# sdl92.g:1150:25: ')'
pass
self.match(41)
......@@ -573,8 +573,8 @@ class sdl92Lexer(Lexer):
_type = COMMA
_channel = DEFAULT_CHANNEL
# sdl92.g:1149:17: ( ',' )
# sdl92.g:1149:25: ','
# sdl92.g:1151:17: ( ',' )
# sdl92.g:1151:25: ','
pass
self.match(44)
......@@ -598,8 +598,8 @@ class sdl92Lexer(Lexer):
_type = SEMI
_channel = DEFAULT_CHANNEL
# sdl92.g:1150:17: ( ';' )
# sdl92.g:1150:25: ';'
# sdl92.g:1152:17: ( ';' )
# sdl92.g:1152:25: ';'
pass
self.match(59)
......@@ -623,8 +623,8 @@ class sdl92Lexer(Lexer):
_type = DASH
_channel = DEFAULT_CHANNEL
# sdl92.g:1151:17: ( '-' )
# sdl92.g:1151:25: '-'
# sdl92.g:1153:17: ( '-' )
# sdl92.g:1153:25: '-'
pass
self.match(45)
......@@ -648,8 +648,8 @@ class sdl92Lexer(Lexer):
_type = ANY
_channel = DEFAULT_CHANNEL
# sdl92.g:1152:17: ( A N Y )
# sdl92.g:1152:25: A N Y
# sdl92.g:1154:17: ( A N Y )
# sdl92.g:1154:25: A N Y
pass
self.mA()
self.mN()
......@@ -675,8 +675,8 @@ class sdl92Lexer(Lexer):
_type = ASTERISK
_channel = DEFAULT_CHANNEL
# sdl92.g:1153:17: ( '*' )
# sdl92.g:1153:25: '*'
# sdl92.g:1155:17: ( '*' )
# sdl92.g:1155:25: '*'
pass
self.match(42)
......@@ -700,8 +700,8 @@ class sdl92Lexer(Lexer):
_type = DCL
_channel = DEFAULT_CHANNEL
# sdl92.g:1154:17: ( D C L )
# sdl92.g:1154:25: D C L
# sdl92.g:1156:17: ( D C L )
# sdl92.g:1156:25: D C L
pass
self.mD()
self.mC()
......@@ -727,8 +727,8 @@ class sdl92Lexer(Lexer):
_type = END
_channel = DEFAULT_CHANNEL
# sdl92.g:1155:17: ( E N D )
# sdl92.g:1155:25: E N D
# sdl92.g:1157:17: ( E N D )
# sdl92.g:1157:25: E N D
pass
self.mE()
self.mN()
......@@ -754,8 +754,8 @@ class sdl92Lexer(Lexer):
_type = KEEP
_channel = DEFAULT_CHANNEL
# sdl92.g:1156:17: ( K E E P )
# sdl92.g:1156:25: K E E P
# sdl92.g:1158:17: ( K E E P )
# sdl92.g:1158:25: K E E P
pass
self.mK()
self.mE()
......@@ -782,8 +782,8 @@ class sdl92Lexer(Lexer):
_type = PARAMNAMES
_channel = DEFAULT_CHANNEL
# sdl92.g:1157:17: ( P A R A M N A M E S )
# sdl92.g:1157:25: P A R A M N A M E S
# sdl92.g:1159:17: ( P A R A M N A M E S )
# sdl92.g:1159:25: P A R A M N A M E S
pass
self.mP()
self.mA()
......@@ -816,8 +816,8 @@ class sdl92Lexer(Lexer):
_type = SPECIFIC
_channel = DEFAULT_CHANNEL
# sdl92.g:1158:17: ( S P E C I F I C )
# sdl92.g:1158:25: S P E C I F I C
# sdl92.g:1160:17: ( S P E C I F I C )
# sdl92.g:1160:25: S P E C I F I C
pass
self.mS()
self.mP()
......@@ -848,8 +848,8 @@ class sdl92Lexer(Lexer):
_type = GEODE
_channel = DEFAULT_CHANNEL
# sdl92.g:1159:17: ( G E O D E )
# sdl92.g:1159:25: G E O D E
# sdl92.g:1161:17: ( G E O D E )
# sdl92.g:1161:25: G E O D E
pass
self.mG()
self.mE()
......@@ -877,8 +877,8 @@ class sdl92Lexer(Lexer):
_type = HYPERLINK
_channel = DEFAULT_CHANNEL
# sdl92.g:1160:17: ( H Y P E R L I N K )
# sdl92.g:1160:25: H Y P E R L I N K
# sdl92.g:1162:17: ( H Y P E R L I N K )
# sdl92.g:1162:25: H Y P E R L I N K
pass
self.mH()
self.mY()
......@@ -910,8 +910,8 @@ class sdl92Lexer(Lexer):
_type = ENDTEXT
_channel = DEFAULT_CHANNEL
# sdl92.g:1161:17: ( E N D T E X T )
# sdl92.g:1161:25: E N D T E X T
# sdl92.g:1163:17: ( E N D T E X T )
# sdl92.g:1163:25: E N D T E X T
pass
self.mE()
self.mN()
......@@ -941,8 +941,8 @@ class sdl92Lexer(Lexer):
_type = RETURN
_channel = DEFAULT_CHANNEL
# sdl92.g:1162:17: ( R E T U R N )
# sdl92.g:1162:25: R E T U R N
# sdl92.g:1164:17: ( R E T U R N )
# sdl92.g:1164:25: R E T U R N
pass
self.mR()
self.mE()
......@@ -971,8 +971,8 @@ class sdl92Lexer(Lexer):
_type = TIMER
_channel = DEFAULT_CHANNEL
# sdl92.g:1163:17: ( T I M E R )
# sdl92.g:1163:25: T I M E R
# sdl92.g:1165:17: ( T I M E R )
# sdl92.g:1165:25: T I M E R
pass
self.mT()
self.mI()
......@@ -1000,8 +1000,8 @@ class sdl92Lexer(Lexer):
_type = PROCESS
_channel = DEFAULT_CHANNEL
# sdl92.g:1164:17: ( P R O C E S S )
# sdl92.g:1164:25: P R O C E S S
# sdl92.g:1166:17: ( P R O C E S S )
# sdl92.g:1166:25: P R O C E S S
pass
self.mP()
self.mR()
......@@ -1031,8 +1031,8 @@ class sdl92Lexer(Lexer):
_type = ENDPROCESS
_channel = DEFAULT_CHANNEL
# sdl92.g:1165:17: ( E N D P R O C E S S )
# sdl92.g:1165:25: E N D P R O C E S S
# sdl92.g:1167:17: ( E N D P R O C E S S )
# sdl92.g:1167:25: E N D P R O C E S S
pass
self.mE()
self.mN()
......@@ -1065,8 +1065,8 @@ class sdl92Lexer(Lexer):
_type = START
_channel = DEFAULT_CHANNEL
# sdl92.g:1166:17: ( S T A R T )
# sdl92.g:1166:25: S T A R T
# sdl92.g:1168:17: ( S T A R T )
# sdl92.g:1168:25: S T A R T
pass
self.mS()
self.mT()
......@@ -1094,8 +1094,8 @@ class sdl92Lexer(Lexer):
_type = STATE
_channel = DEFAULT_CHANNEL
# sdl92.g:1167:17: ( S T A T E )
# sdl92.g:1167:25: S T A T E
# sdl92.g:1169:17: ( S T A T E )
# sdl92.g:1169:25: S T A T E
pass
self.mS()
self.mT()
......@@ -1123,8 +1123,8 @@ class sdl92Lexer(Lexer):
_type = TEXT
_channel = DEFAULT_CHANNEL
# sdl92.g:1168:17: ( T E X T )
# sdl92.g:1168:25: T E X T
# sdl92.g:1170:17: ( T E X T )
# sdl92.g:1170:25: T E X T
pass
self.mT()
self.mE()
......@@ -1151,8 +1151,8 @@ class sdl92Lexer(Lexer):
_type = PROCEDURE
_channel = DEFAULT_CHANNEL
# sdl92.g:1169:17: ( P R O C E D U R E )
# sdl92.g:1169:25: P R O C E D U R E
# sdl92.g:1171:17: ( P R O C E D U R E )
# sdl92.g:1171:25: P R O C E D U R E
pass
self.mP()
self.mR()
......@@ -1184,8 +1184,8 @@ class sdl92Lexer(Lexer):
_type = ENDPROCEDURE
_channel = DEFAULT_CHANNEL
# sdl92.g:1170:17: ( E N D P R O C E D U R E )
# sdl92.g:1170:25: E N D P R O C E D U R E
# sdl92.g:1172:17: ( E N D P R O C E D U R E )
# sdl92.g:1172:25: E N D P R O C E D U R E
pass
self.mE()
self.mN()
......@@ -1220,8 +1220,8 @@ class sdl92Lexer(Lexer):
_type = PROCEDURE_CALL
_channel = DEFAULT_CHANNEL
# sdl92.g:1171:17: ( P R O C E D U R E C A L L )
# sdl92.g:1171:25: P R O C E D U R E C A L L
# sdl92.g:1173:17: ( P R O C E D U R E C A L L )
# sdl92.g:1173:25: P R O C E D U R E C A L L
pass
self.mP()
self.mR()
......@@ -1257,8 +1257,8 @@ class sdl92Lexer(Lexer):
_type = ENDSTATE
_channel = DEFAULT_CHANNEL
# sdl92.g:1172:17: ( E N D S T A T E )
# sdl92.g:1172:25: E N D S T A T E
# sdl92.g:1174:17: ( E N D S T A T E )
# sdl92.g:1174:25: E N D S T A T E
pass
self.mE()
self.mN()
......@@ -1289,8 +1289,8 @@ class sdl92Lexer(Lexer):
_type = INPUT
_channel = DEFAULT_CHANNEL
# sdl92.g:1173:17: ( I N P U T )
# sdl92.g:1173:25: I N P U T
# sdl92.g:1175:17: ( I N P U T )
# sdl92.g:1175:25: I N P U T
pass
self.mI()
self.mN()
......@@ -1318,8 +1318,8 @@ class sdl92Lexer(Lexer):
_type = PROVIDED
_channel = DEFAULT_CHANNEL
# sdl92.g:1174:17: ( P R O V I D E D )
# sdl92.g:1174:25: P R O V I D E D
# sdl92.g:1176:17: ( P R O V I D E D )
# sdl92.g:1176:25: P R O V I D E D
pass
self.mP()
self.mR()
......@@ -1350,8 +1350,8 @@ class sdl92Lexer(Lexer):
_type = PRIORITY
_channel = DEFAULT_CHANNEL
# sdl92.g:1175:17: ( P R I O R I T Y )
# sdl92.g:1175:25: P R I O R I T Y
# sdl92.g:1177:17: ( P R I O R I T Y )
# sdl92.g:1177:25: P R I O R I T Y
pass
self.mP()
self.mR()
......@@ -1382,8 +1382,8 @@ class sdl92Lexer(Lexer):
_type = SAVE
_channel = DEFAULT_CHANNEL
# sdl92.g:1176:17: ( S A V E )
# sdl92.g:1176:25: S A V E
# sdl92.g:1178:17: ( S A V E )
# sdl92.g:1178:25: S A V E
pass
self.mS()
self.mA()
......@@ -1410,8 +1410,8 @@ class sdl92Lexer(Lexer):
_type = NONE
_channel = DEFAULT_CHANNEL
# sdl92.g:1177:17: ( N O N E )
# sdl92.g:1177:25: N O N E
# sdl92.g:1179:17: ( N O N E )
# sdl92.g:1179:25: N O N E
pass
self.mN()
self.mO()
......@@ -1438,8 +1438,8 @@ class sdl92Lexer(Lexer):
_type = FOR
_channel = DEFAULT_CHANNEL
# sdl92.g:1184:17: ( F O R )
# sdl92.g:1184:25: F O R
# sdl92.g:1186:17: ( F O R )
# sdl92.g:1186:25: F O R
pass
self.mF()
self.mO()
......@@ -1465,8 +1465,8 @@ class sdl92Lexer(Lexer):
_type = ENDFOR
_channel = DEFAULT_CHANNEL
# sdl92.g:1185:17: ( E N D F O R )
# sdl92.g:1185:25: E N D F O R
# sdl92.g:1187:17: ( E N D F O R )
# sdl92.g:1187:25: E N D F O R
pass
self.mE()
self.mN()
......@@ -1495,8 +1495,8 @@ class sdl92Lexer(Lexer):
_type = RANGE
_channel = DEFAULT_CHANNEL
# sdl92.g:1186:17: ( R A N G E )
# sdl92.g:1186:25: R A N G E
# sdl92.g:1188:17: ( R A N G E )
# sdl92.g:1188:25: R A N G E
pass
self.mR()
self.mA()
......@@ -1524,8 +1524,8 @@ class sdl92Lexer(Lexer):
_type = NEXTSTATE
_channel = DEFAULT_CHANNEL
# sdl92.g:1187:17: ( N E X T S T A T E )
# sdl92.g:1187:25: N E X T S T A T E
# sdl92.g:1189:17: ( N E X T S T A T E )
# sdl92.g:1189:25: N E X T S T A T E
pass
self.mN()
self.mE()
......@@ -1557,8 +1557,8 @@ class sdl92Lexer(Lexer):
_type = ANSWER
_channel = DEFAULT_CHANNEL
# sdl92.g:1188:17: ( A N S W E R )
# sdl92.g:1188:25: A N S W E R
# sdl92.g:1190:17: ( A N S W E R )
# sdl92.g:1190:25: A N S W E R
pass
self.mA()
self.mN()
......@@ -1587,8 +1587,8 @@ class sdl92Lexer(Lexer):
_type = COMMENT
_channel = DEFAULT_CHANNEL
# sdl92.g:1189:17: ( C O M M E N T )
# sdl92.g:1189:25: C O M M E N T
# sdl92.g:1191:17: ( C O M M E N T )
# sdl92.g:1191:25: C O M M E N T
pass
self.mC()
self.mO()
......@@ -1618,8 +1618,8 @@ class sdl92Lexer(Lexer):
_type = LABEL
_channel = DEFAULT_CHANNEL
# sdl92.g:1190:17: ( L A B E L )
# sdl92.g:1190:25: L A B E L
# sdl92.g:1192:17: ( L A B E L )
# sdl92.g:1192:25: L A B E L
pass
self.mL()
self.mA()
......@@ -1647,8 +1647,8 @@ class sdl92Lexer(Lexer):
_type = STOP
_channel = DEFAULT_CHANNEL
# sdl92.g:1191:17: ( S T O P )
# sdl92.g:1191:25: S T O P
# sdl92.g:1193:17: ( S T O P )
# sdl92.g:1193:25: S T O P
pass
self.mS()
self.mT()
......@@ -1675,8 +1675,8 @@ class sdl92Lexer(Lexer):
_type = IF
_channel = DEFAULT_CHANNEL
# sdl92.g:1192:17: ( I F )
# sdl92.g:1192:25: I F
# sdl92.g:1194:17: ( I F )
# sdl92.g:1194:25: I F
pass
self.mI()
self.mF()
......@@ -1701,8 +1701,8 @@ class sdl92Lexer(Lexer):
_type = THEN
_channel = DEFAULT_CHANNEL
# sdl92.g:1193:17: ( T H E N )
# sdl92.g:1193:25: T H E N