]> code.kerkeslager.com Git - fur/commitdiff
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 1694e1fee2839824cef3de2b627481ed6eae0ead..55b3ade9f8694ca617c9e64119c77e6565d96318 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 4a16a3dcefbf364f9107281708058316f12d1503..9d25ba251802ac3e566e52e93f78241b0eb9bd69 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 2661cef0b1328909e9965f875b67f666876613df..ba10109457fd035176a43676b830e6c1f380dc10 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),
     )