예제 #1
0
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)))
예제 #2
0
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)
예제 #3
0
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)))
예제 #4
0
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)),
                    ),
                ),
            ),
        )
예제 #5
0
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,
    )
예제 #6
0
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))
예제 #7
0
def assignment_expression(
        variable: TranslatedExpression,
        expression: TranslatedExpression) -> TranslatedExpression:
    return NoResult(
        Move(convert_to_expression(variable),
             convert_to_expression(expression)))
예제 #8
0
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