6 NormalVariableExpression = collections.namedtuple(
7 'NormalVariableExpression',
13 NormalIntegerLiteralExpression = collections.namedtuple(
14 'NormalIntegerLiteralExpression',
20 NormalLambdaExpression = collections.namedtuple(
21 'NormalLambdaExpression',
29 NormalStringLiteralExpression = collections.namedtuple(
30 'NormalStringLiteralExpression',
36 NormalSymbolExpression = collections.namedtuple(
37 'NormalSymbolExpression',
43 NormalPushStatement = collections.namedtuple(
44 'NormalPushStatement',
50 NormalFunctionCallExpression = collections.namedtuple(
51 'NormalFunctionCallExpression',
54 'function_expression',
59 NormalArrayVariableInitializationStatement = collections.namedtuple(
60 'NormalArrayVariableInitializationStatement',
67 NormalSymbolArrayVariableInitializationStatement = collections.namedtuple(
68 'NormalSymbolArrayVariableInitializationStatement',
75 NormalVariableInitializationStatement = collections.namedtuple(
76 'NormalVariableInitializationStatement',
83 NormalVariableReassignmentStatement = collections.namedtuple(
84 'NormalVariableReassignmentStatement',
91 NormalExpressionStatement = collections.namedtuple(
92 'NormalExpressionStatement',
98 NormalAssignmentStatement = collections.namedtuple(
99 'NormalAssignmentStatement',
106 NormalIfElseStatement = collections.namedtuple(
107 'NormalIfElseStatement',
109 'condition_expression',
111 'else_statement_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 def normalize_lambda_expression(counter, expression):
136 variable = '${}'.format(counter)
138 _, statement_list = normalize_statement_list(
140 expression.statement_list,
141 assign_result_to='result',
147 NormalVariableInitializationStatement(
149 expression=NormalLambdaExpression(
150 name=expression.name,
151 argument_name_list=expression.argument_name_list,
152 statement_list=statement_list,
156 NormalVariableExpression(variable=variable),
159 NormalListConstructExpression = collections.namedtuple(
160 'NormalListConstructExpression',
166 NormalListAppendStatement = collections.namedtuple(
167 'NormalListAppendStatement',
174 def normalize_list_literal_expression(counter, expression):
175 list_variable = '${}'.format(counter)
179 NormalVariableInitializationStatement(
180 variable=list_variable,
181 expression=NormalListConstructExpression(allocate=len(expression.item_expression_list)),
185 list_expression = NormalVariableExpression(variable=list_variable)
187 for item_expression in expression.item_expression_list:
188 counter, item_expression_prestatements, normalized = normalize_expression(
193 for p in item_expression_prestatements:
194 prestatements.append(p)
196 prestatements.append(
197 NormalListAppendStatement(
198 list_expression=list_expression,
199 item_expression=normalized,
205 tuple(prestatements),
209 def normalize_string_literal_expression(counter, expression):
210 variable = '${}'.format(counter)
214 NormalVariableInitializationStatement(
216 expression=NormalStringLiteralExpression(string=expression.string),
219 NormalVariableExpression(variable=variable),
222 NormalStructureLiteralExpression = collections.namedtuple(
223 'NormalStructureLiteralExpression',
226 'symbol_list_variable',
227 'value_list_variable',
231 def normalize_structure_literal_expression(counter, expression):
233 field_symbol_array = []
234 field_value_array = []
236 for symbol_expression_pair in expression.fields:
237 counter, field_prestatements, field_expression = normalize_expression(
239 symbol_expression_pair.expression,
242 for p in field_prestatements:
243 prestatements.append(p)
245 field_symbol_array.append(symbol_expression_pair.symbol)
246 field_value_array.append(field_expression)
248 symbol_array_variable = '${}'.format(counter)
251 prestatements.append(
252 NormalSymbolArrayVariableInitializationStatement(
253 variable=symbol_array_variable,
254 symbol_list=tuple(field_symbol_array),
258 value_array_variable = '${}'.format(counter)
261 prestatements.append(
262 NormalArrayVariableInitializationStatement(
263 variable=value_array_variable,
264 items=tuple(field_value_array),
268 variable = '${}'.format(counter)
270 prestatements.append(
271 NormalVariableInitializationStatement(
273 expression=NormalStructureLiteralExpression(
274 field_count=len(expression.fields),
275 symbol_list_variable=symbol_array_variable,
276 value_list_variable=value_array_variable,
283 tuple(prestatements),
284 NormalVariableExpression(variable=variable),
288 def normalize_symbol_expression(counter, expression):
289 variable = '${}'.format(counter)
293 NormalVariableInitializationStatement(
295 expression=NormalSymbolExpression(symbol=expression.symbol),
298 NormalVariableExpression(variable=variable),
301 def normalize_function_call_expression(counter, expression):
304 for argument in expression.argument_list:
305 counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
307 for s in argument_prestatements:
308 prestatements.append(s)
310 variable = '${}'.format(counter)
311 prestatements.append(
312 NormalVariableInitializationStatement(
314 expression=normalized_argument,
317 prestatements.append(
319 expression=NormalVariableExpression(
326 counter, function_prestatements, function_expression = normalize_expression(
331 for ps in function_prestatements:
332 prestatements.append(ps)
334 if not isinstance(function_expression, NormalVariableExpression):
335 function_variable = '${}'.format(counter)
337 prestatements.append(
338 NormalVariableInitializationStatement(
339 variable=function_variable,
340 expression=function_expression,
344 function_expression = NormalVariableExpression(variable=function_variable)
347 result_variable = '${}'.format(counter)
349 prestatements.append(
350 NormalVariableInitializationStatement(
351 variable=result_variable,
352 expression=NormalFunctionCallExpression(
353 metadata=expression.metadata,
354 function_expression=function_expression,
355 argument_count=len(expression.argument_list),
362 tuple(prestatements),
363 NormalVariableExpression(variable=result_variable),
366 def normalize_if_expression(counter, expression):
367 counter, condition_prestatements, condition_expression = normalize_expression(
369 expression.condition_expression,
372 result_variable = '${}'.format(counter)
375 counter, if_statement_list = normalize_statement_list(
377 expression.if_statement_list,
378 assign_result_to=result_variable,
380 counter, else_statement_list = normalize_statement_list(
382 expression.else_statement_list,
383 assign_result_to=result_variable,
388 condition_prestatements + (
389 NormalVariableInitializationStatement(
390 variable=result_variable,
391 expression=NormalVariableExpression(variable='builtin$nil'),
393 NormalIfElseStatement(
394 condition_expression=condition_expression,
395 if_statement_list=if_statement_list,
396 else_statement_list=else_statement_list,
399 NormalVariableExpression(variable=result_variable),
402 def normalize_expression(counter, expression):
404 desugaring.DesugaredFunctionCallExpression: normalize_function_call_expression,
405 desugaring.DesugaredIfExpression: normalize_if_expression,
406 desugaring.DesugaredIntegerLiteralExpression: normalize_integer_literal_expression,
407 desugaring.DesugaredLambdaExpression: normalize_lambda_expression,
408 desugaring.DesugaredListLiteralExpression: normalize_list_literal_expression,
409 desugaring.DesugaredStringLiteralExpression: normalize_string_literal_expression,
410 desugaring.DesugaredStructureLiteralExpression: normalize_structure_literal_expression,
411 desugaring.DesugaredSymbolExpression: normalize_symbol_expression,
412 }[type(expression)](counter, expression)
414 def normalize_expression_statement(counter, statement):
415 # TODO Normalized will be a NormalVariableExpression, which will go unused
416 # for expression statements in every case except when it's a return
417 # statement. This cases warnings on C compilation. We should only generate
418 # this variable when it will be used on return.
419 counter, prestatements, normalized = normalize_expression(counter, statement.expression)
424 NormalExpressionStatement(expression=normalized),
427 def normalize_assignment_statement(counter, statement):
428 counter, prestatements, normalized_expression = normalize_expression(counter, statement.expression)
432 NormalAssignmentStatement(
433 target=statement.target,
434 expression=normalized_expression,
438 def normalize_statement(counter, statement):
440 desugaring.DesugaredAssignmentStatement: normalize_assignment_statement,
441 desugaring.DesugaredExpressionStatement: normalize_expression_statement,
442 }[type(statement)](counter, statement)
444 @util.force_generator(tuple)
445 def normalize_statement_list(counter, statement_list, **kwargs):
446 assign_result_to = kwargs.pop('assign_result_to', None)
448 assert len(kwargs) == 0
450 result_statement_list = []
452 for statement in statement_list:
453 counter, prestatements, normalized = normalize_statement(counter, statement)
454 for s in prestatements:
455 result_statement_list.append(s)
456 result_statement_list.append(normalized)
458 # TODO The way we fix the last statement is really confusing
459 last_statement = result_statement_list[-1]
461 if isinstance(last_statement, NormalExpressionStatement) and isinstance(last_statement.expression, NormalVariableExpression):
462 if assign_result_to is not None:
463 result_expression = result_statement_list.pop().expression
464 result_statement_list.append(
465 NormalVariableReassignmentStatement(
466 variable=assign_result_to,
467 expression=result_expression,
473 result_statement_list,
476 def normalize(program):
477 _, statement_list = normalize_statement_list(0, program.statement_list)
479 return NormalProgram(
480 statement_list=statement_list,