X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=transformation.py;h=a9cad95b600141efa33a873942f1f06f54f0cb95;hp=56b61f323c50faefb541308899a35dbf5164bc96;hb=37d4a702fda63b87c1482a59b2ef4c1bba2e3696;hpb=68eb624cc15463008b9ed38e17315e9a1f8bdeb0 diff --git a/transformation.py b/transformation.py index 56b61f3..a9cad95 100644 --- a/transformation.py +++ b/transformation.py @@ -1,7 +1,6 @@ import collections import conversion -import normalization CIntegerLiteral = collections.namedtuple( 'CIntegerLiteral', @@ -117,19 +116,13 @@ 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( 'CFunctionDefinition', [ 'name', + 'index', 'argument_name_list', 'statement_list', ], @@ -191,25 +184,25 @@ def transform_integer_literal_expression(accumulators, expression): CListConstructExpression = collections.namedtuple( 'CListConstructExpression', - [ + ( 'allocate', - ], + ), +) + +CLambdaExpression = collections.namedtuple( + 'CLambdaExpression', + ( + 'name', + 'index', + ), ) CListAppendStatement = collections.namedtuple( 'CListAppendStatement', - [ + ( 'list_expression', 'item_expression', - ], -) - -CListGetExpression = collections.namedtuple( - 'CListGetExpression', - [ - 'list_expression', - 'index_expression', - ], + ), ) def transform_structure_literal_expression(accumulators, expression): @@ -219,15 +212,31 @@ def transform_structure_literal_expression(accumulators, expression): value_list_variable=expression.value_list_variable, ) -def transform_list_construct_expression(accumulators, expression): - return CListConstructExpression(allocate=expression.allocate) +def transform_lambda_expression(accumulators, expression): + if expression.name is None: + name = '__lambda' + else: + name = expression.name -def transform_list_get_expression(accumulators, expression): - return CListGetExpression( - list_expression=transform_expression(accumulators, expression.list_expression), - index_expression=transform_expression(accumulators, expression.index_expression), + index = accumulators.function_name_iterators.get(name, 0) + accumulators.function_name_iterators[name] = index + 1 + + accumulators.function_definition_list.append(CFunctionDefinition( + name=name, + index=index, + argument_name_list=expression.argument_name_list, + statement_list=tuple(transform_statement(accumulators, s) for s in expression.statement_list), + )) + + return CLambdaExpression( + name=name, + index=index, ) + +def transform_list_construct_expression(accumulators, expression): + return CListConstructExpression(allocate=expression.allocate) + def transform_list_append_statement(accumulators, expression): return CListAppendStatement( list_expression=transform_expression(accumulators, expression.list_expression), @@ -238,8 +247,8 @@ def transform_expression(accumulators, expression): return { conversion.CPSFunctionCallExpression: transform_function_call_expression, conversion.CPSIntegerLiteralExpression: transform_integer_literal_expression, + conversion.CPSLambdaExpression: transform_lambda_expression, conversion.CPSListConstructExpression: transform_list_construct_expression, - normalization.NormalListGetExpression: transform_list_get_expression, conversion.CPSStructureLiteralExpression: transform_structure_literal_expression, conversion.CPSStringLiteralExpression: transform_string_literal_expression, conversion.CPSSymbolExpression: transform_symbol_expression, @@ -319,20 +328,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)) @@ -341,7 +336,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, @@ -356,6 +350,7 @@ Accumulators = collections.namedtuple( [ 'builtin_set', 'function_definition_list', + 'function_name_iterators', 'operator_set', 'symbol_list', 'string_literal_list', @@ -366,6 +361,7 @@ def transform(program): accumulators = Accumulators( builtin_set=set(), function_definition_list=[], + function_name_iterators={}, operator_set=set(), symbol_list=[], string_literal_list=[],