From: David Kerkeslager Date: Thu, 14 Sep 2017 23:43:23 +0000 (-0400) Subject: Pass arguments to infix operators via the stack X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=728158b2204b6454eecc12bf2988b3f0cbb9ec81;p=fur Pass arguments to infix operators via the stack --- diff --git a/generation.py b/generation.py index 145132f..d5d64ba 100644 --- a/generation.py +++ b/generation.py @@ -27,10 +27,8 @@ def generate_variable_expression(expression): return expression.variable def generate_function_call_for_fur_infix_operator(expression): - return 'operator${}({}, {})'.format( + return 'operator${}(stack)'.format( expression.name, - generate_expression(expression.left), - generate_expression(expression.right), ) def generate_structure_literal_expression(expression): diff --git a/normalization.py b/normalization.py index 3b492a3..9da90d7 100644 --- a/normalization.py +++ b/normalization.py @@ -51,8 +51,6 @@ NormalInfixExpression = collections.namedtuple( [ 'order', 'operator', - 'left', - 'right', ], ) @@ -398,29 +396,17 @@ 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( order=expression.order, operator=expression.operator, - left=NormalVariableExpression(variable=left_variable), - right=NormalVariableExpression(variable=right_variable), ), ), ) @@ -440,6 +426,7 @@ def desugar_ternary_comparison(counter, expression): middle_variable = '${}'.format(counter) counter += 1 + # 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, diff --git a/templates/program.c b/templates/program.c index 3602921..db1abdf 100644 --- a/templates/program.c +++ b/templates/program.c @@ -544,8 +544,11 @@ Object operator$negate(Object input) } // TODO Make this conditionally added -Object operator$concatenate(Object left, Object right) +Object operator$concatenate(Stack* stack) { + Object right = Stack_pop(stack); + Object left = Stack_pop(stack); + switch(left.type) { case STRING_CONCATENATION: case STRING_LITERAL: @@ -574,8 +577,11 @@ Object operator$concatenate(Object left, Object right) } {% for id in infix_declarations %} -Object operator${{ id.name }}(Object left, Object right) +Object operator${{ id.name }}(Stack* stack) { + Object right = Stack_pop(stack); + Object left = Stack_pop(stack); + assert(left.type == {{ id.in_type.upper() }}); assert(right.type == {{ id.in_type.upper() }}); diff --git a/transformation.py b/transformation.py index 09a9b77..6a5354b 100644 --- a/transformation.py +++ b/transformation.py @@ -62,8 +62,6 @@ CFunctionCallForFurInfixOperator = collections.namedtuple( 'CFunctionCallForFurInfixOperator', [ 'name', - 'left', - 'right', ], ) @@ -240,34 +238,19 @@ FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = { '>': CInfixDeclaration(name='greaterThan', in_type='integer', out_type='boolean', operator='>'), } -def transform_comparison_level_expression(accumulators, expression): - accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator]) - - return CFunctionCallForFurInfixOperator( - name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name, - left=transform_expression(accumulators, expression.left), - right=transform_expression(accumulators, expression.right), - ) - def transform_infix_operator_without_c_equivalent(accumulators, expression): return CFunctionCallForFurInfixOperator( name='concatenate', - left=transform_expression(accumulators, expression.left), - right=transform_expression(accumulators, expression.right), ) + def transform_infix_expression(accumulators, expression): if expression.operator in FUR_INFIX_OPERATOR_TO_C_FUNCTION: return transform_infix_operator_without_c_equivalent(accumulators, expression) - if expression.order == 'comparison_level': - return transform_comparison_level_expression(accumulators, expression) - accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator]) return CFunctionCallForFurInfixOperator( name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name, - left=transform_expression(accumulators, expression.left), - right=transform_expression(accumulators, expression.right), ) def transform_integer_literal_expression(accumulators, expression):