+ # TODO Don't evaluate the middle expression twice
+ return CFunctionCallForFurInfixOperator(
+ name='and',
+ left=left,
+ right=CFunctionCallForFurInfixOperator(
+ name=INFIX_OPERATOR_TO_DECLARATION[expression.operator].name,
+ left=middle,
+ right=right,
+ ),
+ )
+
+ return CFunctionCallForFurInfixOperator(
+ name=INFIX_OPERATOR_TO_DECLARATION[expression.operator].name,
+ left=transform_expression(accumulators, expression.left),
+ right=transform_expression(accumulators, expression.right),
+ )
+
+def transform_infix_expression(accumulators, expression):
+ if expression.order == 'comparison_level':
+ return transform_comparison_level_expression(accumulators, expression)
+
+ accumulators.operator_set.add(INFIX_OPERATOR_TO_DECLARATION[expression.operator])
+
+ return CFunctionCallForFurInfixOperator(
+ name=INFIX_OPERATOR_TO_DECLARATION[expression.operator].name,
+ left=transform_expression(accumulators, expression.left),
+ right=transform_expression(accumulators, expression.right),
+ )
+
+def transform_integer_literal_expression(accumulators, expression):
+ return CIntegerLiteral(value=expression.integer)
+
+def transform_negation_expression(accumulators, expression):
+ return CNegationExpression(
+ value=transform_expression(accumulators, expression.internal_expression),
+ )
+
+def transform_expression(accumulators, expression):
+ # TODO Clean up handlers for parsing expressions
+ return {
+ parsing.FurInfixExpression: transform_infix_expression,
+ parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
+ parsing.FurNegationExpression: transform_negation_expression,
+ parsing.FurStringLiteralExpression: transform_string_literal_expression,
+ normalization.NormalFunctionCallExpression: transform_function_call_expression,
+ normalization.NormalInfixExpression: transform_infix_expression,
+ normalization.NormalIntegerLiteralExpression: transform_integer_literal_expression,
+ normalization.NormalNegationExpression: transform_negation_expression,
+ normalization.NormalStringLiteralExpression: transform_string_literal_expression,
+ normalization.NormalSymbolExpression: transform_symbol_expression,
+ normalization.NormalVariableExpression: transform_variable_expression,
+ }[type(expression)](accumulators, expression)
+
+def transform_symbol_assignment_statement(accumulators, assignment_statement):
+ # TODO Check that target is not a builtin
+ try:
+ symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
+ except ValueError:
+ symbol_list_index = len(accumulators.symbol_list)
+ accumulators.symbol_list.append(assignment_statement.target)
+
+ return CSymbolAssignmentStatement(
+ target=assignment_statement.target,
+ target_symbol_list_index=symbol_list_index,
+ expression=transform_expression(
+ accumulators,
+ assignment_statement.expression,
+ ),
+ )
+
+def transform_function_call_expression(accumulators, function_call):
+ # TODO Use the symbol from SYMBOL LIST
+ return CFunctionCallExpression(
+ function_expression=transform_expression(accumulators, function_call.function_expression),
+ argument_count=function_call.argument_count,
+ argument_items=transform_expression(accumulators, function_call.argument_items),
+ )