Commit a988169c authored by dbarbera's avatar dbarbera
Browse files

Fix type analysis in conditional expressions

parent b42747b6
......@@ -392,11 +392,7 @@ def fix_special_operators(op_name, expr_list, context):
for each in (INTEGER, REAL, BOOLEAN, RAWSTRING, OCTETSTRING):
try:
check_type_compatibility(param, each, context)
if each is OCTETSTRING and isinstance(param,
ogAST.PrimIfThenElse):
param.exprType = param.value['then'].exprType
else:
param.exprType = each
param.exprType = each
break
except TypeError:
continue
......@@ -549,29 +545,8 @@ def check_type_compatibility(primary, typeRef, context):
'" not in this enumeration: ' +
str(actual_type.EnumValues.keys()))
raise TypeError(err)
elif isinstance(primary, ogAST.PrimIfThenElse):
# check that IF expr returns BOOL, and that Then and Else expressions
# are compatible with actual_type
if_expr = primary.value['if']
then_expr = primary.value['then']
else_expr = primary.value['else']
if if_expr.exprType.kind != 'BooleanType':
raise TypeError('IF expression does not return a boolean')
else:
for expr in (then_expr, else_expr):
if expr.is_raw:
check_type_compatibility(expr, typeRef, context)
# compare the types for semantic equivalence:
else:
if expr.exprType is UNKNOWN_TYPE:
# If it was not resolved before, it must be a variable
# this can happen in the context of a special operator
# (write), where at no point before where the type
# could be compared to another type
expr.exprType = find_variable(expr.value[0], context)
compare_types(expr.exprType, typeRef)
return
elif isinstance(primary, ogAST.PrimVariable):
elif isinstance(primary, ogAST.PrimIfThenElse) \
or isinstance(primary, ogAST.PrimVariable):
try:
compare_types(primary.exprType, typeRef)
except TypeError as err:
......@@ -869,7 +844,7 @@ def fix_expression_types(expr, context):
raise TypeError('Cannot resolve type of "{}"'
.format(unknown[0].inputString))
# In Sequence, Choice, SEQUENCE OF, and IfThenElse expressions,
# In Sequence, Choice and SEQUENCE OF expressions,
# we must fix missing inner types
# (due to similarities, the following should be refactored FIXME)
if isinstance(expr.right, ogAST.PrimSequence):
......@@ -911,15 +886,6 @@ def fix_expression_types(expr, context):
check_expr.right = expr.right.value['value']
fix_expression_types(check_expr, context)
expr.right.value['value'] = check_expr.right
elif isinstance(expr.right, ogAST.PrimIfThenElse):
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.exprType = expr.left.exprType
check_expr.right = expr.right.value[det]
fix_expression_types(check_expr, context)
expr.right.value[det] = check_expr.right
if expr.right.is_raw != expr.left.is_raw:
check_type_compatibility(raw_expr, ref_type, context)
......@@ -1039,7 +1005,7 @@ def expression(root, context):
elif root.type == lexer.PAREN:
return expression(root.children[0], context)
elif root.type == lexer.IFTHENELSE:
return if_then_else_expression(root, context)
return conditional_expression(root, context)
elif root.type == lexer.PRIMARY:
return primary(root.children[0], context)
elif root.type == lexer.CALL:
......@@ -1258,8 +1224,8 @@ def neg_expression(root, context):
return expr, errors, warnings
def if_then_else_expression(root, context):
''' If Then Else expression analysis '''
def conditional_expression(root, context):
''' Conditional expression analysis '''
errors, warnings = [], []
expr = ogAST.PrimIfThenElse(
......@@ -1284,7 +1250,20 @@ def if_then_else_expression(root, context):
errors.extend(err)
warnings.extend(warn)
if find_basic_type(if_expr.exprType).kind != 'BooleanType':
msg = 'Conditions in conditional expressions must be of type Boolean'
errors.append(error(root, msg))
# TODO: Refactor this
check_expr = ogAST.ExprEq()
check_expr.left = then_expr
check_expr.right = else_expr
try:
fix_expression_types(check_expr, context)
expr.exprType = check_expr.left.exprType
except (AttributeError, TypeError) as err:
errors.append(error(root, str(err)))
expr.value = {
'if': if_expr,
'then': then_expr,
......
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