+def fake_normalization(counter, thing):
+ return (counter, (), thing)
+
+def normalize_integer_literal_expression(counter, expression):
+ variable = '${}'.format(counter)
+ return (
+ counter + 1,
+ (
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalIntegerLiteralExpression(integer=expression.integer),
+ ),
+ ),
+ NormalVariableExpression(variable=variable),
+ )
+
+NormalListConstructExpression = collections.namedtuple(
+ 'NormalListConstructExpression',
+ [
+ 'allocate',
+ ],
+)
+
+NormalListAppendStatement = collections.namedtuple(
+ 'NormalListAppendStatement',
+ [
+ 'list_expression',
+ 'item_expression',
+ ],
+)
+
+NormalListGetExpression = collections.namedtuple(
+ 'NormalListGetExpression',
+ [
+ 'list_expression',
+ 'index_expression',
+ ],
+)
+
+def normalize_list_literal_expression(counter, expression):
+ list_variable = '${}'.format(counter)
+ counter += 1
+
+ prestatements = [
+ NormalVariableInitializationStatement(
+ variable=list_variable,
+ expression=NormalListConstructExpression(allocate=len(expression.item_expression_list)),
+ ),
+ ]
+
+ list_expression = NormalVariableExpression(variable=list_variable)
+
+ for item_expression in expression.item_expression_list:
+ counter, item_expression_prestatements, normalized = normalize_expression(
+ counter,
+ item_expression,
+ )
+
+ for p in item_expression_prestatements:
+ prestatements.append(p)
+
+ prestatements.append(
+ NormalListAppendStatement(
+ list_expression=list_expression,
+ item_expression=normalized,
+ )
+ )
+
+ return (
+ counter,
+ tuple(prestatements),
+ list_expression,
+ )
+
+def normalize_list_item_expression(counter, expression):
+ counter, list_prestatements, list_expression = normalize_expression(counter, expression.list_expression)
+ counter, index_prestatements, index_expression = normalize_expression(counter, expression.index_expression)
+
+ result_variable = '${}'.format(counter)
+ result_prestatement = NormalVariableInitializationStatement(
+ variable=result_variable,
+ expression=NormalListGetExpression(
+ list_expression=list_expression,
+ index_expression=index_expression,
+ ),
+ )
+
+ return (
+ counter + 1,
+ list_prestatements + index_prestatements + (result_prestatement,),
+ NormalVariableExpression(variable=result_variable),
+ )
+
+def normalize_string_literal_expression(counter, expression):
+ variable = '${}'.format(counter)
+ return (
+ counter + 1,
+ (
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalStringLiteralExpression(string=expression.string),
+ ),
+ ),
+ NormalVariableExpression(variable=variable),
+ )
+
+NormalStructureLiteralExpression = collections.namedtuple(
+ 'NormalStructureLiteralExpression',
+ [
+ 'field_count',
+ 'symbol_list_variable',
+ 'value_list_variable',
+ ],
+)
+
+def normalize_structure_literal_expression(counter, expression):
+ prestatements = []
+ field_symbol_array = []
+ field_value_array = []
+
+ for symbol_expression_pair in expression.fields:
+ counter, field_prestatements, field_expression = normalize_expression(
+ counter,
+ symbol_expression_pair.expression,
+ )
+
+ for p in field_prestatements:
+ prestatements.append(p)
+
+ field_symbol_array.append(symbol_expression_pair.symbol)
+ field_value_array.append(field_expression)
+
+ symbol_array_variable = '${}'.format(counter)
+ counter += 1
+
+ prestatements.append(
+ NormalSymbolArrayVariableInitializationStatement(
+ variable=symbol_array_variable,
+ symbol_list=tuple(field_symbol_array),
+ )
+ )
+
+ value_array_variable = '${}'.format(counter)
+ counter += 1
+
+ prestatements.append(
+ NormalArrayVariableInitializationStatement(
+ variable=value_array_variable,
+ items=tuple(field_value_array),
+ )
+ )
+
+ variable = '${}'.format(counter)
+
+ prestatements.append(
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalStructureLiteralExpression(
+ field_count=len(expression.fields),
+ symbol_list_variable=symbol_array_variable,
+ value_list_variable=value_array_variable,
+ ),
+ )
+ )
+
+ return (
+ counter + 1,
+ tuple(prestatements),
+ NormalVariableExpression(variable=variable),
+ )
+
+
+def normalize_symbol_expression(counter, expression):
+ variable = '${}'.format(counter)
+ return (
+ counter + 1,
+ (
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalSymbolExpression(symbol=expression.symbol),
+ ),
+ ),
+ NormalVariableExpression(variable=variable),
+ )
+
+def normalize_function_call_expression(counter, expression):
+ assert isinstance(expression, parsing.FurFunctionCallExpression)
+
+ prestatements = []
+
+ for argument in expression.arguments:
+ counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
+
+ for s in argument_prestatements:
+ prestatements.append(s)
+
+ variable = '${}'.format(counter)
+ prestatements.append(
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=normalized_argument,
+ )
+ )
+ prestatements.append(
+ NormalPushStatement(
+ expression=NormalVariableExpression(
+ variable=variable,
+ ),
+ ),
+ )
+ counter += 1
+
+ counter, function_prestatements, function_expression = normalize_expression(
+ counter,
+ expression.function,
+ )
+
+ for ps in function_prestatements:
+ prestatements.append(ps)
+
+ if not isinstance(function_expression, NormalVariableExpression):
+ function_variable = '${}'.format(counter)
+
+ prestatements.append(
+ NormalVariableInitializationStatement(
+ variable=function_variable,
+ expression=function_expression,
+ )
+ )
+
+ function_expression = NormalVariableExpression(variable=function_variable)
+ counter += 1
+
+ result_variable = '${}'.format(counter)
+
+ prestatements.append(
+ NormalVariableInitializationStatement(
+ variable=result_variable,
+ expression=NormalFunctionCallExpression(
+ function_expression=function_expression,
+ argument_count=len(expression.arguments),
+ ),
+ )
+ )
+
+ return (
+ counter + 1,
+ tuple(prestatements),
+ NormalVariableExpression(variable=result_variable),
+ )
+
+def normalize_basic_infix_operation(counter, expression):
+ counter, left_prestatements, left_expression = normalize_expression(counter, expression.left)
+ counter, right_prestatements, right_expression = normalize_expression(counter, expression.right)
+
+ center_variable = '${}'.format(counter)
+ counter += 1
+
+ root_prestatements = (
+ NormalPushStatement(expression=left_expression),
+ NormalPushStatement(expression=right_expression),
+ NormalVariableInitializationStatement(
+ variable=center_variable,
+ expression=NormalInfixExpression(
+ metadata=expression.metadata,
+ order=expression.order,
+ operator=expression.operator,
+ ),
+ ),
+ )
+
+ return (
+ counter,
+ left_prestatements + right_prestatements + root_prestatements,
+ NormalVariableExpression(variable=center_variable),
+ )
+
+def desugar_ternary_comparison(counter, expression):
+ counter, left_prestatements, left_expression = normalize_expression(counter, expression.left.left)
+ counter, middle_prestatements, middle_expression = normalize_expression(counter, expression.left.right)
+
+ left_variable = '${}'.format(counter)
+ counter += 1
+ middle_variable = '${}'.format(counter)
+ counter += 1
+
+ # TODO Is there a memory leak if the middle expression throws an exception because the first expression result hasn't been added to the stack?
+ juncture_prestatements = (
+ NormalVariableInitializationStatement(
+ variable=left_variable,
+ expression=left_expression,
+ ),
+ NormalVariableInitializationStatement(
+ variable=middle_variable,
+ expression=middle_expression,
+ )
+ )
+
+ counter, boolean_expression_prestatements, boolean_expression = normalize_boolean_expression(
+ counter,
+ parsing.FurInfixExpression(
+ metadata=expression.left.metadata,
+ order='and_level',
+ operator='and',
+ left=parsing.FurInfixExpression(
+ metadata=expression.left.metadata,
+ order='comparison_level',
+ operator=expression.left.operator,
+ left=NormalVariableExpression(variable=left_variable),
+ right=NormalVariableExpression(variable=middle_variable),
+ ),
+ right=parsing.FurInfixExpression(
+ metadata=expression.metadata,
+ order='comparison_level',
+ operator=expression.operator,
+ left=NormalVariableExpression(variable=middle_variable),
+ right=expression.right,
+ ),
+ )
+ )
+
+ return (
+ counter,
+ left_prestatements + middle_prestatements + juncture_prestatements + boolean_expression_prestatements,
+ boolean_expression,
+ )