Normalize function expressions
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 13 Aug 2017 19:45:45 +0000 (15:45 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 13 Aug 2017 19:45:45 +0000 (15:45 -0400)
generation.py
normalization.py
transformation.py

index 1694e1f..55b3ade 100644 (file)
@@ -56,13 +56,14 @@ def generate_negation_expression(c_negation_expression):
     )
 
 def generate_function_call(function_call):
-    # TODO This gets called twice, which is really inefficient--normalization would also allow other clauses besides a variable reference
-    # TODO This should no longer be called "name", as it can be an expression of a few types
+    # This gets called twice, so we want to be sure it is efficient and without side effects
+    assert isinstance(function_call.function_expression, transformation.CVariableExpression)
+
     # TODO Check the type of the things being called
-    get_closure_clause = generate_expression(function_call.name)
+    function_expression = generate_variable_expression(function_call.function_expression)
     return '{}.instance.closure.call(environmentPool, {}.instance.closure.closed, {}, {})'.format(
-        get_closure_clause,
-        get_closure_clause,
+        function_expression,
+        function_expression,
         function_call.argument_count,
         # TODO This is just a single item containing a reference to the items list--make that clearer
         generate_expression(function_call.argument_items),
index 4a16a3d..9d25ba2 100644 (file)
@@ -51,7 +51,7 @@ NormalInfixExpression = collections.namedtuple(
 NormalFunctionCallExpression = collections.namedtuple(
     'NormalFunctionCallExpression',
     [
-        'function',
+        'function_expression',
         'argument_count',
         'argument_items',
     ],
@@ -189,11 +189,22 @@ def normalize_function_call_expression(counter, expression):
     for ps in function_prestatements:
         prestatements.append(ps)
 
+    if not isinstance(function_expression, NormalVariableExpression):
+        function_variable = '${}'.format(counter)
+
+        prestatements.append(NormalVariableInitializationStatement(
+            variable=function_variable,
+            expression=function_expression,
+        ))
+
+        function_expression = NormalVariableExpression(variable=function_variable)
+        counter += 1
+
     return (
         counter,
         tuple(prestatements),
         NormalFunctionCallExpression(
-            function=function_expression,
+            function_expression=function_expression,
             argument_count=len(arguments),
             argument_items=NormalVariableExpression(variable=arguments_variable),
         ),
index 2661cef..ba10109 100644 (file)
@@ -52,7 +52,7 @@ CFunctionCallForFurInfixOperator = collections.namedtuple(
 CFunctionCallExpression = collections.namedtuple(
     'CFunctionCallExpression',
     [
-        'name',
+        'function_expression',
         'argument_count',
         'argument_items',
     ],
@@ -258,7 +258,6 @@ def transform_negation_expression(accumulators, expression):
 def transform_expression(accumulators, expression):
     # TODO Clean up handlers for parsing expressions
     return {
-        parsing.FurFunctionCallExpression: transform_function_call_expression,
         parsing.FurInfixExpression: transform_infix_expression,
         parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
         parsing.FurNegationExpression: transform_negation_expression,
@@ -292,7 +291,7 @@ def transform_symbol_assignment_statement(accumulators, assignment_statement):
 def transform_function_call_expression(accumulators, function_call):
     # TODO Use the symbol from SYMBOL LIST
     return CFunctionCallExpression(
-        name=transform_expression(accumulators, function_call.function),
+        function_expression=transform_expression(accumulators, function_call.function_expression),
         argument_count=function_call.argument_count,
         argument_items=transform_expression(accumulators, function_call.argument_items),
     )