4 import parsing # TODO Remove this import, as we should be normalizing everything before it gets here
6 CIntegerLiteral = collections.namedtuple(
13 CStringLiteral = collections.namedtuple(
21 CVariableExpression = collections.namedtuple(
22 'CVariableExpression',
28 CSymbolExpression = collections.namedtuple(
36 CStructureLiteralExpression = collections.namedtuple(
37 'CStructureLiteralExpression',
40 'symbol_list_variable',
41 'value_list_variable',
45 CDotExpression = collections.namedtuple(
54 CNegationExpression = collections.namedtuple(
55 'CNegationExpression',
61 CFunctionCallForFurInfixOperator = collections.namedtuple(
62 'CFunctionCallForFurInfixOperator',
68 CPushStatement = collections.namedtuple(
75 CFunctionCallExpression = collections.namedtuple(
76 'CFunctionCallExpression',
78 'function_expression',
83 # TODO We are currently not changing variables, just preventing them from being accessed.
84 CSymbolAssignmentStatement = collections.namedtuple(
85 'CSymbolAssignmentStatement',
88 'target_symbol_list_index',
93 CArrayVariableInitializationStatement = collections.namedtuple(
94 'CArrayVariableInitializationStatement',
101 CSymbolArrayVariableInitializationStatement = collections.namedtuple(
102 'CSymbolArrayVariableInitializationStatement',
106 'symbol_list_indices',
110 CVariableInitializationStatement = collections.namedtuple(
111 'CVariableInitializationStatement',
118 CVariableReassignmentStatement = collections.namedtuple(
119 'CVariableReassignmentStatement',
126 CExpressionStatement = collections.namedtuple(
127 'CExpressionStatement',
133 CIfElseStatement = collections.namedtuple(
136 'condition_expression',
138 'else_statement_list',
142 CFunctionDeclaration = collections.namedtuple(
143 'CFunctionDeclaration',
149 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
150 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
151 CFunctionDefinition = collections.namedtuple(
152 'CFunctionDefinition',
155 'argument_name_list',
160 CProgram = collections.namedtuple(
164 'function_definition_list',
165 'operator_declarations',
167 'standard_libraries',
168 'string_literal_list',
177 'print': ['stdio.h'],
181 def transform_variable_expression(accumulators, expression):
182 assert isinstance(expression, normalization.NormalVariableExpression)
183 return CVariableExpression(variable=expression.variable)
185 def transform_string_literal_expression(accumulators, expression):
186 value = expression.string
189 index = accumulators.string_literal_list.index(value)
191 index = len(accumulators.string_literal_list)
192 accumulators.string_literal_list.append(value)
194 return CStringLiteral(index=index, value=value)
196 def transform_symbol_expression(accumulators, expression):
197 if expression.symbol in BUILTINS:
198 accumulators.builtin_set.add(expression.symbol)
201 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
203 symbol_list_index = len(accumulators.symbol_list)
204 accumulators.symbol_list.append(expression.symbol)
206 return CSymbolExpression(
207 symbol=expression.symbol,
208 symbol_list_index=symbol_list_index,
211 CInfixDeclaration = collections.namedtuple(
221 FUR_INFIX_OPERATOR_TO_C_FUNCTION = {
225 FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = {
226 '+': CInfixDeclaration(name='add', in_type='integer', out_type='integer', operator='+'),
227 '-': CInfixDeclaration(name='subtract', in_type='integer', out_type='integer', operator='-'),
228 '*': CInfixDeclaration(name='multiply', in_type='integer', out_type='integer', operator='*'),
229 '//': CInfixDeclaration(name='integerDivide', in_type='integer', out_type='integer', operator='/'),
230 '%': CInfixDeclaration(name='modularDivide', in_type='integer', out_type='integer', operator='%'),
231 'and': CInfixDeclaration(name='and', in_type='boolean', out_type='boolean', operator='&&'),
232 'or': CInfixDeclaration(name='or', in_type='boolean', out_type='boolean', operator='||'),
233 '==': CInfixDeclaration(name='equals', in_type='integer', out_type='boolean', operator='=='),
234 '!=': CInfixDeclaration(name='notEquals', in_type='integer', out_type='boolean', operator='!='),
235 '<=': CInfixDeclaration(name='lessThanOrEqual', in_type='integer', out_type='boolean', operator='<='),
236 '>=': CInfixDeclaration(name='greaterThanOrEqual', in_type='integer', out_type='boolean', operator='>='),
237 '<': CInfixDeclaration(name='lessThan', in_type='integer', out_type='boolean', operator='<'),
238 '>': CInfixDeclaration(name='greaterThan', in_type='integer', out_type='boolean', operator='>'),
241 def transform_infix_operator_without_c_equivalent(accumulators, expression):
242 return CFunctionCallForFurInfixOperator(
246 def transform_infix_expression(accumulators, expression):
247 if expression.operator in FUR_INFIX_OPERATOR_TO_C_FUNCTION:
248 return transform_infix_operator_without_c_equivalent(accumulators, expression)
250 accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
252 return CFunctionCallForFurInfixOperator(
253 name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
256 def transform_integer_literal_expression(accumulators, expression):
257 return CIntegerLiteral(value=expression.integer)
259 def transform_negation_expression(accumulators, expression):
260 return CNegationExpression(
261 value=transform_expression(accumulators, expression.internal_expression),
264 CListConstructExpression = collections.namedtuple(
265 'CListConstructExpression',
271 CListAppendStatement = collections.namedtuple(
272 'CListAppendStatement',
279 CListGetExpression = collections.namedtuple(
280 'CListGetExpression',
287 def transform_structure_literal_expression(accumulators, expression):
288 return CStructureLiteralExpression(
289 field_count=expression.field_count,
290 symbol_list_variable=expression.symbol_list_variable,
291 value_list_variable=expression.value_list_variable,
294 def transform_dot_expression(accumulators, expression):
296 symbol_list_index = accumulators.symbol_list.index(expression.field)
299 symbol_list_index = len(accumulators.symbol_list)
300 accumulators.symbol_list.append(expression.field)
302 return CDotExpression(
303 instance=transform_variable_expression(accumulators, expression.instance),
304 symbol=expression.field,
305 symbol_list_index=symbol_list_index,
308 def transform_list_construct_expression(accumulators, expression):
309 return CListConstructExpression(allocate=expression.allocate)
311 def transform_list_get_expression(accumulators, expression):
312 return CListGetExpression(
313 list_expression=transform_expression(accumulators, expression.list_expression),
314 index_expression=transform_expression(accumulators, expression.index_expression),
317 def transform_list_append_statement(accumulators, expression):
318 return CListAppendStatement(
319 list_expression=transform_expression(accumulators, expression.list_expression),
320 item_expression=transform_expression(accumulators, expression.item_expression),
323 def transform_expression(accumulators, expression):
324 # TODO Clean up handlers for parsing expressions
326 parsing.FurInfixExpression: transform_infix_expression,
327 parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
328 parsing.FurNegationExpression: transform_negation_expression,
329 parsing.FurStringLiteralExpression: transform_string_literal_expression,
330 normalization.NormalDotExpression: transform_dot_expression,
331 normalization.NormalFunctionCallExpression: transform_function_call_expression,
332 normalization.NormalInfixExpression: transform_infix_expression,
333 normalization.NormalIntegerLiteralExpression: transform_integer_literal_expression,
334 normalization.NormalListConstructExpression: transform_list_construct_expression,
335 normalization.NormalListGetExpression: transform_list_get_expression,
336 normalization.NormalNegationExpression: transform_negation_expression,
337 normalization.NormalStructureLiteralExpression: transform_structure_literal_expression,
338 normalization.NormalStringLiteralExpression: transform_string_literal_expression,
339 normalization.NormalSymbolExpression: transform_symbol_expression,
340 normalization.NormalVariableExpression: transform_variable_expression,
341 }[type(expression)](accumulators, expression)
343 def transform_symbol_assignment_statement(accumulators, assignment_statement):
344 # TODO Check that target is not a builtin
346 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
348 symbol_list_index = len(accumulators.symbol_list)
349 accumulators.symbol_list.append(assignment_statement.target)
351 return CSymbolAssignmentStatement(
352 target=assignment_statement.target,
353 target_symbol_list_index=symbol_list_index,
354 expression=transform_expression(
356 assignment_statement.expression,
360 def transform_function_call_expression(accumulators, function_call):
361 # TODO Use the symbol from SYMBOL LIST
362 return CFunctionCallExpression(
363 function_expression=transform_expression(accumulators, function_call.function_expression),
364 argument_count=function_call.argument_count,
367 def transform_expression_statement(accumulators, statement):
368 return CExpressionStatement(
369 expression=transform_expression(accumulators, statement.expression),
372 def transform_if_else_statement(accumulators, statement):
373 return CIfElseStatement(
374 condition_expression=transform_expression(accumulators, statement.condition_expression),
375 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
376 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
379 def transform_array_variable_initialization_statement(accumulators, statement):
380 return CArrayVariableInitializationStatement(
381 variable=statement.variable,
382 items=tuple(transform_expression(accumulators, i) for i in statement.items),
385 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
386 symbol_list_indices = []
388 for symbol in statement.symbol_list:
390 symbol_list_index = accumulators.symbol_list.index(symbol)
392 symbol_list_index = len(accumulators.symbol_list)
393 accumulators.symbol_list.append(symbol)
395 symbol_list_indices.append(symbol_list_index)
397 return CSymbolArrayVariableInitializationStatement(
398 variable=statement.variable,
399 symbol_list=statement.symbol_list,
400 symbol_list_indices=tuple(symbol_list_indices),
403 def transform_variable_initialization_statement(accumulators, statement):
404 return CVariableInitializationStatement(
405 variable=statement.variable,
406 expression=transform_expression(accumulators, statement.expression),
409 def transform_variable_reassignment_statement(accumulators, statement):
410 return CVariableReassignmentStatement(
411 variable=statement.variable,
412 expression=transform_expression(accumulators, statement.expression),
415 def transform_function_definition_statement(accumulators, statement):
416 # TODO Allow defining the same function in different contexts
417 if any(fd.name == statement.name for fd in accumulators.function_definition_list):
418 raise Exception('A function with name "{}" already exists'.format(statement.name))
420 # TODO Add argument names to the symbol table
421 accumulators.function_definition_list.append(CFunctionDefinition(
423 argument_name_list=statement.argument_name_list,
424 statement_list=tuple(transform_statement(accumulators, s) for s in statement.statement_list)
427 return CFunctionDeclaration(name=statement.name)
429 def transform_push_statement(accumulators, statement):
430 return CPushStatement(expression=transform_expression(accumulators, statement.expression))
432 def transform_statement(accumulators, statement):
434 parsing.FurExpressionStatement: transform_expression_statement,
435 normalization.NormalArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
436 normalization.NormalAssignmentStatement: transform_symbol_assignment_statement,
437 normalization.NormalExpressionStatement: transform_expression_statement,
438 normalization.NormalFunctionDefinitionStatement: transform_function_definition_statement,
439 normalization.NormalIfElseStatement: transform_if_else_statement,
440 normalization.NormalListAppendStatement: transform_list_append_statement,
441 normalization.NormalPushStatement: transform_push_statement,
442 normalization.NormalSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
443 normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement,
444 normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement,
445 }[type(statement)](accumulators, statement)
448 Accumulators = collections.namedtuple(
452 'function_definition_list',
455 'string_literal_list',
459 def transform(program):
460 accumulators = Accumulators(
462 function_definition_list=[],
465 string_literal_list=[],
469 transform_statement(accumulators, statement) for statement in program.statement_list
472 standard_library_set = set()
473 for builtin in accumulators.builtin_set:
474 for standard_library in BUILTINS[builtin]:
475 standard_library_set.add(standard_library)
478 builtin_set=accumulators.builtin_set,
479 function_definition_list=accumulators.function_definition_list,
480 operator_declarations=tuple(sorted(accumulators.operator_set)),
481 statements=statement_list,
482 standard_libraries=standard_library_set,
483 string_literal_list=accumulators.string_literal_list,
484 symbol_list=accumulators.symbol_list,
488 if __name__ == '__main__':