Make it easier to run without memory leak tests
[fur] / transformation.py
index e8ee51c..a9cad95 100644 (file)
@@ -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=[],