X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=normalization.py;h=f2b7b138a6a8dbe9db3ce5cad5e8c5b280b454cb;hp=2fa57fc5365cb3c864fde0f91d9536c1c848b750;hb=61733d6070859e6a639ae4b34faec9aacca52a29;hpb=8d6f07b43d8b41473fb7d8779bbc7a5843adcd7b diff --git a/normalization.py b/normalization.py index 2fa57fc..f2b7b13 100644 --- a/normalization.py +++ b/normalization.py @@ -49,10 +49,9 @@ NormalDotExpression = collections.namedtuple( NormalInfixExpression = collections.namedtuple( 'NormalInfixExpression', [ + 'metadata', 'order', 'operator', - 'left', - 'right', ], ) @@ -398,29 +397,18 @@ def normalize_basic_infix_operation(counter, expression): counter, left_prestatements, left_expression = normalize_expression(counter, expression.left) counter, right_prestatements, right_expression = normalize_expression(counter, expression.right) - left_variable = '${}'.format(counter) - counter += 1 - right_variable = '${}'.format(counter) - counter += 1 center_variable = '${}'.format(counter) counter += 1 root_prestatements = ( - NormalVariableInitializationStatement( - variable=left_variable, - expression=left_expression, - ), - NormalVariableInitializationStatement( - variable=right_variable, - expression=right_expression, - ), + NormalPushStatement(expression=left_expression), + NormalPushStatement(expression=right_expression), NormalVariableInitializationStatement( variable=center_variable, expression=NormalInfixExpression( + metadata=expression.metadata, order=expression.order, operator=expression.operator, - left=NormalVariableExpression(variable=left_variable), - right=NormalVariableExpression(variable=right_variable), ), ), ) @@ -431,67 +419,61 @@ def normalize_basic_infix_operation(counter, expression): NormalVariableExpression(variable=center_variable), ) -def normalize_comparison_expression(counter, expression): - stack = [] - - while isinstance(expression.left, parsing.FurInfixExpression) and expression.order == 'comparison_level': - stack.append((expression.operator, expression.order, expression.right)) - expression = expression.left - - counter, left_prestatements, left_expression = normalize_expression(counter, expression.left) - counter, right_prestatements, right_expression = normalize_expression(counter, expression.right) +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 - right_variable = '${}'.format(counter) + middle_variable = '${}'.format(counter) counter += 1 - root_prestatements = ( + # TODO Is there a memory leak if the middle expression throws an exception because the first expression result hasn't been added to the stack? + juncture_prestatements = ( NormalVariableInitializationStatement( variable=left_variable, expression=left_expression, ), NormalVariableInitializationStatement( - variable=right_variable, - expression=right_expression, - ), + variable=middle_variable, + expression=middle_expression, + ) ) - counter, result_prestatements, result_expression = ( + counter, boolean_expression_prestatements, boolean_expression = normalize_boolean_expression( counter, - left_prestatements + right_prestatements + root_prestatements, - NormalInfixExpression( - order=expression.order, - operator=expression.operator, - left=NormalVariableExpression(variable=left_variable), - right=NormalVariableExpression(variable=right_variable), - ), - ) - - 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', + parsing.FurInfixExpression( + metadata=expression.left.metadata, order='and_level', - left=result_expression, - right=and_right_expression, + operator='and', + left=parsing.FurInfixExpression( + metadata=expression.left.metadata, + order='comparison_level', + operator=expression.left.operator, + left=NormalVariableExpression(variable=left_variable), + right=NormalVariableExpression(variable=middle_variable), + ), + right=parsing.FurInfixExpression( + metadata=expression.metadata, + order='comparison_level', + operator=expression.operator, + left=NormalVariableExpression(variable=middle_variable), + right=expression.right, + ), ) + ) - counter, and_prestatements, result_expression = normalize_boolean_expression( - counter, - and_expression, - ) + return ( + counter, + left_prestatements + middle_prestatements + juncture_prestatements + boolean_expression_prestatements, + boolean_expression, + ) - result_prestatements = result_prestatements + and_prestatements +def normalize_comparison_expression(counter, expression): + if isinstance(expression.left, parsing.FurInfixExpression) and expression.order == 'comparison_level': + return desugar_ternary_comparison(counter, expression) - return (counter, result_prestatements, result_expression) + return normalize_basic_infix_operation(counter, expression) def normalize_boolean_expression(counter, expression): counter, left_prestatements, left_expression = normalize_expression(counter, expression.left)