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',
69 CPushStatement = collections.namedtuple(
76 CFunctionCallExpression = collections.namedtuple(
77 'CFunctionCallExpression',
79 'function_expression',
84 # TODO We are currently not changing variables, just preventing them from being accessed.
85 CSymbolAssignmentStatement = collections.namedtuple(
86 'CSymbolAssignmentStatement',
89 'target_symbol_list_index',
94 CArrayVariableInitializationStatement = collections.namedtuple(
95 'CArrayVariableInitializationStatement',
102 CSymbolArrayVariableInitializationStatement = collections.namedtuple(
103 'CSymbolArrayVariableInitializationStatement',
107 'symbol_list_indices',
111 CVariableInitializationStatement = collections.namedtuple(
112 'CVariableInitializationStatement',
119 CVariableReassignmentStatement = collections.namedtuple(
120 'CVariableReassignmentStatement',
127 CExpressionStatement = collections.namedtuple(
128 'CExpressionStatement',
134 CIfElseStatement = collections.namedtuple(
137 'condition_expression',
139 'else_statement_list',
143 CFunctionDeclaration = collections.namedtuple(
144 'CFunctionDeclaration',
150 # TODO If a function definition doesn't end with an expression, we have issues currently because we try to return statement.
151 # TODO Closures currently wrap entire defining environment, even symbols that are not used, which makes garbage collection ineffective.
152 CFunctionDefinition = collections.namedtuple(
153 'CFunctionDefinition',
156 'argument_name_list',
161 CProgram = collections.namedtuple(
165 'function_definition_list',
166 'operator_declarations',
168 'standard_libraries',
169 'string_literal_list',
178 'print': ['stdio.h'],
182 def transform_variable_expression(accumulators, expression):
183 assert isinstance(expression, normalization.NormalVariableExpression)
184 return CVariableExpression(variable=expression.variable)
186 def transform_string_literal_expression(accumulators, expression):
187 value = expression.string
190 index = accumulators.string_literal_list.index(value)
192 index = len(accumulators.string_literal_list)
193 accumulators.string_literal_list.append(value)
195 return CStringLiteral(index=index, value=value)
197 def transform_symbol_expression(accumulators, expression):
198 if expression.symbol in BUILTINS:
199 accumulators.builtin_set.add(expression.symbol)
202 symbol_list_index = accumulators.symbol_list.index(expression.symbol)
204 symbol_list_index = len(accumulators.symbol_list)
205 accumulators.symbol_list.append(expression.symbol)
207 return CSymbolExpression(
208 symbol=expression.symbol,
209 symbol_list_index=symbol_list_index,
212 CInfixDeclaration = collections.namedtuple(
222 FUR_INFIX_OPERATOR_TO_C_FUNCTION = {
226 FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = {
227 '+': CInfixDeclaration(name='add', in_type='integer', out_type='integer', operator='+'),
228 '-': CInfixDeclaration(name='subtract', in_type='integer', out_type='integer', operator='-'),
229 '*': CInfixDeclaration(name='multiply', in_type='integer', out_type='integer', operator='*'),
230 '//': CInfixDeclaration(name='integerDivide', in_type='integer', out_type='integer', operator='/'),
231 '%': CInfixDeclaration(name='modularDivide', in_type='integer', out_type='integer', operator='%'),
232 'and': CInfixDeclaration(name='and', in_type='boolean', out_type='boolean', operator='&&'),
233 'or': CInfixDeclaration(name='or', in_type='boolean', out_type='boolean', operator='||'),
234 '==': CInfixDeclaration(name='equals', in_type='integer', out_type='boolean', operator='=='),
235 '!=': CInfixDeclaration(name='notEquals', in_type='integer', out_type='boolean', operator='!='),
236 '<=': CInfixDeclaration(name='lessThanOrEqual', in_type='integer', out_type='boolean', operator='<='),
237 '>=': CInfixDeclaration(name='greaterThanOrEqual', in_type='integer', out_type='boolean', operator='>='),
238 '<': CInfixDeclaration(name='lessThan', in_type='integer', out_type='boolean', operator='<'),
239 '>': CInfixDeclaration(name='greaterThan', in_type='integer', out_type='boolean', operator='>'),
242 def transform_infix_operator_without_c_equivalent(accumulators, expression):
243 return CFunctionCallForFurInfixOperator(
244 metadata=expression.metadata,
248 def transform_infix_expression(accumulators, expression):
249 if expression.operator in FUR_INFIX_OPERATOR_TO_C_FUNCTION:
250 return transform_infix_operator_without_c_equivalent(accumulators, expression)
252 accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
254 return CFunctionCallForFurInfixOperator(
255 metadata=expression.metadata,
256 name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
259 def transform_integer_literal_expression(accumulators, expression):
260 return CIntegerLiteral(value=expression.integer)
262 def transform_negation_expression(accumulators, expression):
263 return CNegationExpression(
264 value=transform_expression(accumulators, expression.internal_expression),
267 CListConstructExpression = collections.namedtuple(
268 'CListConstructExpression',
274 CListAppendStatement = collections.namedtuple(
275 'CListAppendStatement',
282 CListGetExpression = collections.namedtuple(
283 'CListGetExpression',
290 def transform_structure_literal_expression(accumulators, expression):
291 return CStructureLiteralExpression(
292 field_count=expression.field_count,
293 symbol_list_variable=expression.symbol_list_variable,
294 value_list_variable=expression.value_list_variable,
297 def transform_dot_expression(accumulators, expression):
299 symbol_list_index = accumulators.symbol_list.index(expression.field)
302 symbol_list_index = len(accumulators.symbol_list)
303 accumulators.symbol_list.append(expression.field)
305 return CDotExpression(
306 instance=transform_variable_expression(accumulators, expression.instance),
307 symbol=expression.field,
308 symbol_list_index=symbol_list_index,
311 def transform_list_construct_expression(accumulators, expression):
312 return CListConstructExpression(allocate=expression.allocate)
314 def transform_list_get_expression(accumulators, expression):
315 return CListGetExpression(
316 list_expression=transform_expression(accumulators, expression.list_expression),
317 index_expression=transform_expression(accumulators, expression.index_expression),
320 def transform_list_append_statement(accumulators, expression):
321 return CListAppendStatement(
322 list_expression=transform_expression(accumulators, expression.list_expression),
323 item_expression=transform_expression(accumulators, expression.item_expression),
326 def transform_expression(accumulators, expression):
327 # TODO Clean up handlers for parsing expressions
329 parsing.FurInfixExpression: transform_infix_expression,
330 parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
331 parsing.FurNegationExpression: transform_negation_expression,
332 parsing.FurStringLiteralExpression: transform_string_literal_expression,
333 normalization.NormalDotExpression: transform_dot_expression,
334 normalization.NormalFunctionCallExpression: transform_function_call_expression,
335 normalization.NormalInfixExpression: transform_infix_expression,
336 normalization.NormalIntegerLiteralExpression: transform_integer_literal_expression,
337 normalization.NormalListConstructExpression: transform_list_construct_expression,
338 normalization.NormalListGetExpression: transform_list_get_expression,
339 normalization.NormalNegationExpression: transform_negation_expression,
340 normalization.NormalStructureLiteralExpression: transform_structure_literal_expression,
341 normalization.NormalStringLiteralExpression: transform_string_literal_expression,
342 normalization.NormalSymbolExpression: transform_symbol_expression,
343 normalization.NormalVariableExpression: transform_variable_expression,
344 }[type(expression)](accumulators, expression)
346 def transform_symbol_assignment_statement(accumulators, assignment_statement):
347 # TODO Check that target is not a builtin
349 symbol_list_index = accumulators.symbol_list.index(assignment_statement.target)
351 symbol_list_index = len(accumulators.symbol_list)
352 accumulators.symbol_list.append(assignment_statement.target)
354 return CSymbolAssignmentStatement(
355 target=assignment_statement.target,
356 target_symbol_list_index=symbol_list_index,
357 expression=transform_expression(
359 assignment_statement.expression,
363 def transform_function_call_expression(accumulators, function_call):
364 # TODO Use the symbol from SYMBOL LIST
365 return CFunctionCallExpression(
366 function_expression=transform_expression(accumulators, function_call.function_expression),
367 argument_count=function_call.argument_count,
370 def transform_expression_statement(accumulators, statement):
371 return CExpressionStatement(
372 expression=transform_expression(accumulators, statement.expression),
375 def transform_if_else_statement(accumulators, statement):
376 return CIfElseStatement(
377 condition_expression=transform_expression(accumulators, statement.condition_expression),
378 if_statement_list=tuple(transform_statement(accumulators, s) for s in statement.if_statement_list),
379 else_statement_list=tuple(transform_statement(accumulators, s) for s in statement.else_statement_list),
382 def transform_array_variable_initialization_statement(accumulators, statement):
383 return CArrayVariableInitializationStatement(
384 variable=statement.variable,
385 items=tuple(transform_expression(accumulators, i) for i in statement.items),
388 def transform_symbol_array_variable_initialization_statement(accumulators, statement):
389 symbol_list_indices = []
391 for symbol in statement.symbol_list:
393 symbol_list_index = accumulators.symbol_list.index(symbol)
395 symbol_list_index = len(accumulators.symbol_list)
396 accumulators.symbol_list.append(symbol)
398 symbol_list_indices.append(symbol_list_index)
400 return CSymbolArrayVariableInitializationStatement(
401 variable=statement.variable,
402 symbol_list=statement.symbol_list,
403 symbol_list_indices=tuple(symbol_list_indices),
406 def transform_variable_initialization_statement(accumulators, statement):
407 return CVariableInitializationStatement(
408 variable=statement.variable,
409 expression=transform_expression(accumulators, statement.expression),
412 def transform_variable_reassignment_statement(accumulators, statement):
413 return CVariableReassignmentStatement(
414 variable=statement.variable,
415 expression=transform_expression(accumulators, statement.expression),
418 def transform_function_definition_statement(accumulators, statement):
419 # TODO Allow defining the same function in different contexts
420 if any(fd.name == statement.name for fd in accumulators.function_definition_list):
421 raise Exception('A function with name "{}" already exists'.format(statement.name))
423 # TODO Add argument names to the symbol table
424 accumulators.function_definition_list.append(CFunctionDefinition(
426 argument_name_list=statement.argument_name_list,
427 statement_list=tuple(transform_statement(accumulators, s) for s in statement.statement_list)
430 return CFunctionDeclaration(name=statement.name)
432 def transform_push_statement(accumulators, statement):
433 return CPushStatement(expression=transform_expression(accumulators, statement.expression))
435 def transform_statement(accumulators, statement):
437 parsing.FurExpressionStatement: transform_expression_statement,
438 normalization.NormalArrayVariableInitializationStatement: transform_array_variable_initialization_statement,
439 normalization.NormalAssignmentStatement: transform_symbol_assignment_statement,
440 normalization.NormalExpressionStatement: transform_expression_statement,
441 normalization.NormalFunctionDefinitionStatement: transform_function_definition_statement,
442 normalization.NormalIfElseStatement: transform_if_else_statement,
443 normalization.NormalListAppendStatement: transform_list_append_statement,
444 normalization.NormalPushStatement: transform_push_statement,
445 normalization.NormalSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
446 normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement,
447 normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement,
448 }[type(statement)](accumulators, statement)
451 Accumulators = collections.namedtuple(
455 'function_definition_list',
458 'string_literal_list',
462 def transform(program):
463 accumulators = Accumulators(
465 function_definition_list=[],
468 string_literal_list=[],
472 transform_statement(accumulators, statement) for statement in program.statement_list
475 standard_library_set = set()
476 for builtin in accumulators.builtin_set:
477 for standard_library in BUILTINS[builtin]:
478 standard_library_set.add(standard_library)
481 builtin_set=accumulators.builtin_set,
482 function_definition_list=accumulators.function_definition_list,
483 operator_declarations=tuple(sorted(accumulators.operator_set)),
484 statements=statement_list,
485 standard_libraries=standard_library_set,
486 string_literal_list=accumulators.string_literal_list,
487 symbol_list=accumulators.symbol_list,
491 if __name__ == '__main__':