X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=transformation.py;h=a9cad95b600141efa33a873942f1f06f54f0cb95;hp=e8ee51c9bab31edc1a60c0d4dbb841d95baefa67;hb=37d4a702fda63b87c1482a59b2ef4c1bba2e3696;hpb=aa339c441f43849a8cae256aa130278ca7618b7e diff --git a/transformation.py b/transformation.py index e8ee51c..a9cad95 100644 --- a/transformation.py +++ b/transformation.py @@ -116,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', ], @@ -199,6 +193,7 @@ CLambdaExpression = collections.namedtuple( 'CLambdaExpression', ( 'name', + 'index', ), ) @@ -218,21 +213,25 @@ def transform_structure_literal_expression(accumulators, expression): ) def transform_lambda_expression(accumulators, expression): - # TODO This function feels hacky - if len(accumulators.lambda_number_list) == 0: - accumulators.lambda_number_list.append(0) + if expression.name is None: + name = '__lambda' else: - accumulators.lambda_number_list.append(accumulators.lambda_number_list[-1] + 1) + name = expression.name - name = '__lambda_{}'.format(accumulators.lambda_number_list[-1]) + 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) + return CLambdaExpression( + name=name, + index=index, + ) def transform_list_construct_expression(accumulators, expression): @@ -329,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)) @@ -351,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, @@ -366,7 +350,7 @@ Accumulators = collections.namedtuple( [ 'builtin_set', 'function_definition_list', - 'lambda_number_list', + 'function_name_iterators', 'operator_set', 'symbol_list', 'string_literal_list', @@ -377,7 +361,7 @@ def transform(program): accumulators = Accumulators( builtin_set=set(), function_definition_list=[], - lambda_number_list=[], + function_name_iterators={}, operator_set=set(), symbol_list=[], string_literal_list=[],