From: David Kerkeslager Date: Tue, 8 Aug 2017 17:47:45 +0000 (-0400) Subject: Normalized all infix expression statements X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=2f7d76f2fc50763953b7268e0fe6558aac260187;p=fur Normalized all infix expression statements --- diff --git a/generation.py b/generation.py index 4b0ad7e..149a5e2 100644 --- a/generation.py +++ b/generation.py @@ -87,11 +87,31 @@ def generate_variable_initialization_statement(statement): generate_expression(statement.expression), ) +def generate_variable_reassignment_statement(statement): + return '{} = {};'.format( + statement.variable, + generate_expression(statement.expression), + ) + + +def indent(s): + return '\n'.join(' ' * 2 + l for l in s.split('\n')) + +def generate_if_else_statement(statement): + # TODO Check that the argument is boolean + return 'if({}.instance.boolean)\n{{\n{}\n}}\nelse\n{{\n{}\n}}'.format( + generate_expression(statement.condition_expression), + indent('\n'.join(generate_statement(s) for s in statement.if_statements)), + indent('\n'.join(generate_statement(s) for s in statement.else_statements)), + ) + def generate_statement(statement): return { - transformation.CSymbolAssignmentStatement: generate_symbol_assignment_statement, transformation.CExpressionStatement: generate_expression_statement, + transformation.CIfElseStatement: generate_if_else_statement, + transformation.CSymbolAssignmentStatement: generate_symbol_assignment_statement, transformation.CVariableInitializationStatement: generate_variable_initialization_statement, + transformation.CVariableReassignmentStatement: generate_variable_reassignment_statement, }[type(statement)](statement) def generate(program): diff --git a/normalization.py b/normalization.py index 94d3a7c..1dbeddb 100644 --- a/normalization.py +++ b/normalization.py @@ -35,6 +35,14 @@ NormalVariableInitializationStatement = collections.namedtuple( ], ) +NormalVariableReassignmentStatement = collections.namedtuple( + 'NormalVariableReassignmentStatement', + [ + 'variable', + 'expression', + ], +) + NormalExpressionStatement = collections.namedtuple( 'NormalExpressionStatement', [ @@ -42,6 +50,15 @@ NormalExpressionStatement = collections.namedtuple( ], ) +NormalIfElseStatement = collections.namedtuple( + 'NormalIfElseStatement', + [ + 'condition_expression', + 'if_statements', + 'else_statements', + ], +) + NormalProgram = collections.namedtuple( 'NormalProgram', [ @@ -178,8 +195,39 @@ def normalize_comparison_expression(counter, expression): return (counter, result_prestatements, result_expression) def normalize_boolean_expression(counter, expression): - # TODO Unfake this - return fake_normalization(counter, expression) + counter, left_prestatements, left_expression = normalize_expression(counter, expression.left) + counter, right_prestatements, right_expression = normalize_expression(counter, expression.right) + + result_variable = '${}'.format(counter) + if_else_prestatment = NormalVariableInitializationStatement(variable=result_variable, expression=left_expression) + counter += 1 + + condition_expression=NormalVariableExpression(variable=result_variable) + short_circuited_statements = right_prestatements + (NormalVariableReassignmentStatement(variable=result_variable, expression=right_expression),) + + if expression.operator == 'and': + if_else_statement = NormalIfElseStatement( + condition_expression=condition_expression, + if_statements=short_circuited_statements, + else_statements=(), + ) + + elif expression.operator == 'or': + if_else_statement = NormalIfElseStatement( + condition_expression=condition_expression, + if_statements=(), + else_statements=short_circuited_statements, + ) + + else: + raise Exception('Unable to handle operator "{}"'.format(expression.operator)) + + return ( + counter, + left_prestatements + (if_else_prestatment, if_else_statement), + NormalVariableExpression(variable=result_variable), + ) + def normalize_infix_expression(counter, expression): return { @@ -192,6 +240,8 @@ def normalize_infix_expression(counter, expression): def normalize_expression(counter, expression): return { + NormalInfixExpression: fake_normalization, + NormalVariableExpression: fake_normalization, parsing.FurFunctionCallExpression: normalize_function_call_expression, parsing.FurInfixExpression: normalize_infix_expression, parsing.FurIntegerLiteralExpression: fake_normalization, diff --git a/transformation.py b/transformation.py index 2d729fa..efc7d99 100644 --- a/transformation.py +++ b/transformation.py @@ -81,6 +81,14 @@ CVariableInitializationStatement = collections.namedtuple( ], ) +CVariableReassignmentStatement = collections.namedtuple( + 'CVariableReassignmentStatement', + [ + 'variable', + 'expression', + ], +) + CExpressionStatement = collections.namedtuple( 'CExpressionStatement', [ @@ -88,6 +96,15 @@ CExpressionStatement = collections.namedtuple( ], ) +CIfElseStatement = collections.namedtuple( + 'CIfElseStatement', + [ + 'condition_expression', + 'if_statements', + 'else_statements', + ], +) + CProgram = collections.namedtuple( 'CProgram', [ @@ -264,18 +281,33 @@ def transform_expression_statement(accumulators, statement): expression=expression, ) +def transform_if_else_statement(accumulators, statement): + return CIfElseStatement( + condition_expression=transform_expression(accumulators, statement.condition_expression), + if_statements=tuple(transform_statement(accumulators, s) for s in statement.if_statements), + else_statements=tuple(transform_statement(accumulators, s) for s in statement.else_statements), + ) + def transform_variable_initialization_statement(accumulators, statement): return CVariableInitializationStatement( variable=statement.variable, expression=transform_expression(accumulators, statement.expression), ) +def transform_variable_reassignment_statement(accumulators, statement): + return CVariableReassignmentStatement( + variable=statement.variable, + expression=transform_expression(accumulators, statement.expression), + ) + def transform_statement(accumulators, statement): return { parsing.FurAssignmentStatement: transform_symbol_assignment_statement, parsing.FurExpressionStatement: transform_expression_statement, - normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement, normalization.NormalExpressionStatement: transform_expression_statement, + normalization.NormalIfElseStatement: transform_if_else_statement, + normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement, + normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement, }[type(statement)](accumulators, statement)