示例#1
0
def test_dont_optimize_jumps_with_missing_label_in_chain():
    start_ast = [
            parser.LabelStmt("start"),
            parser.AssignOp(src="inbox", dst="emp"),
            parser.JumpOp(label_name="a"),
            parser.OutboxOp(),
            parser.JumpOp(label_name="start"),
            parser.LabelStmt("a"),
            parser.JumpOp(label_name="b"),
            parser.LabelStmt("b"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("misspelled_start"),
    ]
    expected_ast = [
            parser.LabelStmt("start"),
            parser.AssignOp(src="inbox", dst="emp"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.OutboxOp(),
            parser.JumpOp(label_name="start"),
            parser.LabelStmt("a"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("b"),
            parser.JumpOp(label_name="misspelled_start"),
            parser.LabelStmt("misspelled_start"),
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#2
0
def test_convert_iftojump_nested():
    code = [
        p.IfOp("ez", [
            p.IfOp("ez", [p.AssignOp("inbox", "emp")], [p.OutboxOp()]),
        ], [
            p.IfOp("neg", [p.AssignOp("inbox", "emp")], [p.OutboxOp()])
        ])]
    expected_ast = [
        p.JumpCondOp(condition="jez", label_name="_hrm_1"),
          p.JumpCondOp(condition="jneg", label_name="_hrm_2"),
            p.OutboxOp(),
            p.JumpOp("_hrm_endif_2"),
          p.LabelStmt("_hrm_2"),
            p.AssignOp("inbox", "emp"),
          p.LabelStmt("_hrm_endif_2"),
       p.JumpOp("_hrm_endif_1"),
       p.LabelStmt("_hrm_1"),
          p.JumpCondOp(condition="jez", label_name="_hrm_3"),
            p.OutboxOp(),
            p.JumpOp("_hrm_endif_3"),
          p.LabelStmt("_hrm_3"),
            p.AssignOp("inbox", "emp"),
          p.LabelStmt("_hrm_endif_3"),
       p.LabelStmt("_hrm_endif_1")]
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
示例#3
0
def test_compress_jcond_single():
    start_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("if", "ez"),
            parser.OutboxOp(),
            parser.JumpOp("endif"),
        parser.LabelStmt("if"),
            parser.JumpOp("start"),
        parser.LabelStmt("endif"),
        parser.OutboxOp()
    ]
    expected_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("start", "ez"),
            parser.OutboxOp(),
            parser.JumpOp("endif"),
        parser.LabelStmt("if"),
            parser.JumpOp("start"),
        parser.LabelStmt("endif"),
        parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#4
0
def test_labelinast_nojump():
    start_ast = [
        parser.OutboxOp(),
        parser.LabelStmt("test"),
        parser.OutboxOp()
    ]
    labels_positions, _ = labels_in_ast(start_ast)
    assert "test" in labels_positions
    assert labels_positions["test"] == 2
def test_convert_jmpthenlabel_conditionaljumps_leading_to_same_instr():
    start_ast = [
        p.JumpCondOp(condition="ez", label_name="output"),
        p.LabelStmt("output"),
        p.OutboxOp()
    ]
    expected_ast = [p.OutboxOp()]
    ast = conversion.fix_jmp_then_label(start_ast)
    assert ast == expected_ast
示例#6
0
def test_compress_jcond_no_compress():
    start_ast = [
        parser.JumpCondOp("label", "ez"),
          parser.OutboxOp(),
          parser.JumpOp("endif"),
        parser.LabelStmt("label"),
          parser.OutboxOp(),
        parser.LabelStmt("endif"),
        parser.OutboxOp()
    ]
    expected_ast = start_ast
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#7
0
def test_convert_iftojump_onlyfalsebranch():
    code = [
        p.IfOp("ez", [], [
            p.OutboxOp()
        ])]
    expected_ast = [
        p.JumpCondOp(condition="jez", label_name="_hrm_1"),
        p.OutboxOp(),
        p.JumpOp("_hrm_endif_1"),
        p.LabelStmt("_hrm_1"),
        p.LabelStmt("_hrm_endif_1")
    ]
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
示例#8
0
def test_labelinast_no_labels():
    start_ast = []
    start_ast_2 = [parser.OutboxOp()]
    labels_positions, _ = labels_in_ast(start_ast)
    labels_positions_2, _ = labels_in_ast(start_ast_2)
    assert not len(labels_positions)
    assert not len(labels_positions_2)
示例#9
0
def test_unreachable_condjumps():
    start_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("_hrm_1", "jez"),
        parser.OutboxOp(),
        parser.LabelStmt("_hrm_1"),
        parser.LabelStmt("_hrm_endif_1")
    ]
    expected_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("_hrm_unreachable", "jez"),
        parser.OutboxOp(),
        parser.LabelStmt("_hrm_unreachable")
    ]
    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
示例#10
0
def test_labelinast_invalid_access():
    start_ast = [
        parser.OutboxOp(),
        parser.LabelStmt("test")
    ]
    labels_positions, _ = labels_in_ast(start_ast)
    assert "test" not in labels_positions
示例#11
0
def test_compress_single_jump():
    start_ast = [
        parser.JumpOp("test"),
        parser.LabelStmt("test"),
        parser.JumpOp("wow"),
        parser.LabelStmt("wow"),
        parser.OutboxOp()
    ]
    expected_ast = [
        parser.JumpOp("wow"),
        parser.LabelStmt("test"),
        parser.JumpOp("wow"),
        parser.LabelStmt("wow"),
        parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#12
0
def test_no_compress():
    expected_ast = start_ast = [
        parser.JumpOp("test"),
        parser.LabelStmt("test"),
        parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert expected_ast == ast
示例#13
0
def test_no_duplicated_labels_on_same_point():
    start_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpOp("skip"),
        parser.LabelStmt("comehere"),
        parser.OutboxOp(),
        parser.LabelStmt("skip"),
        parser.JumpOp("comehere")
    ]
    ast = remove_unreachable_code(start_ast)

    comehere_counter = sum(1 for ast_item in ast \
                    if type(ast_item) == parser.LabelStmt \
                        and ast_item.label_name == "comehere")
    assert comehere_counter == 1

    start_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpOp("comehere"),
        parser.LabelStmt("comehere"),
        parser.OutboxOp(),
        parser.LabelStmt("skip"),
        parser.JumpOp("comehere")
    ]
    ast = remove_unreachable_code(start_ast)

    comehere_counter = sum(1 for ast_item in ast \
                    if type(ast_item) == parser.LabelStmt \
                        and ast_item.label_name == "comehere")
    assert comehere_counter == 1

    start_ast = [
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp("comehere", "jez"),
        parser.JumpOp("comehere"),
        parser.LabelStmt("comehere"),
        parser.OutboxOp(),
        parser.LabelStmt("skip"),
        parser.JumpOp("comehere")
    ]
    ast = remove_unreachable_code(start_ast)

    comehere_counter = sum(1 for ast_item in ast \
                    if type(ast_item) == parser.LabelStmt \
                        and ast_item.label_name == "comehere")
    assert comehere_counter == 1
def test_convert_jmpthenlabel_conditionaljumps_multiple():
    start_ast = [
        p.JumpCondOp(condition="jneg", label_name="other"),
        p.JumpCondOp(condition="jez", label_name="output"),
        p.LabelStmt("output"),
        p.OutboxOp(),
        p.LabelStmt("other"),
        p.AssignOp(src="inbox", dst="emp")
    ]
    expected_ast = [
        p.JumpCondOp(condition="jneg", label_name="other"),
        p.OutboxOp(),
        p.LabelStmt("other"),
        p.AssignOp(src="inbox", dst="emp")
    ]
    ast = conversion.fix_jmp_then_label(start_ast)

    assert ast == expected_ast
示例#15
0
def test_convert_iftojump_nothingchanged():
    code = [
        p.AssignOp("inbox", "emp"),
        p.SubOp("0"),
        p.OutboxOp()
    ]
    expected_ast = code
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
示例#16
0
def test_jcond_avoid_loop():
    start_ast = [
        parser.LabelStmt("test"),
        parser.JumpCondOp("test", "ez"),
        parser.OutboxOp(),
        parser.JumpOp("test"),
    ]
    expected_ast = start_ast
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#17
0
def test_convert_iftojump_onlytruebranch_consecutive():
    code = [
        p.IfOp("ez", [p.OutboxOp()], []),
        p.IfOp("ez", [p.OutboxOp()], [])]
    expected_ast = [
        # first IF
        p.JumpCondOp(condition="jez", label_name="_hrm_1"),
        p.JumpOp("_hrm_endif_1"),
        p.LabelStmt("_hrm_1"),
        p.OutboxOp(),
        p.LabelStmt("_hrm_endif_1"),
        # second IF
        p.JumpCondOp(condition="jez", label_name="_hrm_2"),
        p.JumpOp("_hrm_endif_2"),
        p.LabelStmt("_hrm_2"),
        p.OutboxOp(),
        p.LabelStmt("_hrm_endif_2")]
    ast = c.convert_iftojump(code)
    assert ast == expected_ast
示例#18
0
def test_compress_multi_jump():
    start_ast = [
        parser.JumpOp("first"),
        parser.LabelStmt("first"), parser.JumpOp("second"),
        parser.LabelStmt("second"), parser.JumpOp("third"),
        parser.LabelStmt("third"), parser.JumpOp("fourth"),
        parser.LabelStmt("fourth"), parser.JumpOp("last"),
        parser.LabelStmt("last"), parser.OutboxOp()
    ]
    expected_ast = [
        parser.JumpOp("last"),
        parser.LabelStmt("first"), parser.JumpOp("last"),
        parser.LabelStmt("second"), parser.JumpOp("last"),
        parser.LabelStmt("third"), parser.JumpOp("last"),
        parser.LabelStmt("fourth"), parser.JumpOp("last"),
        parser.LabelStmt("last"), parser.OutboxOp()
    ]
    ast = compress_jumps(start_ast)
    assert ast == expected_ast
示例#19
0
def test_jcond_no_jump_in_false():
    start_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpCondOp(condition="ez", label_name="truebranch"),
        parser.OutboxOp(),
        parser.LabelStmt("truebranch"),
        parser.AddOp("tmp")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast
示例#20
0
def test_still_reachable():
    start_ast = [
        parser.JumpOp("skip"),
        parser.LabelStmt("ahah"),
        parser.OutboxOp(),
        parser.LabelStmt("skip"),
        parser.JumpOp("ahah")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == start_ast
示例#21
0
def test_if_doublebranch():
    assembler = Assembler()
    transformed_ast = [
        parser.IfOp("ez", [parser.OutboxOp()],
                    [parser.AssignOp("inbox", "emp")])
    ]
    assembler.convert(transformed_ast)

    assert assembler.code == [
        "jez _hrm_1", "inbox", "jmp _hrm_endif_1", "_hrm_1:", "outbox",
        "_hrm_endif_1:"
    ]
示例#22
0
def test_if_noelse():
    assembler = Assembler()
    transformed_ast = [parser.IfOp("ez", [parser.OutboxOp()], [])]
    assembler.convert(transformed_ast)

    assert assembler.code == clean_output("""
        jez _hrm_1
        jmp _hrm_endif_1
        _hrm_1:
        outbox
        _hrm_endif_1:
    """)
示例#23
0
def test_dont_keep_only_last_label_on_instruction():
    start_ast = [
        parser.AssignOp(src='inbox', dst='emp'),
        parser.JumpCondOp(label_name='_hrm_1', condition='jez'),
        parser.OutboxOp(),
        parser.JumpOp(label_name="_hrm_endif_1"),
        parser.LabelStmt("_hrm_1"),
        parser.LabelStmt("_hrm_endif_1"),
        parser.AssignOp(src="inbox", dst="emp")
    ]
    ast = remove_unreachable_code(start_ast)
    assert parser.LabelStmt("_hrm_endif_1") in ast
    assert parser.LabelStmt("_hrm_1") in ast
示例#24
0
def test_unreachable_jump_to_lone_label_in_jcond_false_path():
    start_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp(condition="ez", label_name="isZero"),
        parser.JumpOp("loneLabel"),
        parser.LabelStmt("isZero"),
        parser.OutboxOp(),
        parser.JumpOp("start"),
        parser.LabelStmt("loneLabel")
    ]
    expected_ast = [
        parser.LabelStmt("start"),
        parser.AssignOp(src="inbox", dst="emp"),
        parser.JumpCondOp(condition="ez", label_name="isZero"),
        parser.JumpOp("_hrm_unreachable"),
        parser.LabelStmt("isZero"),
        parser.OutboxOp(),
        parser.JumpOp("start"),
        parser.LabelStmt("_hrm_unreachable")
    ]
    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
def test_if_multiple_ops():
    code = """
    start:
    emp = inbox
    if ez then
        outbox
        jmp start
    endif
    """
    with StringIO(code) as f:
        ast = parser.parse_it(f)

    if_op = ast[2]
    assert type(if_op) == parser.IfOp
    assert if_op.condition == "ez"
    assert if_op.true_branch == [parser.OutboxOp(), parser.JumpOp("start")]
示例#26
0
def test_skip_operation():
    start_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpOp("label"),
        parser.OutboxOp(),
        parser.LabelStmt("label"),
        parser.AddOp("tmp")
    ]
    expected_ast = [
        parser.AssignOp("inbox", "emp"),
        parser.JumpOp("label"),
        parser.LabelStmt("label"),
        parser.AddOp("tmp")
    ]

    ast = remove_unreachable_code(start_ast)
    assert ast == expected_ast
示例#27
0
def test_dont_optimize_conditional_jumps():
    """
    if ez then
        # nothing, but the `jez` must not be removed!
        # if removed, the program becomes only `outbox`,
        # that is incorrect.
    else
        outbox
    endif
    """
    start_ast = [
            parser.JumpCondOp(label_name='_hrm_1', condition='jez'),
            parser.OutboxOp(),
            parser.JumpOp(label_name="_hrm_endif_1"),
            parser.LabelStmt(label_name="_hrm_1"),
            parser.LabelStmt(label_name="_hrm_endif_1")
    ]
    ast = compress_jumps(start_ast)
    assert parser.JumpCondOp(label_name="_hrm_1", condition="jez") in ast
示例#28
0
def test_convert_ifnojump_no_ifs_remaining():
    code = [p.IfOp("ez", [p.OutboxOp()], [p.AssignOp("inbox", "emp")])]
    ast = c.convert_iftojump(code)
    assert not [ast_item for ast_item in ast if type(ast_item) == p.IfOp]
def test_outbox():
    code = [parser.OutboxOp()]
    converter = Assembler()
    converter.convert(code)

    assert converter.code == [{"operation": "outbox"}]
示例#30
0
def test_single_operation():
    start_ast = [parser.OutboxOp()]
    ast = remove_unreachable_code(start_ast)

    assert start_ast == ast