From: David Kerkeslager Date: Sat, 6 Jan 2018 19:50:54 +0000 (-0500) Subject: Desugar function definitions to assignments to lambda X-Git-Url: https://code.kerkeslager.com/?p=fur;a=commitdiff_plain;h=4d6f362ca35cd00803b1a79e03985301bcfbeea8 Desugar function definitions to assignments to lambda --- diff --git a/conversion.py b/conversion.py index fd469fa..49e27fd 100644 --- a/conversion.py +++ b/conversion.py @@ -21,6 +21,7 @@ CPSIntegerLiteralExpression = collections.namedtuple( CPSLambdaExpression = collections.namedtuple( 'CPSLambdaExpression', ( + 'name', 'argument_name_list', 'statement_list', ), @@ -86,15 +87,6 @@ CPSExpressionStatement = collections.namedtuple( ), ) -CPSFunctionDefinitionStatement = collections.namedtuple( - 'CPSFunctionDefinitionStatement', - ( - 'name', - 'argument_name_list', - 'statement_list', - ) -) - CPSIfElseStatement = collections.namedtuple( 'CPSIfElseStatement', ( @@ -162,6 +154,7 @@ def convert_integer_literal_expression(expression): def convert_lambda_expression(expression): return CPSLambdaExpression( + name=expression.name, argument_name_list=expression.argument_name_list, statement_list=tuple(convert_statement(s) for s in expression.statement_list), ) @@ -214,13 +207,6 @@ def convert_expression_statement(statement): expression=convert_expression(statement.expression), ) -def convert_function_definition_statement(statement): - return CPSFunctionDefinitionStatement( - name=statement.name, - argument_name_list=statement.argument_name_list, - statement_list=tuple(convert_statement(s) for s in statement.statement_list), - ) - def convert_if_else_statement(statement): return CPSIfElseStatement( condition_expression=convert_expression(statement.condition_expression), @@ -263,7 +249,6 @@ def convert_statement(statement): normalization.NormalArrayVariableInitializationStatement: convert_array_variable_initialization_statement, normalization.NormalAssignmentStatement: convert_assignment_statement, normalization.NormalExpressionStatement: convert_expression_statement, - normalization.NormalFunctionDefinitionStatement: convert_function_definition_statement, normalization.NormalIfElseStatement: convert_if_else_statement, normalization.NormalListAppendStatement: convert_list_append_statement, normalization.NormalPushStatement: convert_push_statement, diff --git a/desugaring.py b/desugaring.py index c951fd5..47dfe6f 100644 --- a/desugaring.py +++ b/desugaring.py @@ -27,14 +27,22 @@ DesugaredIntegerLiteralExpression = collections.namedtuple( ), ) -DesugaredLambdaExpression = collections.namedtuple( +_DesugaredLambdaExpression = collections.namedtuple( 'DesugaredLambdaExpression', ( + 'name', 'argument_name_list', 'statement_list', ), ) +class DesugaredLambdaExpression(_DesugaredLambdaExpression): + def __new__(cls, *args, **kwargs): + if 'name' not in kwargs: + kwargs['name'] = None + + return super(DesugaredLambdaExpression, cls).__new__(cls, *args, **kwargs) + DesugaredListLiteralExpression = collections.namedtuple( 'DesugaredListLiteralExpression', ( @@ -87,15 +95,6 @@ DesugaredExpressionStatement = collections.namedtuple( ), ) -DesugaredFunctionDefinitionStatement = collections.namedtuple( - 'DesugaredFunctionDefinitionStatement', - ( - 'name', - 'argument_name_list', - 'statement_list', - ), -) - DesugaredProgram = collections.namedtuple( 'DesugaredProgram', ( @@ -279,10 +278,13 @@ def desugar_expression_statement(statement): ) def desugar_function_definition_statement(statement): - return DesugaredFunctionDefinitionStatement( - name=statement.name, - argument_name_list=statement.argument_name_list, - statement_list=tuple(desugar_statement(s) for s in statement.statement_list), + return DesugaredAssignmentStatement( + target=statement.name, + expression=DesugaredLambdaExpression( + name=statement.name, + argument_name_list=statement.argument_name_list, + statement_list=tuple(desugar_statement(s) for s in statement.statement_list), + ), ) def desugar_statement(statement): diff --git a/generation.py b/generation.py index 6c1cf0b..74a3fa5 100644 --- a/generation.py +++ b/generation.py @@ -139,12 +139,6 @@ def generate_if_else_statement(statement): return generated_if_clause + generated_if_statement_list + generated_else_statement_list -def generate_function_declaration(statement): - return 'Environment_set(environment, "{}", (Object){{ CLOSURE, (Instance)(Closure){{ environment, user${}$implementation }} }});'.format( - statement.name, - statement.name, - ) - def generate_list_append_statement(statement): return 'List_append(&{}, {});'.format( generate_expression(statement.list_expression), @@ -158,7 +152,6 @@ def generate_statement(statement): return { transformation.CArrayVariableInitializationStatement: generate_array_variable_initialization_statement, transformation.CExpressionStatement: generate_expression_statement, - transformation.CFunctionDeclaration: generate_function_declaration, transformation.CIfElseStatement: generate_if_else_statement, transformation.CListAppendStatement: generate_list_append_statement, transformation.CPushStatement: generate_push_statement, diff --git a/normalization.py b/normalization.py index 9725b5b..f6c4246 100644 --- a/normalization.py +++ b/normalization.py @@ -20,6 +20,7 @@ NormalIntegerLiteralExpression = collections.namedtuple( NormalLambdaExpression = collections.namedtuple( 'NormalLambdaExpression', ( + 'name', 'argument_name_list', 'statement_list', ), @@ -111,15 +112,6 @@ NormalIfElseStatement = collections.namedtuple( ], ) -NormalFunctionDefinitionStatement = collections.namedtuple( - 'NormalFunctionDefinitionStatement', - [ - 'name', - 'argument_name_list', - 'statement_list', - ], -) - NormalProgram = collections.namedtuple( 'NormalProgram', [ @@ -155,6 +147,7 @@ def normalize_lambda_expression(counter, expression): NormalVariableInitializationStatement( variable=variable, expression=NormalLambdaExpression( + name=expression.name, argument_name_list=expression.argument_name_list, statement_list=statement_list, ), @@ -431,22 +424,6 @@ def normalize_expression_statement(counter, statement): NormalExpressionStatement(expression=normalized), ) -def normalize_function_definition_statement(counter, statement): - _, statement_list = normalize_statement_list( - 0, - statement.statement_list, - assign_result_to='result', - ) - return ( - counter, - (), - NormalFunctionDefinitionStatement( - name=statement.name, - argument_name_list=statement.argument_name_list, - statement_list=statement_list, - ), - ) - def normalize_assignment_statement(counter, statement): counter, prestatements, normalized_expression = normalize_expression(counter, statement.expression) return ( @@ -462,7 +439,6 @@ def normalize_statement(counter, statement): return { desugaring.DesugaredAssignmentStatement: normalize_assignment_statement, desugaring.DesugaredExpressionStatement: normalize_expression_statement, - desugaring.DesugaredFunctionDefinitionStatement: normalize_function_definition_statement, }[type(statement)](counter, statement) @util.force_generator(tuple) diff --git a/transformation.py b/transformation.py index e8ee51c..6f46d43 100644 --- a/transformation.py +++ b/transformation.py @@ -116,13 +116,6 @@ CIfElseStatement = collections.namedtuple( ], ) -CFunctionDeclaration = collections.namedtuple( - 'CFunctionDeclaration', - [ - 'name', - ], -) - # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement. # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective. CFunctionDefinition = collections.namedtuple( @@ -224,7 +217,10 @@ def transform_lambda_expression(accumulators, expression): else: accumulators.lambda_number_list.append(accumulators.lambda_number_list[-1] + 1) - name = '__lambda_{}'.format(accumulators.lambda_number_list[-1]) + if expression.name is None: + name = '__lambda_{}'.format(accumulators.lambda_number_list[-1]) + else: + name = expression.name accumulators.function_definition_list.append(CFunctionDefinition( name=name, @@ -329,20 +325,6 @@ def transform_variable_reassignment_statement(accumulators, statement): expression=transform_expression(accumulators, statement.expression), ) -def transform_function_definition_statement(accumulators, statement): - # TODO Allow defining the same function in different contexts - if any(fd.name == statement.name for fd in accumulators.function_definition_list): - raise Exception('A function with name "{}" already exists'.format(statement.name)) - - # TODO Add argument names to the symbol table - accumulators.function_definition_list.append(CFunctionDefinition( - name=statement.name, - argument_name_list=statement.argument_name_list, - statement_list=tuple(transform_statement(accumulators, s) for s in statement.statement_list) - )) - - return CFunctionDeclaration(name=statement.name) - def transform_push_statement(accumulators, statement): return CPushStatement(expression=transform_expression(accumulators, statement.expression)) @@ -351,7 +333,6 @@ def transform_statement(accumulators, statement): conversion.CPSArrayVariableInitializationStatement: transform_array_variable_initialization_statement, conversion.CPSAssignmentStatement: transform_symbol_assignment_statement, conversion.CPSExpressionStatement: transform_expression_statement, - conversion.CPSFunctionDefinitionStatement: transform_function_definition_statement, conversion.CPSIfElseStatement: transform_if_else_statement, conversion.CPSListAppendStatement: transform_list_append_statement, conversion.CPSPushStatement: transform_push_statement,