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 CExpressionStatement = collections.namedtuple(
96 'CExpressionStatement',
102 CIfElseExpression = collections.namedtuple(
105 'condition_expression',
107 'else_statement_list',
111 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
112 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
113 CFunctionDefinition = collections.namedtuple(
114 'CFunctionDefinition',
118 'argument_name_list',
123 CProgram = collections.namedtuple(
127 'function_definition_list',
128 'operator_declarations',
130 'standard_libraries',
131 'string_literal_list',
140 'print': ['stdio.h'],
144 def transform_variable_expression(accumulators, expression):
145 assert isinstance(expression, conversion.CPSVariableExpression)
146 return CVariableExpression(variable=expression.variable)
148 def transform_string_literal_expression(accumulators, expression):
149 value = expression.string
152 index = accumulators.string_literal_list.index(value)
154 index = len(accumulators.string_literal_list)
155 accumulators.string_literal_list.append(value)
157 return CStringLiteral(index=index, value=value)
159 def transform_symbol_expression(accumulators, expression):
160 if expression.symbol in BUILTINS:
161 accumulators.builtin_set.add(expression.symbol)
164 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
166 symbol_list_index = len(accumulators.symbol_list)
167 accumulators.symbol_list.append(expression.symbol)
169 return CSymbolExpression(
170 symbol=expression.symbol,
171 symbol_list_index=symbol_list_index,
174 def transform_integer_literal_expression(accumulators, expression):
175 return CIntegerLiteral(value=expression.integer)
177 CListConstructExpression = collections.namedtuple(
178 'CListConstructExpression',
184 CLambdaExpression = collections.namedtuple(
192 CListAppendStatement = collections.namedtuple(
193 'CListAppendStatement',
200 def transform_structure_literal_expression(accumulators, expression):
201 return CStructureLiteralExpression(
202 field_count=expression.field_count,
203 symbol_list_variable=expression.symbol_list_variable,
204 value_list_variable=expression.value_list_variable,
207 def transform_lambda_expression(accumulators, expression):
208 if expression.name is None:
211 name = expression.name
213 index = accumulators.function_name_iterators.get(name, 0)
214 accumulators.function_name_iterators[name] = index + 1
216 accumulators.function_definition_list.append(CFunctionDefinition(
219 argument_name_list=expression.argument_name_list,
220 statement_list=tuple(transform_statement(accumulators, s) for s in expression.statement_list),
223 return CLambdaExpression(
229 def transform_list_construct_expression(accumulators, expression):
230 return CListConstructExpression(allocate=expression.allocate)
232 def transform_list_append_statement(accumulators, expression):
233 return CListAppendStatement(
234 list_expression=transform_expression(accumulators, expression.list_expression),
235 item_expression=transform_expression(accumulators, expression.item_expression),
238 def transform_expression(accumulators, expression):
240 conversion.CPSFunctionCallExpression: transform_function_call_expression,
241 conversion.CPSIfElseExpression: transform_if_else_expression,
242 conversion.CPSIntegerLiteralExpression: transform_integer_literal_expression,
243 conversion.CPSLambdaExpression: transform_lambda_expression,
244 conversion.CPSListConstructExpression: transform_list_construct_expression,
245 conversion.CPSStructureLiteralExpression: transform_structure_literal_expression,
246 conversion.CPSStringLiteralExpression: transform_string_literal_expression,
247 conversion.CPSSymbolExpression: transform_symbol_expression,
248 conversion.CPSVariableExpression: transform_variable_expression,
249 }[type(expression)](accumulators, expression)
251 def transform_symbol_assignment_statement(accumulators, assignment_statement):
252 # TODO Check that target is not a builtin
254 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
256 symbol_list_index = len(accumulators.symbol_list)
257 accumulators.symbol_list.append(assignment_statement.target)
259 return CSymbolAssignmentStatement(
260 target=assignment_statement.target,
261 target_symbol_list_index=symbol_list_index,
262 expression=transform_expression(
264 assignment_statement.expression,
268 def transform_function_call_expression(accumulators, function_call):
269 # TODO Use the symbol from SYMBOL LIST
270 return CFunctionCallExpression(
271 metadata=function_call.metadata,
272 function_expression=transform_expression(accumulators, function_call.function_expression),
273 argument_count=function_call.argument_count,
276 def transform_expression_statement(accumulators, statement):
277 return CExpressionStatement(
278 expression=transform_expression(accumulators, statement.expression),
281 def transform_if_else_expression(accumulators, statement):
282 return CIfElseExpression(
283 condition_expression=transform_expression(accumulators, statement.condition_expression),
284 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
285 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
288 def transform_array_variable_initialization_statement(accumulators, statement):
289 return CArrayVariableInitializationStatement(
290 variable=statement.variable,
291 items=tuple(transform_expression(accumulators, i) for i in statement.items),
294 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
295 symbol_list_indices = []
297 for symbol in statement.symbol_list:
299 symbol_list_index = accumulators.symbol_list.index(symbol)
301 symbol_list_index = len(accumulators.symbol_list)
302 accumulators.symbol_list.append(symbol)
304 symbol_list_indices.append(symbol_list_index)
306 return CSymbolArrayVariableInitializationStatement(
307 variable=statement.variable,
308 symbol_list=statement.symbol_list,
309 symbol_list_indices=tuple(symbol_list_indices),
312 def transform_variable_initialization_statement(accumulators, statement):
313 return CVariableInitializationStatement(
314 variable=statement.variable,
315 expression=transform_expression(accumulators, statement.expression),
318 def transform_push_statement(accumulators, statement):
319 return CPushStatement(expression=transform_expression(accumulators, statement.expression))
321 def transform_statement(accumulators, statement):
323 conversion.CPSArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
324 conversion.CPSAssignmentStatement: transform_symbol_assignment_statement,
325 conversion.CPSExpressionStatement: transform_expression_statement,
326 conversion.CPSListAppendStatement: transform_list_append_statement,
327 conversion.CPSPushStatement: transform_push_statement,
328 conversion.CPSSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
329 conversion.CPSVariableInitializationStatement: transform_variable_initialization_statement,
330 }[type(statement)](accumulators, statement)
333 Accumulators = collections.namedtuple(
337 'function_definition_list',
338 'function_name_iterators',
341 'string_literal_list',
345 def transform(program):
346 accumulators = Accumulators(
348 function_definition_list=[],
349 function_name_iterators={},
352 string_literal_list=[],
356 transform_statement(accumulators, statement) for statement in program.statement_list
359 standard_library_set = set()
360 for builtin in accumulators.builtin_set:
361 for standard_library in BUILTINS[builtin]:
362 standard_library_set.add(standard_library)
365 builtin_set=accumulators.builtin_set,
366 function_definition_list=accumulators.function_definition_list,
367 operator_declarations=tuple(sorted(accumulators.operator_set)),
368 statements=statement_list,
369 standard_libraries=standard_library_set,
370 string_literal_list=accumulators.string_literal_list,
371 symbol_list=accumulators.symbol_list,
375 if __name__ == '__main__':