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',
70 CFunctionCallExpression = collections.namedtuple(
71 'CFunctionCallExpression',
73 'function_expression',
79 # TODO We are currently not changing variables, just preventing them from being accessed.
80 CSymbolAssignmentStatement = collections.namedtuple(
81 'CSymbolAssignmentStatement',
84 'target_symbol_list_index',
89 CArrayVariableInitializationStatement = collections.namedtuple(
90 'CArrayVariableInitializationStatement',
97 CSymbolArrayVariableInitializationStatement = collections.namedtuple(
98 'CSymbolArrayVariableInitializationStatement',
102 'symbol_list_indices',
106 CVariableInitializationStatement = collections.namedtuple(
107 'CVariableInitializationStatement',
114 CVariableReassignmentStatement = collections.namedtuple(
115 'CVariableReassignmentStatement',
122 CExpressionStatement = collections.namedtuple(
123 'CExpressionStatement',
129 CIfElseStatement = collections.namedtuple(
132 'condition_expression',
134 'else_statement_list',
138 CFunctionDeclaration = collections.namedtuple(
139 'CFunctionDeclaration',
145 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
146 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
147 CFunctionDefinition = collections.namedtuple(
148 'CFunctionDefinition',
151 'argument_name_list',
156 CProgram = collections.namedtuple(
160 'function_definition_list',
161 'operator_declarations',
163 'standard_libraries',
164 'string_literal_list',
173 'print': ['stdio.h'],
177 def transform_variable_expression(accumulators, expression):
178 assert isinstance(expression, normalization.NormalVariableExpression)
179 return CVariableExpression(variable=expression.variable)
181 def transform_string_literal_expression(accumulators, expression):
182 value = expression.string
185 index = accumulators.string_literal_list.index(value)
187 index = len(accumulators.string_literal_list)
188 accumulators.string_literal_list.append(value)
190 return CStringLiteral(index=index, value=value)
192 def transform_symbol_expression(accumulators, expression):
193 if expression.symbol in BUILTINS:
194 accumulators.builtin_set.add(expression.symbol)
197 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
199 symbol_list_index = len(accumulators.symbol_list)
200 accumulators.symbol_list.append(expression.symbol)
202 return CSymbolExpression(
203 symbol=expression.symbol,
204 symbol_list_index=symbol_list_index,
207 CInfixDeclaration = collections.namedtuple(
217 FUR_INFIX_OPERATOR_TO_C_FUNCTION = {
221 FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = {
222 '+': CInfixDeclaration(name='add', in_type='integer', out_type='integer', operator='+'),
223 '-': CInfixDeclaration(name='subtract', in_type='integer', out_type='integer', operator='-'),
224 '*': CInfixDeclaration(name='multiply', in_type='integer', out_type='integer', operator='*'),
225 '//': CInfixDeclaration(name='integerDivide', in_type='integer', out_type='integer', operator='/'),
226 '%': CInfixDeclaration(name='modularDivide', in_type='integer', out_type='integer', operator='%'),
227 'and': CInfixDeclaration(name='and', in_type='boolean', out_type='boolean', operator='&&'),
228 'or': CInfixDeclaration(name='or', in_type='boolean', out_type='boolean', operator='||'),
229 '==': CInfixDeclaration(name='equals', in_type='integer', out_type='boolean', operator='=='),
230 '!=': CInfixDeclaration(name='notEquals', in_type='integer', out_type='boolean', operator='!='),
231 '<=': CInfixDeclaration(name='lessThanOrEqual', in_type='integer', out_type='boolean', operator='<='),
232 '>=': CInfixDeclaration(name='greaterThanOrEqual', in_type='integer', out_type='boolean', operator='>='),
233 '<': CInfixDeclaration(name='lessThan', in_type='integer', out_type='boolean', operator='<'),
234 '>': CInfixDeclaration(name='greaterThan', in_type='integer', out_type='boolean', operator='>'),
237 def transform_comparison_level_expression(accumulators, expression):
238 accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
240 # Transform expressions like 1 < 2 < 3 into expressions like 1 < 2 && 2 < 3
241 if isinstance(expression.left, parsing.FurInfixExpression) and expression.left.order == 'comparison_level':
242 left = transform_comparison_level_expression(
249 right = transform_expression(
254 # TODO Don't evaluate the middle expression twice
255 return CFunctionCallForFurInfixOperator(
258 right=CFunctionCallForFurInfixOperator(
259 name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
265 return CFunctionCallForFurInfixOperator(
266 name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
267 left=transform_expression(accumulators, expression.left),
268 right=transform_expression(accumulators, expression.right),
271 def transform_infix_operator_without_c_equivalent(accumulators, expression):
272 return CFunctionCallForFurInfixOperator(
274 left=transform_expression(accumulators, expression.left),
275 right=transform_expression(accumulators, expression.right),
277 def transform_infix_expression(accumulators, expression):
278 if expression.operator in FUR_INFIX_OPERATOR_TO_C_FUNCTION:
279 return transform_infix_operator_without_c_equivalent(accumulators, expression)
281 if expression.order == 'comparison_level':
282 return transform_comparison_level_expression(accumulators, expression)
284 accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
286 return CFunctionCallForFurInfixOperator(
287 name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
288 left=transform_expression(accumulators, expression.left),
289 right=transform_expression(accumulators, expression.right),
292 def transform_integer_literal_expression(accumulators, expression):
293 return CIntegerLiteral(value=expression.integer)
295 def transform_negation_expression(accumulators, expression):
296 return CNegationExpression(
297 value=transform_expression(accumulators, expression.internal_expression),
300 CListConstructExpression = collections.namedtuple(
301 'CListConstructExpression',
307 CListAppendStatement = collections.namedtuple(
308 'CListAppendStatement',
315 CListGetExpression = collections.namedtuple(
316 'CListGetExpression',
323 def transform_structure_literal_expression(accumulators, expression):
324 return CStructureLiteralExpression(
325 field_count=expression.field_count,
326 symbol_list_variable=expression.symbol_list_variable,
327 value_list_variable=expression.value_list_variable,
330 def transform_dot_expression(accumulators, expression):
332 symbol_list_index = accumulators.symbol_list.index(expression.field)
335 symbol_list_index = len(accumulators.symbol_list)
336 accumulators.symbol_list.append(expression.field)
338 return CDotExpression(
339 instance=transform_variable_expression(accumulators, expression.instance),
340 symbol=expression.field,
341 symbol_list_index=symbol_list_index,
344 def transform_list_construct_expression(accumulators, expression):
345 return CListConstructExpression(allocate=expression.allocate)
347 def transform_list_get_expression(accumulators, expression):
348 return CListGetExpression(
349 list_expression=transform_expression(accumulators, expression.list_expression),
350 index_expression=transform_expression(accumulators, expression.index_expression),
353 def transform_list_append_statement(accumulators, expression):
354 return CListAppendStatement(
355 list_expression=transform_expression(accumulators, expression.list_expression),
356 item_expression=transform_expression(accumulators, expression.item_expression),
359 def transform_expression(accumulators, expression):
360 # TODO Clean up handlers for parsing expressions
362 parsing.FurInfixExpression: transform_infix_expression,
363 parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
364 parsing.FurNegationExpression: transform_negation_expression,
365 parsing.FurStringLiteralExpression: transform_string_literal_expression,
366 normalization.NormalDotExpression: transform_dot_expression,
367 normalization.NormalFunctionCallExpression: transform_function_call_expression,
368 normalization.NormalInfixExpression: transform_infix_expression,
369 normalization.NormalIntegerLiteralExpression: transform_integer_literal_expression,
370 normalization.NormalListConstructExpression: transform_list_construct_expression,
371 normalization.NormalListGetExpression: transform_list_get_expression,
372 normalization.NormalNegationExpression: transform_negation_expression,
373 normalization.NormalStructureLiteralExpression: transform_structure_literal_expression,
374 normalization.NormalStringLiteralExpression: transform_string_literal_expression,
375 normalization.NormalSymbolExpression: transform_symbol_expression,
376 normalization.NormalVariableExpression: transform_variable_expression,
377 }[type(expression)](accumulators, expression)
379 def transform_symbol_assignment_statement(accumulators, assignment_statement):
380 # TODO Check that target is not a builtin
382 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
384 symbol_list_index = len(accumulators.symbol_list)
385 accumulators.symbol_list.append(assignment_statement.target)
387 return CSymbolAssignmentStatement(
388 target=assignment_statement.target,
389 target_symbol_list_index=symbol_list_index,
390 expression=transform_expression(
392 assignment_statement.expression,
396 def transform_function_call_expression(accumulators, function_call):
397 # TODO Use the symbol from SYMBOL LIST
398 return CFunctionCallExpression(
399 function_expression=transform_expression(accumulators, function_call.function_expression),
400 argument_count=function_call.argument_count,
401 argument_items=transform_expression(accumulators, function_call.argument_items),
404 def transform_expression_statement(accumulators, statement):
405 return CExpressionStatement(
406 expression=transform_expression(accumulators, statement.expression),
409 def transform_if_else_statement(accumulators, statement):
410 return CIfElseStatement(
411 condition_expression=transform_expression(accumulators, statement.condition_expression),
412 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
413 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
416 def transform_array_variable_initialization_statement(accumulators, statement):
417 return CArrayVariableInitializationStatement(
418 variable=statement.variable,
419 items=tuple(transform_expression(accumulators, i) for i in statement.items),
422 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
423 symbol_list_indices = []
425 for symbol in statement.symbol_list:
427 symbol_list_index = accumulators.symbol_list.index(symbol)
429 symbol_list_index = len(accumulators.symbol_list)
430 accumulators.symbol_list.append(symbol)
432 symbol_list_indices.append(symbol_list_index)
434 return CSymbolArrayVariableInitializationStatement(
435 variable=statement.variable,
436 symbol_list=statement.symbol_list,
437 symbol_list_indices=tuple(symbol_list_indices),
440 def transform_variable_initialization_statement(accumulators, statement):
441 return CVariableInitializationStatement(
442 variable=statement.variable,
443 expression=transform_expression(accumulators, statement.expression),
446 def transform_variable_reassignment_statement(accumulators, statement):
447 return CVariableReassignmentStatement(
448 variable=statement.variable,
449 expression=transform_expression(accumulators, statement.expression),
452 def transform_function_definition_statement(accumulators, statement):
453 # TODO Allow defining the same function in different contexts
454 if any(fd.name == statement.name for fd in accumulators.function_definition_list):
455 raise Exception('A function with name "{}" already exists'.format(statement.name))
457 # TODO Add argument names to the symbol table
458 accumulators.function_definition_list.append(CFunctionDefinition(
460 argument_name_list=statement.argument_name_list,
461 statement_list=tuple(transform_statement(accumulators, s) for s in statement.statement_list)
464 return CFunctionDeclaration(name=statement.name)
466 def transform_statement(accumulators, statement):
468 parsing.FurExpressionStatement: transform_expression_statement,
469 normalization.NormalArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
470 normalization.NormalAssignmentStatement: transform_symbol_assignment_statement,
471 normalization.NormalExpressionStatement: transform_expression_statement,
472 normalization.NormalFunctionDefinitionStatement: transform_function_definition_statement,
473 normalization.NormalIfElseStatement: transform_if_else_statement,
474 normalization.NormalListAppendStatement: transform_list_append_statement,
475 normalization.NormalSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
476 normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement,
477 normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement,
478 }[type(statement)](accumulators, statement)
481 Accumulators = collections.namedtuple(
485 'function_definition_list',
488 'string_literal_list',
492 def transform(program):
493 accumulators = Accumulators(
495 function_definition_list=[],
498 string_literal_list=[],
502 transform_statement(accumulators, statement) for statement in program.statement_list
505 standard_library_set = set()
506 for builtin in accumulators.builtin_set:
507 for standard_library in BUILTINS[builtin]:
508 standard_library_set.add(standard_library)
511 builtin_set=accumulators.builtin_set,
512 function_definition_list=accumulators.function_definition_list,
513 operator_declarations=tuple(sorted(accumulators.operator_set)),
514 statements=statement_list,
515 standard_libraries=standard_library_set,
516 string_literal_list=accumulators.string_literal_list,
517 symbol_list=accumulators.symbol_list,
521 if __name__ == '__main__':