def if_expression( test: TranslatedExpression, then: TranslatedExpression, else_do: Optional[TranslatedExpression], ) -> TranslatedExpression: test_condition = convert_to_condition(test) then_expression = convert_to_expression(then) else_expression = (convert_to_expression(else_do) if else_do is not None else Constant(0)) true_label = TempManager.new_label() false_label = TempManager.new_label() join_label = TempManager.new_label() result = TempManager.new_temp() patch_true_labels(test_condition.trues, true_label) patch_false_labels(test_condition.trues, false_label) sequence = Sequence([ test_condition.statement, Label(true_label), Move(Temporary(result), then_expression), Jump(Name(join_label), [join_label]), Label(false_label), Move(Temporary(result), else_expression), Label(join_label), ]) return Expression(EvaluateSequence(sequence, Temporary(result)))
def for_expression( variable: TranslatedExpression, lo: TranslatedExpression, hi: TranslatedExpression, body: TranslatedExpression, break_label: TempLabel, ) -> TranslatedExpression: test_label = TempManager.new_label() body_label = TempManager.new_label() limit = TempManager.new_temp() variable_expression = convert_to_expression(variable) sequence = Sequence([ Move(variable_expression, convert_to_expression(lo)), Move(Temporary(limit), convert_to_expression(hi)), Label(test_label), ConditionalJump( RelationalOperator.le, variable_expression, Temporary(limit), body_label, break_label, ), Label(body_label), convert_to_statement(body), Move( variable_expression, BinaryOperation(BinaryOperator.plus, variable_expression, Constant(1)), ), Jump(Name(test_label), [test_label]), Label(break_label), ]) return NoResult(sequence)
def record_expression( field_list: List[TranslatedExpression]) -> TranslatedExpression: result = TempManager.new_temp() creation_sequence = [ Move( Temporary(result), frame.external_call("init_record", [Constant(len(field_list) * frame.word_size)]), ) ] for index, field_expression in enumerate(field_list): field_allocation = Move( Memory( BinaryOperation( BinaryOperator.plus, Temporary(result), Constant(index * frame.word_size), )), convert_to_expression(field_expression), ) creation_sequence.append(field_allocation) return Expression( EvaluateSequence(Sequence(creation_sequence), Temporary(result)))
def convert_to_expression(exp: TranslatedExpression) -> tree.Expression: if isinstance(exp, Expression): return exp.expression if isinstance(exp, NoResult): return EvaluateSequence(exp.statement, Constant(0)) if isinstance(exp, Conditional): temporary_value = TempManager.new_temp() true = TempManager.new_label() false = TempManager.new_label() patch_true_labels(exp.condition.trues, true) patch_false_labels(exp.condition.falses, false) return EvaluateSequence( Move(Temporary(temporary_value), Constant(1)), EvaluateSequence( exp.condition.statement, EvaluateSequence( Label(false), EvaluateSequence( Move(Temporary(temporary_value), Constant(0)), EvaluateSequence(Label(true), Temporary(temporary_value)), ), ), ), )
def reorder( expression_list: List[Expression] ) -> Tuple[Statement, List[Expression]]: if not expression_list: return noop_statement(), [] if isinstance(expression_list[0], Call): temporary = TempManager.new_temp() expression_list[0] = EvaluateSequence( Move(Temporary(temporary), expression_list[0]), Temporary(temporary)) return reorder(expression_list) head_statement, head_expression = do_expression(expression_list[0]) tail_statement, tail_expressions = reorder(expression_list[1:]) if commute(tail_statement, head_expression): return ( simplified_sequence(head_statement, tail_statement), [head_expression] + tail_expressions, ) temporary = TempManager.new_temp() return ( simplified_sequence( simplified_sequence(head_statement, Move(Temporary(temporary), head_expression)), tail_statement, ), [Temporary(temporary)] + tail_expressions, )
def proc_entry_exit(function_level: RealLevel, body: TranslatedExpression): body_statement = Move(Temporary(frame.return_value()), convert_to_expression(body)) proc_statement = frame.preserve_callee_registers( function_level.frame, frame.shift_view(function_level.frame, body_statement)) FragmentManager.add_fragment( ProcessFragment(proc_statement, function_level.frame))
def assignment_expression( variable: TranslatedExpression, expression: TranslatedExpression) -> TranslatedExpression: return NoResult( Move(convert_to_expression(variable), convert_to_expression(expression)))
def do_statement(statement: Statement) -> Statement: if isinstance(statement, Sequence): substatement_list = [] for substatement in statement.sequence: new_substatement = do_statement(substatement) if not is_noop(new_substatement): substatement_list.append(new_substatement) if not substatement_list: return noop_statement() return Sequence(substatement_list) if isinstance(statement, Jump): new_statement, new_expressions = reorder([statement.expression]) return simplified_sequence(new_statement, Jump(new_expressions[0], statement.labels)) if isinstance(statement, ConditionalJump): new_statement, new_expressions = reorder( [statement.left, statement.right]) return simplified_sequence( new_statement, ConditionalJump( statement.operator, new_expressions[0], new_expressions[1], statement.true, statement.false, ), ) if isinstance(statement, Move): if isinstance(statement.temporary, Temporary) and isinstance( statement.expression, Call): new_statement, new_expressions = reorder( [statement.expression.function] + statement.expression.arguments) return simplified_sequence( new_statement, Move(statement.temporary, Call(new_expressions[0], new_expressions[1:])), ) if isinstance(statement.temporary, Temporary): new_statement, new_expressions = reorder([statement.expression]) return simplified_sequence( new_statement, Move(statement.temporary, new_expressions[0])) if isinstance(statement.temporary, Memory): new_statement, new_expressions = reorder( [statement.temporary.expression, statement.expression]) return simplified_sequence( new_statement, Move(Memory(new_expressions[0]), new_expressions[1])) if isinstance(statement.temporary, EvaluateSequence): substatement = statement.temporary.statement return do_statement( Sequence([ substatement, Move(statement.temporary.expression, statement.expression), ])) if isinstance(statement, StatementExpression): if isinstance(statement.expression, Call): new_statement, new_expressions = reorder( [statement.expression.function] + statement.expression.arguments) statement.expression.function = new_expressions[0] statement.expression.arguments = new_expressions[1:] return simplified_sequence( new_statement, StatementExpression( Call(new_expressions[0], new_expressions[1:])), ) else: new_statement, new_expressions = reorder([statement.expression]) return simplified_sequence(new_statement, StatementExpression(new_expressions[0])) return statement