From: David Kerkeslager Date: Sun, 13 Aug 2017 19:45:45 +0000 (-0400) Subject: Normalize function expressions X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=dad13948cf5519f1a6e843235c046da7024f4e05;p=fur Normalize function expressions --- diff --git a/generation.py b/generation.py index 1694e1f..55b3ade 100644 --- a/generation.py +++ b/generation.py @@ -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), diff --git a/normalization.py b/normalization.py index 4a16a3d..9d25ba2 100644 --- a/normalization.py +++ b/normalization.py @@ -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), ), diff --git a/transformation.py b/transformation.py index 2661cef..ba10109 100644 --- a/transformation.py +++ b/transformation.py @@ -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), )