Desugar function definitions to assignments to lambda
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sat, 6 Jan 2018 19:50:54 +0000 (14:50 -0500)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sat, 6 Jan 2018 19:50:54 +0000 (14:50 -0500)
conversion.py
desugaring.py
generation.py
normalization.py
transformation.py

index fd469fa..49e27fd 100644 (file)
@@ -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,
index c951fd5..47dfe6f 100644 (file)
@@ -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):
index 6c1cf0b..74a3fa5 100644 (file)
@@ -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,
index 9725b5b..f6c4246 100644 (file)
@@ -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)
index e8ee51c..6f46d43 100644 (file)
@@ -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,