Combined accumulators into one namedtuple
authorDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 8 Aug 2017 02:02:36 +0000 (22:02 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 8 Aug 2017 02:02:36 +0000 (22:02 -0400)
transformation.py

index 3e898d8..d27a0c5 100644 (file)
@@ -83,20 +83,18 @@ EQUALITY_LEVEL_OPERATOR_TO_FUNCTION_NAME_MAPPING = {
     '>':    'greaterThan',
 }
 
-def transform_equality_level_expression(builtin_dependencies, symbol_list, expression):
+def transform_equality_level_expression(accumulators, expression):
     # Transform expressions like 1 < 2 < 3 into expressions like 1 < 2 && 2 < 3
     if isinstance(expression.left, parsing.FurInfixExpression) and expression.left.order == 'equality_level':
         left = transform_equality_level_expression(
-            builtin_dependencies,
-            symbol_list,
+            accumulators,
             expression.left
         )
 
         middle = left.right
 
         right = transform_expression(
-            builtin_dependencies,
-            symbol_list,
+            accumulators,
             expression.right,
         )
 
@@ -113,8 +111,8 @@ def transform_equality_level_expression(builtin_dependencies, symbol_list, expre
 
     return CFunctionCallForFurInfixOperator(
         name=EQUALITY_LEVEL_OPERATOR_TO_FUNCTION_NAME_MAPPING[expression.operator],
-        left=transform_expression(builtin_dependencies, symbol_list, expression.left),
-        right=transform_expression(builtin_dependencies, symbol_list, expression.right),
+        left=transform_expression(accumulators, expression.left),
+        right=transform_expression(accumulators, expression.right),
     )
 
 BUILTINS = {
@@ -124,27 +122,27 @@ BUILTINS = {
     'true':     [],
 }
 
-def transform_expression(builtin_dependencies, symbol_list, expression):
+def transform_expression(accumulators, expression):
     if isinstance(expression, parsing.FurParenthesizedExpression):
         # Parentheses can be removed because everything in the C output is explicitly parenthesized
-        return transform_expression(builtin_dependencies, symbol_list, expression.internal)
+        return transform_expression(accumulators, expression.internal)
 
     if isinstance(expression, parsing.FurNegationExpression):
-        return transform_negation_expression(builtin_dependencies, symbol_list, expression)
+        return transform_negation_expression(accumulators, expression)
 
     if isinstance(expression, parsing.FurFunctionCallExpression):
-        return transform_function_call_expression(builtin_dependencies, symbol_list, expression)
+        return transform_function_call_expression(accumulators, expression)
 
     if isinstance(expression, parsing.FurSymbolExpression):
         if expression.value in ['true', 'false']:
             return CConstantExpression(value=expression.value)
 
-        if expression.value not in symbol_list:
+        if expression.value not in accumulators.symbol_list:
             symbol_list.append(expression.value)
 
         return CSymbolExpression(
             symbol=expression.value,
-            symbol_list_index=symbol_list.index(expression.value),
+            symbol_list_index=accumulators.symbol_list.index(expression.value),
         )
 
     LITERAL_TYPE_MAPPING = {
@@ -157,7 +155,7 @@ def transform_expression(builtin_dependencies, symbol_list, expression):
 
     if isinstance(expression, parsing.FurInfixExpression):
         if expression.order == 'equality_level':
-            return transform_equality_level_expression(builtin_dependencies, symbol_list, expression)
+            return transform_equality_level_expression(accumulators, expression)
 
         INFIX_OPERATOR_TO_FUNCTION_NAME = {
             '+':    'add',
@@ -171,71 +169,81 @@ def transform_expression(builtin_dependencies, symbol_list, expression):
 
         return CFunctionCallForFurInfixOperator(
             name=INFIX_OPERATOR_TO_FUNCTION_NAME[expression.operator],
-            left=transform_expression(builtin_dependencies, symbol_list, expression.left),
-            right=transform_expression(builtin_dependencies, symbol_list, expression.right),
+            left=transform_expression(accumulators, expression.left),
+            right=transform_expression(accumulators, expression.right),
         )
 
     raise Exception('Could not transform expression "{}"'.format(expression))
 
-def transform_assignment_statement(builtin_dependencies, symbol_list, assignment_statement):
+def transform_assignment_statement(accumulators, assignment_statement):
     # TODO Check that target is not a builtin
-    if assignment_statement.target not in symbol_list:
-        symbol_list.append(assignment_statement.target)
+    if assignment_statement.target not in accumulators.symbol_list:
+        accumulators.symbol_list.append(assignment_statement.target)
 
     return CAssignmentStatement(
         target=assignment_statement.target,
-        target_symbol_list_index=symbol_list.index(assignment_statement.target),
+        target_symbol_list_index=accumulators.symbol_list.index(assignment_statement.target),
         expression=transform_expression(
-            builtin_dependencies,
-            symbol_list,
+            accumulators,
             assignment_statement.expression,
         ),
     )
 
-def transform_negation_expression(builtin_dependencies, symbol_list, negation_expression):
+def transform_negation_expression(accumulators, negation_expression):
     return CNegationExpression(
-        value=transform_expression(builtin_dependencies, symbol_list, negation_expression.value),
+        value=transform_expression(accumulators, negation_expression.value),
     )
 
-def transform_function_call_expression(builtin_dependencies, symbol_list, function_call):
+def transform_function_call_expression(accumulators, function_call):
     if function_call.function.value in BUILTINS.keys():
         # TODO Check that the builtin is actually callable
-        builtin_dependencies.add(function_call.function.value)
+        accumulators.builtins.add(function_call.function.value)
 
         return CFunctionCallExpression(
             name='builtin$' + function_call.function.value,
             arguments=tuple(
-                transform_expression(builtin_dependencies, symbol_list, arg)
+                transform_expression(accumulators, arg)
                 for arg in function_call.arguments
             ),
         )
 
     raise Exception()
 
-def transform_statement(builtin_dependencies, symbol_list, statement):
+def transform_statement(accumulators, statement):
     return {
         parsing.FurAssignmentStatement: transform_assignment_statement,
         parsing.FurFunctionCallExpression: transform_function_call_expression,
-    }[type(statement)](builtin_dependencies, symbol_list, statement)
+    }[type(statement)](accumulators, statement)
+
+
+Accumulators = collections.namedtuple(
+    'Accumulators',
+    [
+        'builtins',
+        'symbol_list',
+    ],
+)
 
 def transform(program):
-    builtins = set()
-    symbol_list = []
+    accumulators = Accumulators(
+        builtins=set(),
+        symbol_list = [],
+    )
 
     c_statements = [
-        transform_statement(builtins, symbol_list, statement) for statement in program.statement_list
+        transform_statement(accumulators, statement) for statement in program.statement_list
     ]
 
     standard_libraries = set()
-    for builtin in builtins:
+    for builtin in accumulators.builtins:
         for standard_library in BUILTINS[builtin]:
             standard_libraries.add(standard_library)
 
     return CProgram(
-        builtins=builtins,
+        builtins=accumulators.builtins,
         statements=c_statements,
         standard_libraries=standard_libraries,
-        symbol_list=symbol_list,
+        symbol_list=accumulators.symbol_list,
     )