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): ...@@ -866,51 +866,11 @@ 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 binary expressions ''' ''' Check/ensure type consistency in binary expressions '''
if isinstance(expr, ogAST.Primary): if isinstance(expr, ogAST.Primary):
return 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 # 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 # the other side is a literal of that sort, and change type accordingly
for side in permutations(('left', 'right')): for side in permutations(('left', 'right')):
...@@ -1074,9 +1034,6 @@ def primary_path(root, context=None): ...@@ -1074,9 +1034,6 @@ def primary_path(root, context=None):
prim.inputString = get_input_string(root) prim.inputString = get_input_string(root)
prim.tmpVar = tmp() prim.tmpVar = tmp()
if len(root.children) == 1:
return prim, errors, warnings
proc_list = [proc.inputString.lower() for proc in context.procedures] proc_list = [proc.inputString.lower() for proc in context.procedures]
call = prim.value[0].lower() in (SPECIAL_OPERATORS.keys() + proc_list) call = prim.value[0].lower() in (SPECIAL_OPERATORS.keys() + proc_list)
...@@ -1126,6 +1083,32 @@ def primary_path(root, context=None): ...@@ -1126,6 +1083,32 @@ def primary_path(root, context=None):
return prim, errors, warnings 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(): def tmp():
''' Return a temporary variable name ''' ''' Return a temporary variable name '''
global TMPVAR global TMPVAR
...@@ -1379,8 +1362,6 @@ def not_expression(root, context): ...@@ -1379,8 +1362,6 @@ def not_expression(root, context):
''' Not expression analysis ''' ''' Not expression analysis '''
expr, errors, warnings = unary_expression(root, context) expr, errors, warnings = unary_expression(root, context)
fix_expression_type(expr, context)
bty = find_basic_type(expr.expr.exprType) bty = find_basic_type(expr.expr.exprType)
if bty.kind in ('BooleanType', ): if bty.kind in ('BooleanType', ):
expr.exprType = BOOLEAN expr.exprType = BOOLEAN
...@@ -1399,8 +1380,6 @@ def neg_expression(root, context): ...@@ -1399,8 +1380,6 @@ def neg_expression(root, context):
''' Negative expression analysis ''' ''' Negative expression analysis '''
expr, errors, warnings = unary_expression(root, context) expr, errors, warnings = unary_expression(root, context)
fix_expression_type(expr, context)
basic = find_basic_type(expr.expr.exprType) basic = find_basic_type(expr.expr.exprType)
if not basic.kind in ('IntegerType', 'Integer32Type', 'RealType'): if not basic.kind in ('IntegerType', 'Integer32Type', 'RealType'):
msg = 'Negative expressions can only be applied to numeric types' msg = 'Negative expressions can only be applied to numeric types'
...@@ -1450,7 +1429,9 @@ def primary(root, context): ...@@ -1450,7 +1429,9 @@ def primary(root, context):
''' Literal expression analysis ''' ''' Literal expression analysis '''
prim, errors, warnings = None, [], [] 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) return primary_path(root, context)
elif root.type == lexer.INT: elif root.type == lexer.INT:
prim = ogAST.PrimInteger() prim = ogAST.PrimInteger()
...@@ -3057,21 +3038,18 @@ def assign(root, context): ...@@ -3057,21 +3038,18 @@ def assign(root, context):
get_input_string(root), root.getLine(), get_input_string(root), root.getLine(),
root.getCharPositionInLine()) root.getCharPositionInLine())
expr.kind = 'assign' expr.kind = 'assign'
for child in root.getChildren():
if child.type == lexer.VARIABLE: if root.children[0].type == lexer.PATH:
# Left part of the assignation expr.left, err, warn = primary_path(root.children[0], context)
prim, err, warn = primary_path(child, context) else:
prim.inputString = get_input_string(child) expr.left, err, warn = primary_variable(root.children[0], context)
prim.line = child.getLine() warnings.extend(warn)
prim.charPositionInLine = child.getCharPositionInLine() errors.extend(err)
warnings.extend(warn)
errors.extend(err) expr.right, err, warn = expression(root.children[1], context)
expr.left = prim errors.extend(err)
else: warnings.extend(warn)
# Right part of the assignation
expr.right, err, warn = expression(child, context)
errors.extend(err)
warnings.extend(warn)
try: try:
fix_expression_types(expr, context) fix_expression_types(expr, context)
except(AttributeError, TypeError) as err: except(AttributeError, TypeError) as err:
...@@ -3130,6 +3108,11 @@ def for_loop(root, context): ...@@ -3130,6 +3108,11 @@ def for_loop(root, context):
# Implicit variable declaration for the iterator # Implicit variable declaration for the iterator
context_scope = dict(context.variables) context_scope = dict(context.variables)
elif child.type == lexer.VARIABLE: 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) list_var, err, warn = primary_path(child, context)
forloop['list'] = ogAST.PrimVariable(primary=list_var) forloop['list'] = ogAST.PrimVariable(primary=list_var)
warnings.extend(warn) warnings.extend(warn)
......
...@@ -791,8 +791,9 @@ assignement_statement ...@@ -791,8 +791,9 @@ assignement_statement
// Variable: covers eg. toto(5)(4)!titi(3)!tutu!yoyo // Variable: covers eg. toto(5)(4)!titi(3)!tutu!yoyo
variable variable
: variable_id primary_params* : ID primary_params+ -> ^(PATH ID primary_params+)
-> ^(VARIABLE variable_id primary_params*); | ID -> ^(VARIABLE ID);
field_selection field_selection
: (('!'|'.') field_name); : (('!'|'.') field_name);
...@@ -836,7 +837,8 @@ primary ...@@ -836,7 +837,8 @@ primary
| INT^ | INT^
| FLOAT^ | FLOAT^
| ID ':' expression -> ^(CHOICE ID expression) | ID ':' expression -> ^(CHOICE ID expression)
| ID primary_params* -> ^(PATH ID primary_params*) | ID primary_params+ -> ^(PATH ID primary_params+)
| ID -> ^(VARIABLE ID)
| '{' '}' -> ^(EMPTYSTR) | '{' '}' -> ^(EMPTYSTR)
| '{' | '{'
MANTISSA mant=INT COMMA MANTISSA mant=INT COMMA
......
This diff is collapsed.
This diff is collapsed.
Supports Markdown
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