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 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
120 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
121 CFunctionDefinition = collections.namedtuple(
122 'CFunctionDefinition',
126 'argument_name_list',
131 CProgram = collections.namedtuple(
135 'function_definition_list',
136 'operator_declarations',
138 'standard_libraries',
139 'string_literal_list',
148 'print': ['stdio.h'],
152 def transform_variable_expression(accumulators, expression):
153 assert isinstance(expression, conversion.CPSVariableExpression)
154 return CVariableExpression(variable=expression.variable)
156 def transform_string_literal_expression(accumulators, expression):
157 value = expression.string
160 index = accumulators.string_literal_list.index(value)
162 index = len(accumulators.string_literal_list)
163 accumulators.string_literal_list.append(value)
165 return CStringLiteral(index=index, value=value)
167 def transform_symbol_expression(accumulators, expression):
168 if expression.symbol in BUILTINS:
169 accumulators.builtin_set.add(expression.symbol)
172 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
174 symbol_list_index = len(accumulators.symbol_list)
175 accumulators.symbol_list.append(expression.symbol)
177 return CSymbolExpression(
178 symbol=expression.symbol,
179 symbol_list_index=symbol_list_index,
182 def transform_integer_literal_expression(accumulators, expression):
183 return CIntegerLiteral(value=expression.integer)
185 CListConstructExpression = collections.namedtuple(
186 'CListConstructExpression',
192 CLambdaExpression = collections.namedtuple(
200 CListAppendStatement = collections.namedtuple(
201 'CListAppendStatement',
208 def transform_structure_literal_expression(accumulators, expression):
209 return CStructureLiteralExpression(
210 field_count=expression.field_count,
211 symbol_list_variable=expression.symbol_list_variable,
212 value_list_variable=expression.value_list_variable,
215 def transform_lambda_expression(accumulators, expression):
216 if expression.name is None:
219 name = expression.name
221 index = accumulators.function_name_iterators.get(name, 0)
222 accumulators.function_name_iterators[name] = index + 1
224 accumulators.function_definition_list.append(CFunctionDefinition(
227 argument_name_list=expression.argument_name_list,
228 statement_list=tuple(transform_statement(accumulators, s) for s in expression.statement_list),
231 return CLambdaExpression(
237 def transform_list_construct_expression(accumulators, expression):
238 return CListConstructExpression(allocate=expression.allocate)
240 def transform_list_append_statement(accumulators, expression):
241 return CListAppendStatement(
242 list_expression=transform_expression(accumulators, expression.list_expression),
243 item_expression=transform_expression(accumulators, expression.item_expression),
246 def transform_expression(accumulators, expression):
248 conversion.CPSFunctionCallExpression: transform_function_call_expression,
249 conversion.CPSIntegerLiteralExpression: transform_integer_literal_expression,
250 conversion.CPSLambdaExpression: transform_lambda_expression,
251 conversion.CPSListConstructExpression: transform_list_construct_expression,
252 conversion.CPSStructureLiteralExpression: transform_structure_literal_expression,
253 conversion.CPSStringLiteralExpression: transform_string_literal_expression,
254 conversion.CPSSymbolExpression: transform_symbol_expression,
255 conversion.CPSVariableExpression: transform_variable_expression,
256 }[type(expression)](accumulators, expression)
258 def transform_symbol_assignment_statement(accumulators, assignment_statement):
259 # TODO Check that target is not a builtin
261 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
263 symbol_list_index = len(accumulators.symbol_list)
264 accumulators.symbol_list.append(assignment_statement.target)
266 return CSymbolAssignmentStatement(
267 target=assignment_statement.target,
268 target_symbol_list_index=symbol_list_index,
269 expression=transform_expression(
271 assignment_statement.expression,
275 def transform_function_call_expression(accumulators, function_call):
276 # TODO Use the symbol from SYMBOL LIST
277 return CFunctionCallExpression(
278 metadata=function_call.metadata,
279 function_expression=transform_expression(accumulators, function_call.function_expression),
280 argument_count=function_call.argument_count,
283 def transform_expression_statement(accumulators, statement):
284 return CExpressionStatement(
285 expression=transform_expression(accumulators, statement.expression),
288 def transform_if_else_statement(accumulators, statement):
289 return CIfElseStatement(
290 condition_expression=transform_expression(accumulators, statement.condition_expression),
291 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
292 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
295 def transform_array_variable_initialization_statement(accumulators, statement):
296 return CArrayVariableInitializationStatement(
297 variable=statement.variable,
298 items=tuple(transform_expression(accumulators, i) for i in statement.items),
301 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
302 symbol_list_indices = []
304 for symbol in statement.symbol_list:
306 symbol_list_index = accumulators.symbol_list.index(symbol)
308 symbol_list_index = len(accumulators.symbol_list)
309 accumulators.symbol_list.append(symbol)
311 symbol_list_indices.append(symbol_list_index)
313 return CSymbolArrayVariableInitializationStatement(
314 variable=statement.variable,
315 symbol_list=statement.symbol_list,
316 symbol_list_indices=tuple(symbol_list_indices),
319 def transform_variable_initialization_statement(accumulators, statement):
320 return CVariableInitializationStatement(
321 variable=statement.variable,
322 expression=transform_expression(accumulators, statement.expression),
325 def transform_variable_reassignment_statement(accumulators, statement):
326 return CVariableReassignmentStatement(
327 variable=statement.variable,
328 expression=transform_expression(accumulators, statement.expression),
331 def transform_push_statement(accumulators, statement):
332 return CPushStatement(expression=transform_expression(accumulators, statement.expression))
334 def transform_statement(accumulators, statement):
336 conversion.CPSArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
337 conversion.CPSAssignmentStatement: transform_symbol_assignment_statement,
338 conversion.CPSExpressionStatement: transform_expression_statement,
339 conversion.CPSIfElseStatement: transform_if_else_statement,
340 conversion.CPSListAppendStatement: transform_list_append_statement,
341 conversion.CPSPushStatement: transform_push_statement,
342 conversion.CPSSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
343 conversion.CPSVariableInitializationStatement: transform_variable_initialization_statement,
344 conversion.CPSVariableReassignmentStatement: transform_variable_reassignment_statement,
345 }[type(statement)](accumulators, statement)
348 Accumulators = collections.namedtuple(
352 'function_definition_list',
353 'function_name_iterators',
356 'string_literal_list',
360 def transform(program):
361 accumulators = Accumulators(
363 function_definition_list=[],
364 function_name_iterators={},
367 string_literal_list=[],
371 transform_statement(accumulators, statement) for statement in program.statement_list
374 standard_library_set = set()
375 for builtin in accumulators.builtin_set:
376 for standard_library in BUILTINS[builtin]:
377 standard_library_set.add(standard_library)
380 builtin_set=accumulators.builtin_set,
381 function_definition_list=accumulators.function_definition_list,
382 operator_declarations=tuple(sorted(accumulators.operator_set)),
383 statements=statement_list,
384 standard_libraries=standard_library_set,
385 string_literal_list=accumulators.string_literal_list,
386 symbol_list=accumulators.symbol_list,
390 if __name__ == '__main__':