5 CIntegerLiteral = collections.namedtuple(
12 CStringLiteral = collections.namedtuple(
19 CConstantExpression = collections.namedtuple(
20 'CConstantExpression',
26 CSymbolExpression = collections.namedtuple(
34 CNegationExpression = collections.namedtuple(
35 'CNegationExpression',
41 CAdditionExpression = collections.namedtuple(
42 'CAdditionExpression',
49 CSubtractionExpression = collections.namedtuple(
50 'CSubtractionExpression',
57 CMultiplicationExpression = collections.namedtuple(
58 'CMultiplicationExpression',
65 CIntegerDivisionExpression = collections.namedtuple(
66 'CIntegerDivisionExpression',
73 CModularDivisionExpression = collections.namedtuple(
74 'CModularDivisionExpression',
81 CFunctionCallExpression = collections.namedtuple(
82 'CFunctionCallExpression',
89 CAssignmentStatement = collections.namedtuple(
90 'CAssignmentStatement',
93 'target_symbol_list_index',
98 CProgram = collections.namedtuple(
103 'standard_libraries',
111 'print': ['stdio.h'],
115 def transform_expression(builtin_dependencies, symbol_list, expression):
116 if isinstance(expression, parsing.FurParenthesizedExpression):
117 # Parentheses can be removed because everything in the C output is explicitly parenthesized
118 return transform_expression(builtin_dependencies, symbol_list, expression.internal)
120 if isinstance(expression, parsing.FurNegationExpression):
121 return transform_negation_expression(builtin_dependencies, symbol_list, expression)
123 if isinstance(expression, parsing.FurFunctionCallExpression):
124 return transform_function_call_expression(builtin_dependencies, symbol_list, expression)
126 if isinstance(expression, parsing.FurSymbolExpression):
127 if expression.value in ['true', 'false']:
128 return CConstantExpression(value=expression.value)
130 if expression.value not in symbol_list:
131 symbol_list.append(expression.value)
133 return CSymbolExpression(
134 symbol=expression.value,
135 symbol_list_index=symbol_list.index(expression.value),
138 LITERAL_TYPE_MAPPING = {
139 parsing.FurIntegerLiteralExpression: CIntegerLiteral,
140 parsing.FurStringLiteralExpression: CStringLiteral,
143 if type(expression) in LITERAL_TYPE_MAPPING:
144 return LITERAL_TYPE_MAPPING[type(expression)](value=expression.value)
146 INFIX_TYPE_MAPPING = {
147 parsing.FurAdditionExpression: CAdditionExpression,
148 parsing.FurSubtractionExpression: CSubtractionExpression,
149 parsing.FurMultiplicationExpression: CMultiplicationExpression,
150 parsing.FurIntegerDivisionExpression: CIntegerDivisionExpression,
151 parsing.FurModularDivisionExpression: CModularDivisionExpression,
154 return INFIX_TYPE_MAPPING[type(expression)](
155 left=transform_expression(builtin_dependencies, symbol_list, expression.left),
156 right=transform_expression(builtin_dependencies, symbol_list, expression.right),
159 def transform_assignment_statement(builtin_dependencies, symbol_list, assignment_statement):
160 # TODO Check that target is not a builtin
161 if assignment_statement.target not in symbol_list:
162 symbol_list.append(assignment_statement.target)
164 return CAssignmentStatement(
165 target=assignment_statement.target,
166 target_symbol_list_index=symbol_list.index(assignment_statement.target),
167 expression=transform_expression(
168 builtin_dependencies,
170 assignment_statement.expression,
174 def transform_negation_expression(builtin_dependencies, symbol_list, negation_expression):
175 return CNegationExpression(
176 value=transform_expression(builtin_dependencies, symbol_list, negation_expression.value),
179 def transform_function_call_expression(builtin_dependencies, symbol_list, function_call):
180 if function_call.function.value in BUILTINS.keys():
181 # TODO Check that the builtin is actually callable
182 builtin_dependencies.add(function_call.function.value)
184 return CFunctionCallExpression(
185 name='builtin$' + function_call.function.value,
187 transform_expression(builtin_dependencies, symbol_list, arg)
188 for arg in function_call.arguments
194 def transform_statement(builtin_dependencies, symbol_list, statement):
196 parsing.FurAssignmentStatement: transform_assignment_statement,
197 parsing.FurFunctionCallExpression: transform_function_call_expression,
198 }[type(statement)](builtin_dependencies, symbol_list, statement)
200 def transform(program):
205 transform_statement(builtins, symbol_list, statement) for statement in program.statement_list
208 standard_libraries = set()
209 for builtin in builtins:
210 for standard_library in BUILTINS[builtin]:
211 standard_libraries.add(standard_library)
215 statements=c_statements,
216 standard_libraries=standard_libraries,
217 symbol_list=symbol_list,
221 if __name__ == '__main__':