From 3769b766b898b95fd699e3cb6d005576a4c22086 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Thu, 14 Sep 2017 19:06:05 -0400 Subject: [PATCH] Move desugaring ternary comparison operators into the normalization step --- normalization.py | 76 ++++++++++++++++++++++++++++++----------------- transformation.py | 25 ---------------- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/normalization.py b/normalization.py index 2fa57fc..5b5bd94 100644 --- a/normalization.py +++ b/normalization.py @@ -431,12 +431,55 @@ def normalize_basic_infix_operation(counter, expression): NormalVariableExpression(variable=center_variable), ) -def normalize_comparison_expression(counter, expression): - stack = [] +def desugar_ternary_comparison(counter, expression): + counter, left_prestatements, left_expression = normalize_expression(counter, expression.left.left) + counter, middle_prestatements, middle_expression = normalize_expression(counter, expression.left.right) + + left_variable = '${}'.format(counter) + counter += 1 + middle_variable = '${}'.format(counter) + counter += 1 + + juncture_prestatements = ( + NormalVariableInitializationStatement( + variable=left_variable, + expression=left_expression, + ), + NormalVariableInitializationStatement( + variable=middle_variable, + expression=middle_expression, + ) + ) + + counter, boolean_expression_prestatements, boolean_expression = normalize_boolean_expression( + counter, + parsing.FurInfixExpression( + order='and_level', + operator='and', + left=parsing.FurInfixExpression( + order='comparison_level', + operator=expression.left.operator, + left=NormalVariableExpression(variable=left_variable), + right=NormalVariableExpression(variable=middle_variable), + ), + right=parsing.FurInfixExpression( + order='comparison_level', + operator=expression.operator, + left=NormalVariableExpression(variable=middle_variable), + right=expression.right, + ), + ) + ) + + return ( + counter, + left_prestatements + middle_prestatements + juncture_prestatements + boolean_expression_prestatements, + boolean_expression, + ) - while isinstance(expression.left, parsing.FurInfixExpression) and expression.order == 'comparison_level': - stack.append((expression.operator, expression.order, expression.right)) - expression = expression.left +def normalize_comparison_expression(counter, expression): + if isinstance(expression.left, parsing.FurInfixExpression) and expression.order == 'comparison_level': + return desugar_ternary_comparison(counter, expression) counter, left_prestatements, left_expression = normalize_expression(counter, expression.left) counter, right_prestatements, right_expression = normalize_expression(counter, expression.right) @@ -468,29 +511,6 @@ def normalize_comparison_expression(counter, expression): ), ) - while len(stack) > 0: - right_operator, right_order, right_expression = stack.pop() - and_right_expression = parsing.FurInfixExpression( - operator=right_operator, - order=right_order, - left=NormalVariableExpression(variable=right_variable), - right=right_expression, - ) - - and_expression = parsing.FurInfixExpression( - operator='and', - order='and_level', - left=result_expression, - right=and_right_expression, - ) - - counter, and_prestatements, result_expression = normalize_boolean_expression( - counter, - and_expression, - ) - - result_prestatements = result_prestatements + and_prestatements - return (counter, result_prestatements, result_expression) def normalize_boolean_expression(counter, expression): diff --git a/transformation.py b/transformation.py index 82d4b3f..09a9b77 100644 --- a/transformation.py +++ b/transformation.py @@ -243,31 +243,6 @@ FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = { def transform_comparison_level_expression(accumulators, expression): accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator]) - # Transform expressions like 1 < 2 < 3 into expressions like 1 < 2 && 2 < 3 - if isinstance(expression.left, parsing.FurInfixExpression) and expression.left.order == 'comparison_level': - left = transform_comparison_level_expression( - accumulators, - expression.left - ) - - middle = left.right - - right = transform_expression( - accumulators, - expression.right, - ) - - # TODO Don't evaluate the middle expression twice - return CFunctionCallForFurInfixOperator( - name='and', - left=left, - right=CFunctionCallForFurInfixOperator( - name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name, - left=middle, - right=right, - ), - ) - return CFunctionCallForFurInfixOperator( name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name, left=transform_expression(accumulators, expression.left), -- 2.20.1