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 def normalize_list_literal_expression(counter, expression):
151 list_variable = '${}'.format(counter)
155 NormalVariableInitializationStatement(
156 variable=list_variable,
157 expression=NormalListConstructExpression(allocate=len(expression.item_expression_list)),
161 list_expression = NormalVariableExpression(variable=list_variable)
163 for item_expression in expression.item_expression_list:
164 counter, item_expression_prestatements, normalized = normalize_expression(
169 for p in item_expression_prestatements:
170 prestatements.append(p)
172 prestatements.append(
173 NormalListAppendStatement(
174 list_expression=list_expression,
175 item_expression=normalized,
181 tuple(prestatements),
185 def normalize_string_literal_expression(counter, expression):
186 variable = '${}'.format(counter)
190 NormalVariableInitializationStatement(
192 expression=NormalStringLiteralExpression(string=expression.string),
195 NormalVariableExpression(variable=variable),
198 NormalStructureLiteralExpression = collections.namedtuple(
199 'NormalStructureLiteralExpression',
202 'symbol_list_variable',
203 'value_list_variable',
207 def normalize_structure_literal_expression(counter, expression):
209 field_symbol_array = []
210 field_value_array = []
212 for symbol_expression_pair in expression.fields:
213 counter, field_prestatements, field_expression = normalize_expression(
215 symbol_expression_pair.expression,
218 for p in field_prestatements:
219 prestatements.append(p)
221 field_symbol_array.append(symbol_expression_pair.symbol)
222 field_value_array.append(field_expression)
224 symbol_array_variable = '${}'.format(counter)
227 prestatements.append(
228 NormalSymbolArrayVariableInitializationStatement(
229 variable=symbol_array_variable,
230 symbol_list=tuple(field_symbol_array),
234 value_array_variable = '${}'.format(counter)
237 prestatements.append(
238 NormalArrayVariableInitializationStatement(
239 variable=value_array_variable,
240 items=tuple(field_value_array),
244 variable = '${}'.format(counter)
246 prestatements.append(
247 NormalVariableInitializationStatement(
249 expression=NormalStructureLiteralExpression(
250 field_count=len(expression.fields),
251 symbol_list_variable=symbol_array_variable,
252 value_list_variable=value_array_variable,
259 tuple(prestatements),
260 NormalVariableExpression(variable=variable),
264 def normalize_symbol_expression(counter, expression):
265 variable = '${}'.format(counter)
269 NormalVariableInitializationStatement(
271 expression=NormalSymbolExpression(symbol=expression.symbol),
274 NormalVariableExpression(variable=variable),
277 def normalize_function_call_expression(counter, expression):
280 for argument in expression.argument_list:
281 counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
283 for s in argument_prestatements:
284 prestatements.append(s)
286 variable = '${}'.format(counter)
287 prestatements.append(
288 NormalVariableInitializationStatement(
290 expression=normalized_argument,
293 prestatements.append(
295 expression=NormalVariableExpression(
302 counter, function_prestatements, function_expression = normalize_expression(
307 for ps in function_prestatements:
308 prestatements.append(ps)
310 if not isinstance(function_expression, NormalVariableExpression):
311 function_variable = '${}'.format(counter)
313 prestatements.append(
314 NormalVariableInitializationStatement(
315 variable=function_variable,
316 expression=function_expression,
320 function_expression = NormalVariableExpression(variable=function_variable)
323 result_variable = '${}'.format(counter)
325 prestatements.append(
326 NormalVariableInitializationStatement(
327 variable=result_variable,
328 expression=NormalFunctionCallExpression(
329 metadata=expression.metadata,
330 function_expression=function_expression,
331 argument_count=len(expression.argument_list),
338 tuple(prestatements),
339 NormalVariableExpression(variable=result_variable),
342 def normalize_if_expression(counter, expression):
343 counter, condition_prestatements, condition_expression = normalize_expression(
345 expression.condition_expression,
348 result_variable = '${}'.format(counter)
351 counter, if_statement_list = normalize_statement_list(
353 expression.if_statement_list,
354 assign_result_to=result_variable,
356 counter, else_statement_list = normalize_statement_list(
358 expression.else_statement_list,
359 assign_result_to=result_variable,
364 condition_prestatements + (
365 NormalVariableInitializationStatement(
366 variable=result_variable,
367 expression=NormalVariableExpression(variable='builtin$nil'),
369 NormalIfElseStatement(
370 condition_expression=condition_expression,
371 if_statement_list=if_statement_list,
372 else_statement_list=else_statement_list,
375 NormalVariableExpression(variable=result_variable),
378 def normalize_expression(counter, expression):
380 desugaring.DesugaredFunctionCallExpression: normalize_function_call_expression,
381 desugaring.DesugaredIfExpression: normalize_if_expression,
382 desugaring.DesugaredIntegerLiteralExpression: normalize_integer_literal_expression,
383 desugaring.DesugaredListLiteralExpression: normalize_list_literal_expression,
384 desugaring.DesugaredStringLiteralExpression: normalize_string_literal_expression,
385 desugaring.DesugaredStructureLiteralExpression: normalize_structure_literal_expression,
386 desugaring.DesugaredSymbolExpression: normalize_symbol_expression,
387 }[type(expression)](counter, expression)
389 def normalize_expression_statement(counter, statement):
390 # TODO Normalized will be a NormalVariableExpression, which will go unused
391 # for expression statements in every case except when it's a return
392 # statement. This cases warnings on C compilation. We should only generate
393 # this variable when it will be used on return.
394 counter, prestatements, normalized = normalize_expression(counter, statement.expression)
399 NormalExpressionStatement(expression=normalized),
402 def normalize_function_definition_statement(counter, statement):
403 _, statement_list = normalize_statement_list(
405 statement.statement_list,
406 assign_result_to='result',
411 NormalFunctionDefinitionStatement(
413 argument_name_list=statement.argument_name_list,
414 statement_list=statement_list,
418 def normalize_assignment_statement(counter, statement):
419 counter, prestatements, normalized_expression = normalize_expression(counter, statement.expression)
423 NormalAssignmentStatement(
424 target=statement.target,
425 expression=normalized_expression,
429 def normalize_statement(counter, statement):
431 desugaring.DesugaredAssignmentStatement: normalize_assignment_statement,
432 desugaring.DesugaredExpressionStatement: normalize_expression_statement,
433 desugaring.DesugaredFunctionDefinitionStatement: normalize_function_definition_statement,
434 }[type(statement)](counter, statement)
436 @util.force_generator(tuple)
437 def normalize_statement_list(counter, statement_list, **kwargs):
438 assign_result_to = kwargs.pop('assign_result_to', None)
440 assert len(kwargs) == 0
442 result_statement_list = []
444 for statement in statement_list:
445 counter, prestatements, normalized = normalize_statement(counter, statement)
446 for s in prestatements:
447 result_statement_list.append(s)
448 result_statement_list.append(normalized)
450 # TODO The way we fix the last statement is really confusing
451 last_statement = result_statement_list[-1]
453 if isinstance(last_statement, NormalExpressionStatement) and isinstance(last_statement.expression, NormalVariableExpression):
454 if assign_result_to is not None:
455 result_expression = result_statement_list.pop().expression
456 result_statement_list.append(
457 NormalVariableReassignmentStatement(
458 variable=assign_result_to,
459 expression=result_expression,
465 result_statement_list,
468 def normalize(program):
469 _, statement_list = normalize_statement_list(0, program.statement_list)
471 return NormalProgram(
472 statement_list=statement_list,