6 NormalVariableExpression = collections.namedtuple(
7 'NormalVariableExpression',
13 NormalIntegerLiteralExpression = collections.namedtuple(
14 'NormalIntegerLiteralExpression',
20 NormalLambdaExpression = collections.namedtuple(
21 'NormalLambdaExpression',
28 NormalStringLiteralExpression = collections.namedtuple(
29 'NormalStringLiteralExpression',
35 NormalSymbolExpression = collections.namedtuple(
36 'NormalSymbolExpression',
42 NormalPushStatement = collections.namedtuple(
43 'NormalPushStatement',
49 NormalFunctionCallExpression = collections.namedtuple(
50 'NormalFunctionCallExpression',
53 'function_expression',
58 NormalArrayVariableInitializationStatement = collections.namedtuple(
59 'NormalArrayVariableInitializationStatement',
66 NormalSymbolArrayVariableInitializationStatement = collections.namedtuple(
67 'NormalSymbolArrayVariableInitializationStatement',
74 NormalVariableInitializationStatement = collections.namedtuple(
75 'NormalVariableInitializationStatement',
82 NormalVariableReassignmentStatement = collections.namedtuple(
83 'NormalVariableReassignmentStatement',
90 NormalExpressionStatement = collections.namedtuple(
91 'NormalExpressionStatement',
97 NormalAssignmentStatement = collections.namedtuple(
98 'NormalAssignmentStatement',
105 NormalIfElseStatement = collections.namedtuple(
106 'NormalIfElseStatement',
108 'condition_expression',
110 'else_statement_list',
114 NormalFunctionDefinitionStatement = collections.namedtuple(
115 'NormalFunctionDefinitionStatement',
118 'argument_name_list',
123 NormalProgram = collections.namedtuple(
130 def normalize_integer_literal_expression(counter, expression):
131 variable = '${}'.format(counter)
135 NormalVariableInitializationStatement(
137 expression=NormalIntegerLiteralExpression(integer=expression.integer),
140 NormalVariableExpression(variable=variable),
143 def normalize_lambda_expression(counter, expression):
144 variable = '${}'.format(counter)
146 _, statement_list = normalize_statement_list(
148 expression.statement_list,
149 assign_result_to='result',
155 NormalVariableInitializationStatement(
157 expression=NormalLambdaExpression(
158 argument_name_list=expression.argument_name_list,
159 statement_list=statement_list,
163 NormalVariableExpression(variable=variable),
166 NormalListConstructExpression = collections.namedtuple(
167 'NormalListConstructExpression',
173 NormalListAppendStatement = collections.namedtuple(
174 'NormalListAppendStatement',
181 def normalize_list_literal_expression(counter, expression):
182 list_variable = '${}'.format(counter)
186 NormalVariableInitializationStatement(
187 variable=list_variable,
188 expression=NormalListConstructExpression(allocate=len(expression.item_expression_list)),
192 list_expression = NormalVariableExpression(variable=list_variable)
194 for item_expression in expression.item_expression_list:
195 counter, item_expression_prestatements, normalized = normalize_expression(
200 for p in item_expression_prestatements:
201 prestatements.append(p)
203 prestatements.append(
204 NormalListAppendStatement(
205 list_expression=list_expression,
206 item_expression=normalized,
212 tuple(prestatements),
216 def normalize_string_literal_expression(counter, expression):
217 variable = '${}'.format(counter)
221 NormalVariableInitializationStatement(
223 expression=NormalStringLiteralExpression(string=expression.string),
226 NormalVariableExpression(variable=variable),
229 NormalStructureLiteralExpression = collections.namedtuple(
230 'NormalStructureLiteralExpression',
233 'symbol_list_variable',
234 'value_list_variable',
238 def normalize_structure_literal_expression(counter, expression):
240 field_symbol_array = []
241 field_value_array = []
243 for symbol_expression_pair in expression.fields:
244 counter, field_prestatements, field_expression = normalize_expression(
246 symbol_expression_pair.expression,
249 for p in field_prestatements:
250 prestatements.append(p)
252 field_symbol_array.append(symbol_expression_pair.symbol)
253 field_value_array.append(field_expression)
255 symbol_array_variable = '${}'.format(counter)
258 prestatements.append(
259 NormalSymbolArrayVariableInitializationStatement(
260 variable=symbol_array_variable,
261 symbol_list=tuple(field_symbol_array),
265 value_array_variable = '${}'.format(counter)
268 prestatements.append(
269 NormalArrayVariableInitializationStatement(
270 variable=value_array_variable,
271 items=tuple(field_value_array),
275 variable = '${}'.format(counter)
277 prestatements.append(
278 NormalVariableInitializationStatement(
280 expression=NormalStructureLiteralExpression(
281 field_count=len(expression.fields),
282 symbol_list_variable=symbol_array_variable,
283 value_list_variable=value_array_variable,
290 tuple(prestatements),
291 NormalVariableExpression(variable=variable),
295 def normalize_symbol_expression(counter, expression):
296 variable = '${}'.format(counter)
300 NormalVariableInitializationStatement(
302 expression=NormalSymbolExpression(symbol=expression.symbol),
305 NormalVariableExpression(variable=variable),
308 def normalize_function_call_expression(counter, expression):
311 for argument in expression.argument_list:
312 counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
314 for s in argument_prestatements:
315 prestatements.append(s)
317 variable = '${}'.format(counter)
318 prestatements.append(
319 NormalVariableInitializationStatement(
321 expression=normalized_argument,
324 prestatements.append(
326 expression=NormalVariableExpression(
333 counter, function_prestatements, function_expression = normalize_expression(
338 for ps in function_prestatements:
339 prestatements.append(ps)
341 if not isinstance(function_expression, NormalVariableExpression):
342 function_variable = '${}'.format(counter)
344 prestatements.append(
345 NormalVariableInitializationStatement(
346 variable=function_variable,
347 expression=function_expression,
351 function_expression = NormalVariableExpression(variable=function_variable)
354 result_variable = '${}'.format(counter)
356 prestatements.append(
357 NormalVariableInitializationStatement(
358 variable=result_variable,
359 expression=NormalFunctionCallExpression(
360 metadata=expression.metadata,
361 function_expression=function_expression,
362 argument_count=len(expression.argument_list),
369 tuple(prestatements),
370 NormalVariableExpression(variable=result_variable),
373 def normalize_if_expression(counter, expression):
374 counter, condition_prestatements, condition_expression = normalize_expression(
376 expression.condition_expression,
379 result_variable = '${}'.format(counter)
382 counter, if_statement_list = normalize_statement_list(
384 expression.if_statement_list,
385 assign_result_to=result_variable,
387 counter, else_statement_list = normalize_statement_list(
389 expression.else_statement_list,
390 assign_result_to=result_variable,
395 condition_prestatements + (
396 NormalVariableInitializationStatement(
397 variable=result_variable,
398 expression=NormalVariableExpression(variable='builtin$nil'),
400 NormalIfElseStatement(
401 condition_expression=condition_expression,
402 if_statement_list=if_statement_list,
403 else_statement_list=else_statement_list,
406 NormalVariableExpression(variable=result_variable),
409 def normalize_expression(counter, expression):
411 desugaring.DesugaredFunctionCallExpression: normalize_function_call_expression,
412 desugaring.DesugaredIfExpression: normalize_if_expression,
413 desugaring.DesugaredIntegerLiteralExpression: normalize_integer_literal_expression,
414 desugaring.DesugaredLambdaExpression: normalize_lambda_expression,
415 desugaring.DesugaredListLiteralExpression: normalize_list_literal_expression,
416 desugaring.DesugaredStringLiteralExpression: normalize_string_literal_expression,
417 desugaring.DesugaredStructureLiteralExpression: normalize_structure_literal_expression,
418 desugaring.DesugaredSymbolExpression: normalize_symbol_expression,
419 }[type(expression)](counter, expression)
421 def normalize_expression_statement(counter, statement):
422 # TODO Normalized will be a NormalVariableExpression, which will go unused
423 # for expression statements in every case except when it's a return
424 # statement. This cases warnings on C compilation. We should only generate
425 # this variable when it will be used on return.
426 counter, prestatements, normalized = normalize_expression(counter, statement.expression)
431 NormalExpressionStatement(expression=normalized),
434 def normalize_function_definition_statement(counter, statement):
435 _, statement_list = normalize_statement_list(
437 statement.statement_list,
438 assign_result_to='result',
443 NormalFunctionDefinitionStatement(
445 argument_name_list=statement.argument_name_list,
446 statement_list=statement_list,
450 def normalize_assignment_statement(counter, statement):
451 counter, prestatements, normalized_expression = normalize_expression(counter, statement.expression)
455 NormalAssignmentStatement(
456 target=statement.target,
457 expression=normalized_expression,
461 def normalize_statement(counter, statement):
463 desugaring.DesugaredAssignmentStatement: normalize_assignment_statement,
464 desugaring.DesugaredExpressionStatement: normalize_expression_statement,
465 desugaring.DesugaredFunctionDefinitionStatement: normalize_function_definition_statement,
466 }[type(statement)](counter, statement)
468 @util.force_generator(tuple)
469 def normalize_statement_list(counter, statement_list, **kwargs):
470 assign_result_to = kwargs.pop('assign_result_to', None)
472 assert len(kwargs) == 0
474 result_statement_list = []
476 for statement in statement_list:
477 counter, prestatements, normalized = normalize_statement(counter, statement)
478 for s in prestatements:
479 result_statement_list.append(s)
480 result_statement_list.append(normalized)
482 # TODO The way we fix the last statement is really confusing
483 last_statement = result_statement_list[-1]
485 if isinstance(last_statement, NormalExpressionStatement) and isinstance(last_statement.expression, NormalVariableExpression):
486 if assign_result_to is not None:
487 result_expression = result_statement_list.pop().expression
488 result_statement_list.append(
489 NormalVariableReassignmentStatement(
490 variable=assign_result_to,
491 expression=result_expression,
497 result_statement_list,
500 def normalize(program):
501 _, statement_list = normalize_statement_list(0, program.statement_list)
503 return NormalProgram(
504 statement_list=statement_list,