6 NormalVariableExpression = collections.namedtuple(
7 'NormalVariableExpression',
13 NormalIntegerLiteralExpression = collections.namedtuple(
14 'NormalIntegerLiteralExpression',
20 NormalStringLiteralExpression = collections.namedtuple(
21 'NormalStringLiteralExpression',
27 NormalSymbolExpression = collections.namedtuple(
28 'NormalSymbolExpression',
34 NormalPushStatement = collections.namedtuple(
35 'NormalPushStatement',
41 NormalFunctionCallExpression = collections.namedtuple(
42 'NormalFunctionCallExpression',
45 'function_expression',
50 NormalArrayVariableInitializationStatement = collections.namedtuple(
51 'NormalArrayVariableInitializationStatement',
58 NormalSymbolArrayVariableInitializationStatement = collections.namedtuple(
59 'NormalSymbolArrayVariableInitializationStatement',
66 NormalVariableInitializationStatement = collections.namedtuple(
67 'NormalVariableInitializationStatement',
74 NormalVariableReassignmentStatement = collections.namedtuple(
75 'NormalVariableReassignmentStatement',
82 NormalExpressionStatement = collections.namedtuple(
83 'NormalExpressionStatement',
89 NormalAssignmentStatement = collections.namedtuple(
90 'NormalAssignmentStatement',
97 NormalIfElseStatement = collections.namedtuple(
98 'NormalIfElseStatement',
100 'condition_expression',
102 'else_statement_list',
106 NormalFunctionDefinitionStatement = collections.namedtuple(
107 'NormalFunctionDefinitionStatement',
110 'argument_name_list',
115 NormalProgram = collections.namedtuple(
122 def normalize_integer_literal_expression(counter, expression):
123 variable = '${}'.format(counter)
127 NormalVariableInitializationStatement(
129 expression=NormalIntegerLiteralExpression(integer=expression.integer),
132 NormalVariableExpression(variable=variable),
135 NormalListConstructExpression = collections.namedtuple(
136 'NormalListConstructExpression',
142 NormalListAppendStatement = collections.namedtuple(
143 'NormalListAppendStatement',
150 NormalListGetExpression = collections.namedtuple(
151 'NormalListGetExpression',
158 def normalize_list_literal_expression(counter, expression):
159 list_variable = '${}'.format(counter)
163 NormalVariableInitializationStatement(
164 variable=list_variable,
165 expression=NormalListConstructExpression(allocate=len(expression.item_expression_list)),
169 list_expression = NormalVariableExpression(variable=list_variable)
171 for item_expression in expression.item_expression_list:
172 counter, item_expression_prestatements, normalized = normalize_expression(
177 for p in item_expression_prestatements:
178 prestatements.append(p)
180 prestatements.append(
181 NormalListAppendStatement(
182 list_expression=list_expression,
183 item_expression=normalized,
189 tuple(prestatements),
193 def normalize_list_item_expression(counter, expression):
194 counter, list_prestatements, list_expression = normalize_expression(counter, expression.list_expression)
195 counter, index_prestatements, index_expression = normalize_expression(counter, expression.index_expression)
197 result_variable = '${}'.format(counter)
198 result_prestatement = NormalVariableInitializationStatement(
199 variable=result_variable,
200 expression=NormalListGetExpression(
201 list_expression=list_expression,
202 index_expression=index_expression,
208 list_prestatements + index_prestatements + (result_prestatement,),
209 NormalVariableExpression(variable=result_variable),
212 def normalize_string_literal_expression(counter, expression):
213 variable = '${}'.format(counter)
217 NormalVariableInitializationStatement(
219 expression=NormalStringLiteralExpression(string=expression.string),
222 NormalVariableExpression(variable=variable),
225 NormalStructureLiteralExpression = collections.namedtuple(
226 'NormalStructureLiteralExpression',
229 'symbol_list_variable',
230 'value_list_variable',
234 def normalize_structure_literal_expression(counter, expression):
236 field_symbol_array = []
237 field_value_array = []
239 for symbol_expression_pair in expression.fields:
240 counter, field_prestatements, field_expression = normalize_expression(
242 symbol_expression_pair.expression,
245 for p in field_prestatements:
246 prestatements.append(p)
248 field_symbol_array.append(symbol_expression_pair.symbol)
249 field_value_array.append(field_expression)
251 symbol_array_variable = '${}'.format(counter)
254 prestatements.append(
255 NormalSymbolArrayVariableInitializationStatement(
256 variable=symbol_array_variable,
257 symbol_list=tuple(field_symbol_array),
261 value_array_variable = '${}'.format(counter)
264 prestatements.append(
265 NormalArrayVariableInitializationStatement(
266 variable=value_array_variable,
267 items=tuple(field_value_array),
271 variable = '${}'.format(counter)
273 prestatements.append(
274 NormalVariableInitializationStatement(
276 expression=NormalStructureLiteralExpression(
277 field_count=len(expression.fields),
278 symbol_list_variable=symbol_array_variable,
279 value_list_variable=value_array_variable,
286 tuple(prestatements),
287 NormalVariableExpression(variable=variable),
291 def normalize_symbol_expression(counter, expression):
292 variable = '${}'.format(counter)
296 NormalVariableInitializationStatement(
298 expression=NormalSymbolExpression(symbol=expression.symbol),
301 NormalVariableExpression(variable=variable),
304 def normalize_function_call_expression(counter, expression):
307 for argument in expression.argument_list:
308 counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
310 for s in argument_prestatements:
311 prestatements.append(s)
313 variable = '${}'.format(counter)
314 prestatements.append(
315 NormalVariableInitializationStatement(
317 expression=normalized_argument,
320 prestatements.append(
322 expression=NormalVariableExpression(
329 counter, function_prestatements, function_expression = normalize_expression(
334 for ps in function_prestatements:
335 prestatements.append(ps)
337 if not isinstance(function_expression, NormalVariableExpression):
338 function_variable = '${}'.format(counter)
340 prestatements.append(
341 NormalVariableInitializationStatement(
342 variable=function_variable,
343 expression=function_expression,
347 function_expression = NormalVariableExpression(variable=function_variable)
350 result_variable = '${}'.format(counter)
352 prestatements.append(
353 NormalVariableInitializationStatement(
354 variable=result_variable,
355 expression=NormalFunctionCallExpression(
356 metadata=expression.metadata,
357 function_expression=function_expression,
358 argument_count=len(expression.argument_list),
365 tuple(prestatements),
366 NormalVariableExpression(variable=result_variable),
369 def normalize_if_expression(counter, expression):
370 counter, condition_prestatements, condition_expression = normalize_expression(
372 expression.condition_expression,
375 result_variable = '${}'.format(counter)
378 counter, if_statement_list = normalize_statement_list(
380 expression.if_statement_list,
381 assign_result_to=result_variable,
383 counter, else_statement_list = normalize_statement_list(
385 expression.else_statement_list,
386 assign_result_to=result_variable,
391 condition_prestatements + (
392 NormalVariableInitializationStatement(
393 variable=result_variable,
394 expression=NormalVariableExpression(variable='builtin$nil'),
396 NormalIfElseStatement(
397 condition_expression=condition_expression,
398 if_statement_list=if_statement_list,
399 else_statement_list=else_statement_list,
402 NormalVariableExpression(variable=result_variable),
405 def normalize_expression(counter, expression):
407 desugaring.DesugaredFunctionCallExpression: normalize_function_call_expression,
408 desugaring.DesugaredIfExpression: normalize_if_expression,
409 desugaring.DesugaredIntegerLiteralExpression: normalize_integer_literal_expression,
410 desugaring.DesugaredListLiteralExpression: normalize_list_literal_expression,
411 desugaring.DesugaredStringLiteralExpression: normalize_string_literal_expression,
412 desugaring.DesugaredStructureLiteralExpression: normalize_structure_literal_expression,
413 desugaring.DesugaredSymbolExpression: normalize_symbol_expression,
414 }[type(expression)](counter, expression)
416 def normalize_expression_statement(counter, statement):
417 # TODO Normalized will be a NormalVariableExpression, which will go unused
418 # for expression statements in every case except when it's a return
419 # statement. This cases warnings on C compilation. We should only generate
420 # this variable when it will be used on return.
421 counter, prestatements, normalized = normalize_expression(counter, statement.expression)
426 NormalExpressionStatement(expression=normalized),
429 def normalize_function_definition_statement(counter, statement):
430 _, statement_list = normalize_statement_list(
432 statement.statement_list,
433 assign_result_to='result',
438 NormalFunctionDefinitionStatement(
440 argument_name_list=statement.argument_name_list,
441 statement_list=statement_list,
445 def normalize_assignment_statement(counter, statement):
446 counter, prestatements, normalized_expression = normalize_expression(counter, statement.expression)
450 NormalAssignmentStatement(
451 target=statement.target,
452 expression=normalized_expression,
456 def normalize_statement(counter, statement):
458 desugaring.DesugaredAssignmentStatement: normalize_assignment_statement,
459 desugaring.DesugaredExpressionStatement: normalize_expression_statement,
460 desugaring.DesugaredFunctionDefinitionStatement: normalize_function_definition_statement,
461 }[type(statement)](counter, statement)
463 @util.force_generator(tuple)
464 def normalize_statement_list(counter, statement_list, **kwargs):
465 assign_result_to = kwargs.pop('assign_result_to', None)
467 assert len(kwargs) == 0
469 result_statement_list = []
471 for statement in statement_list:
472 counter, prestatements, normalized = normalize_statement(counter, statement)
473 for s in prestatements:
474 result_statement_list.append(s)
475 result_statement_list.append(normalized)
477 # TODO The way we fix the last statement is really confusing
478 last_statement = result_statement_list[-1]
480 if isinstance(last_statement, NormalExpressionStatement) and isinstance(last_statement.expression, NormalVariableExpression):
481 if assign_result_to is not None:
482 result_expression = result_statement_list.pop().expression
483 result_statement_list.append(
484 NormalVariableReassignmentStatement(
485 variable=assign_result_to,
486 expression=result_expression,
492 result_statement_list,
495 def normalize(program):
496 _, statement_list = normalize_statement_list(0, program.statement_list)
498 return NormalProgram(
499 statement_list=statement_list,