5 CIntegerLiteral = collections.namedtuple(
12 CStringLiteral = collections.namedtuple(
20 CVariableExpression = collections.namedtuple(
21 'CVariableExpression',
27 CSymbolExpression = collections.namedtuple(
35 CStructureLiteralExpression = collections.namedtuple(
36 'CStructureLiteralExpression',
39 'symbol_list_variable',
40 'value_list_variable',
44 CPushStatement = collections.namedtuple(
51 CFunctionCallExpression = collections.namedtuple(
52 'CFunctionCallExpression',
55 'function_expression',
60 # TODO We are currently not changing variables, just preventing them from being accessed.
61 CSymbolAssignmentStatement = collections.namedtuple(
62 'CSymbolAssignmentStatement',
65 'target_symbol_list_index',
70 CArrayVariableInitializationStatement = collections.namedtuple(
71 'CArrayVariableInitializationStatement',
78 CSymbolArrayVariableInitializationStatement = collections.namedtuple(
79 'CSymbolArrayVariableInitializationStatement',
83 'symbol_list_indices',
87 CVariableInitializationStatement = collections.namedtuple(
88 'CVariableInitializationStatement',
95 CVariableReassignmentStatement = collections.namedtuple(
96 'CVariableReassignmentStatement',
103 CExpressionStatement = collections.namedtuple(
104 'CExpressionStatement',
110 CIfElseStatement = collections.namedtuple(
113 'condition_expression',
115 'else_statement_list',
119 CFunctionDeclaration = collections.namedtuple(
120 'CFunctionDeclaration',
126 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
127 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
128 CFunctionDefinition = collections.namedtuple(
129 'CFunctionDefinition',
132 'argument_name_list',
137 CProgram = collections.namedtuple(
141 'function_definition_list',
142 'operator_declarations',
144 'standard_libraries',
145 'string_literal_list',
154 'print': ['stdio.h'],
158 def transform_variable_expression(accumulators, expression):
159 assert isinstance(expression, conversion.CPSVariableExpression)
160 return CVariableExpression(variable=expression.variable)
162 def transform_string_literal_expression(accumulators, expression):
163 value = expression.string
166 index = accumulators.string_literal_list.index(value)
168 index = len(accumulators.string_literal_list)
169 accumulators.string_literal_list.append(value)
171 return CStringLiteral(index=index, value=value)
173 def transform_symbol_expression(accumulators, expression):
174 if expression.symbol in BUILTINS:
175 accumulators.builtin_set.add(expression.symbol)
178 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
180 symbol_list_index = len(accumulators.symbol_list)
181 accumulators.symbol_list.append(expression.symbol)
183 return CSymbolExpression(
184 symbol=expression.symbol,
185 symbol_list_index=symbol_list_index,
188 def transform_integer_literal_expression(accumulators, expression):
189 return CIntegerLiteral(value=expression.integer)
191 CListConstructExpression = collections.namedtuple(
192 'CListConstructExpression',
198 CListAppendStatement = collections.namedtuple(
199 'CListAppendStatement',
206 def transform_structure_literal_expression(accumulators, expression):
207 return CStructureLiteralExpression(
208 field_count=expression.field_count,
209 symbol_list_variable=expression.symbol_list_variable,
210 value_list_variable=expression.value_list_variable,
213 def transform_list_construct_expression(accumulators, expression):
214 return CListConstructExpression(allocate=expression.allocate)
216 def transform_list_append_statement(accumulators, expression):
217 return CListAppendStatement(
218 list_expression=transform_expression(accumulators, expression.list_expression),
219 item_expression=transform_expression(accumulators, expression.item_expression),
222 def transform_expression(accumulators, expression):
224 conversion.CPSFunctionCallExpression: transform_function_call_expression,
225 conversion.CPSIntegerLiteralExpression: transform_integer_literal_expression,
226 conversion.CPSListConstructExpression: transform_list_construct_expression,
227 conversion.CPSStructureLiteralExpression: transform_structure_literal_expression,
228 conversion.CPSStringLiteralExpression: transform_string_literal_expression,
229 conversion.CPSSymbolExpression: transform_symbol_expression,
230 conversion.CPSVariableExpression: transform_variable_expression,
231 }[type(expression)](accumulators, expression)
233 def transform_symbol_assignment_statement(accumulators, assignment_statement):
234 # TODO Check that target is not a builtin
236 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
238 symbol_list_index = len(accumulators.symbol_list)
239 accumulators.symbol_list.append(assignment_statement.target)
241 return CSymbolAssignmentStatement(
242 target=assignment_statement.target,
243 target_symbol_list_index=symbol_list_index,
244 expression=transform_expression(
246 assignment_statement.expression,
250 def transform_function_call_expression(accumulators, function_call):
251 # TODO Use the symbol from SYMBOL LIST
252 return CFunctionCallExpression(
253 metadata=function_call.metadata,
254 function_expression=transform_expression(accumulators, function_call.function_expression),
255 argument_count=function_call.argument_count,
258 def transform_expression_statement(accumulators, statement):
259 return CExpressionStatement(
260 expression=transform_expression(accumulators, statement.expression),
263 def transform_if_else_statement(accumulators, statement):
264 return CIfElseStatement(
265 condition_expression=transform_expression(accumulators, statement.condition_expression),
266 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
267 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
270 def transform_array_variable_initialization_statement(accumulators, statement):
271 return CArrayVariableInitializationStatement(
272 variable=statement.variable,
273 items=tuple(transform_expression(accumulators, i) for i in statement.items),
276 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
277 symbol_list_indices = []
279 for symbol in statement.symbol_list:
281 symbol_list_index = accumulators.symbol_list.index(symbol)
283 symbol_list_index = len(accumulators.symbol_list)
284 accumulators.symbol_list.append(symbol)
286 symbol_list_indices.append(symbol_list_index)
288 return CSymbolArrayVariableInitializationStatement(
289 variable=statement.variable,
290 symbol_list=statement.symbol_list,
291 symbol_list_indices=tuple(symbol_list_indices),
294 def transform_variable_initialization_statement(accumulators, statement):
295 return CVariableInitializationStatement(
296 variable=statement.variable,
297 expression=transform_expression(accumulators, statement.expression),
300 def transform_variable_reassignment_statement(accumulators, statement):
301 return CVariableReassignmentStatement(
302 variable=statement.variable,
303 expression=transform_expression(accumulators, statement.expression),
306 def transform_function_definition_statement(accumulators, statement):
307 # TODO Allow defining the same function in different contexts
308 if any(fd.name == statement.name for fd in accumulators.function_definition_list):
309 raise Exception('A function with name "{}" already exists'.format(statement.name))
311 # TODO Add argument names to the symbol table
312 accumulators.function_definition_list.append(CFunctionDefinition(
314 argument_name_list=statement.argument_name_list,
315 statement_list=tuple(transform_statement(accumulators, s) for s in statement.statement_list)
318 return CFunctionDeclaration(name=statement.name)
320 def transform_push_statement(accumulators, statement):
321 return CPushStatement(expression=transform_expression(accumulators, statement.expression))
323 def transform_statement(accumulators, statement):
325 conversion.CPSArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
326 conversion.CPSAssignmentStatement: transform_symbol_assignment_statement,
327 conversion.CPSExpressionStatement: transform_expression_statement,
328 conversion.CPSFunctionDefinitionStatement: transform_function_definition_statement,
329 conversion.CPSIfElseStatement: transform_if_else_statement,
330 conversion.CPSListAppendStatement: transform_list_append_statement,
331 conversion.CPSPushStatement: transform_push_statement,
332 conversion.CPSSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
333 conversion.CPSVariableInitializationStatement: transform_variable_initialization_statement,
334 conversion.CPSVariableReassignmentStatement: transform_variable_reassignment_statement,
335 }[type(statement)](accumulators, statement)
338 Accumulators = collections.namedtuple(
342 'function_definition_list',
345 'string_literal_list',
349 def transform(program):
350 accumulators = Accumulators(
352 function_definition_list=[],
355 string_literal_list=[],
359 transform_statement(accumulators, statement) for statement in program.statement_list
362 standard_library_set = set()
363 for builtin in accumulators.builtin_set:
364 for standard_library in BUILTINS[builtin]:
365 standard_library_set.add(standard_library)
368 builtin_set=accumulators.builtin_set,
369 function_definition_list=accumulators.function_definition_list,
370 operator_declarations=tuple(sorted(accumulators.operator_set)),
371 statements=statement_list,
372 standard_libraries=standard_library_set,
373 string_literal_list=accumulators.string_literal_list,
374 symbol_list=accumulators.symbol_list,
378 if __name__ == '__main__':