Pass arguments to infix operators via the stack
authorDavid Kerkeslager <kerkeslager@gmail.com>
Thu, 14 Sep 2017 23:43:23 +0000 (19:43 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Thu, 14 Sep 2017 23:43:23 +0000 (19:43 -0400)
generation.py
normalization.py
templates/program.c
transformation.py

index 145132f..d5d64ba 100644 (file)
@@ -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):
index 3b492a3..9da90d7 100644 (file)
@@ -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,
index 3602921..db1abdf 100644 (file)
@@ -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() }});
 
index 09a9b77..6a5354b 100644 (file)
@@ -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):