示例#1
0
def test_parse_if_statements():
    assert (project_10.IfStatementP.parse(
        project_10.lex(
            "if (debugEnabled) { do Output.printString(\"got here\"); }")) ==
            IfStatement(VarRef("debugEnabled"), [
                DoStatement(
                    SubroutineCall(class_name="Output",
                                   var_name=None,
                                   sub_name="printString",
                                   args=[StringConstant("got here")]))
            ], None))

    assert (project_10.IfStatementP.parse(
        project_10.lex(
            "if (true) { } else { do firstThing(); do secondThing(); }")) ==
            IfStatement(KeywordConstant(True), [], [
                DoStatement(
                    SubroutineCall(class_name=None,
                                   var_name=None,
                                   sub_name="firstThing",
                                   args=[])),
                DoStatement(
                    SubroutineCall(class_name=None,
                                   var_name=None,
                                   sub_name="secondThing",
                                   args=[])),
            ]))
示例#2
0
def test_integer_overflow():
    try:
        project_10.lex("12345678")

        assert False
    except:
        pass
示例#3
0
def test_parse_return_statements():
    assert (project_10.ReturnStatementP.parse(
        project_10.lex("return;")) == ReturnStatement(None))

    assert (project_10.ReturnStatementP.parse(
        project_10.lex("return 137;")) == ReturnStatement(
            IntegerConstant(137)))
示例#4
0
def test_parse_class_var_decs():
    assert (project_10.ClassVarDecP.parse(
        project_10.lex("static Game instance;")) == ClassVarDec(
            static=True, type=Type("Game"), names=["instance"]))

    assert (project_10.ClassVarDecP.parse(
        project_10.lex("field int count, limit;")) == ClassVarDec(
            static=False, type=Type("int"), names=["count", "limit"]))
示例#5
0
def test_parse_types():
    assert project_10.TypeP.parse(project_10.lex("int")) == Type("int")
    assert project_10.TypeP.parse(project_10.lex("char")) == Type("char")
    assert project_10.TypeP.parse(project_10.lex("boolean")) == Type("boolean")
    assert project_10.TypeP.parse(project_10.lex("MyClass")) == Type("MyClass")

    with pytest.raises(parsing.ParseFailure):
        project_10.TypeP.parse(project_10.lex("text"))
示例#6
0
def test_parse_let_statements():
    assert (project_10.LetStatementP.parse(
        project_10.lex("let x = 1;")) == LetStatement("x", None,
                                                      IntegerConstant(1)))

    assert (project_10.LetStatementP.parse(
        project_10.lex("let a[0] = x + 1;")) == LetStatement(
            "a", IntegerConstant(0),
            BinaryExpression(VarRef("x"), Op("+"), IntegerConstant(1))))
示例#7
0
def test_parse_classes():
    assert (project_10.ClassP.parse(project_10.lex("class Foo {}")) == Class(
        "Foo", [], []))

    assert (project_10.ClassP.parse(
        project_10.lex(
            "class Counter { field int value; method void reset() { let value = 0; } }"
        )) == Class("Counter", [ClassVarDec(False, Type("int"), ["value"])], [
            SubroutineDec(
                "method", None, "reset", [],
                SubroutineBody(
                    [], [LetStatement("value", None, IntegerConstant(0))]))
        ]))
示例#8
0
def test_parse_do_statements():
    assert (project_10.DoStatementP.parse(
        project_10.lex("do Output.printInt(42);")) == DoStatement(
            SubroutineCall(class_name="Output",
                           var_name=None,
                           sub_name="printInt",
                           args=[IntegerConstant(42)])))
示例#9
0
def test_parse_terms():
    assert (project_10.ExpressionP.parse(
        project_10.lex("x + 1")) == BinaryExpression(VarRef("x"), Op("+"),
                                                     IntegerConstant(1)))

    # Note: all operators associate to the right, which is almost definitely *not* what you want
    assert (project_10.ExpressionP.parse(
        project_10.lex("x + y + z")) == BinaryExpression(
            VarRef("x"), Op("+"),
            (BinaryExpression(VarRef("y"), Op("+"), VarRef("z")))))

    # Parens required here.
    assert (project_10.ExpressionP.parse(
        project_10.lex("(x - y) + z")) == BinaryExpression(
            (BinaryExpression(VarRef("x"), Op("-"), VarRef("y"))), Op("+"),
            VarRef("z")))
示例#10
0
def test_parse_while_statements():
    assert (project_10.WhileStatementP.parse(
        project_10.lex("while (x > 1) { let x = x - 1; }")) == WhileStatement(
            BinaryExpression(VarRef("x"), Op(">"), IntegerConstant(1)), [
                LetStatement(
                    "x", None,
                    BinaryExpression(VarRef("x"), Op("-"), IntegerConstant(1)))
            ]))
示例#11
0
def test_simple_statement():
    tokens = project_10.lex("let x = 10;")

    assert tokens == [
        ("keyword", "let"),
        ("identifier", "x"),
        ("symbol", "="),
        ("integerConstant", "10"),
        ("symbol", ";"),
    ]
示例#12
0
def test_parse_subroutine_decs():
    assert (project_10.SubroutineDecP.parse(
        project_10.lex("function void foo() { }")) == SubroutineDec(
            "function", None, "foo", [], SubroutineBody([], [])))

    assert (project_10.SubroutineDecP.parse(
        project_10.lex(
            "constructor Thing new(int width, int height) { let area = width*height; return this; }"
        )) == SubroutineDec(
            "constructor", Type("Thing"), "new", [
                Parameter(Type("int"), "width"),
                Parameter(Type("int"), "height")
            ],
            SubroutineBody([], [
                LetStatement(
                    "area", None,
                    BinaryExpression(VarRef("width"), Op("*"),
                                     VarRef("height"))),
                ReturnStatement(KeywordConstant("this")),
            ])))
示例#13
0
def test_trivial_expression():
    ast = project_10.ExpressionP.parse(project_10.lex("1 + 2"))

    symbol_table = project_11.SymbolTable("Main")
    asm = AssemblySource()
    project_11.compile_expression(ast, symbol_table, asm)

    assert asm.lines == [
        "  push constant 1",
        "  push constant 2",
        "  add",
    ]
示例#14
0
def test_comment_multiline():
    tokens = project_10.lex("""
/** A comment that
 * spans more than
 * one line.
 */
 class Foo {
   /* Another
    multi-line
    comment. */
 }
 """)

    assert tokens == [("keyword", "class"), ("identifier", "Foo"),
                      ("symbol", "{"), ("symbol", "}")]
示例#15
0
def test_parse_var_decs():
    assert project_10.VarDecP.parse(project_10.lex("var int x;")) == VarDec(
        Type("int"), ["x"])
    assert project_10.VarDecP.parse(
        project_10.lex("var boolean isBlue, isOvine;")) == VarDec(
            Type("boolean"), ["isBlue", "isOvine"])
示例#16
0
def test_identifier():
    tokens = project_10.lex("done")

    assert tokens == [("identifier", "done")]
示例#17
0
def test_comment_simple():
    tokens = project_10.lex("// A simple comment\n")

    assert tokens == []
示例#18
0
def test_stringConstant_escaped():
    """It's confusing, but this string has two escaped double quotes and an escaped backslash."""
    tokens = project_10.lex(r'"/ \"Hello\" \\"')

    assert tokens == [("stringConstant", '/ "Hello" \\')]
示例#19
0
def test_white_space():
    tokens = project_10.lex(" \n\t\n  ")

    assert tokens == []
示例#20
0
def test_stringConstant():
    tokens = project_10.lex('"abc def"')

    assert tokens == [("stringConstant", "abc def")]
示例#21
0
def test_symbol():
    tokens = project_10.lex("+")

    assert tokens == [("symbol", "+")]
示例#22
0
def test_integerConstant():
    tokens = project_10.lex("012345")

    # Note: the odd formatting surivives the lexer, just because it makes the behavior more
    # consistent. In this case, it's not a problem for the parser to deal with it.
    assert tokens == [("integerConstant", "012345")]
示例#23
0
def parse_classVarDecs(src):
    return parsing.ManyP(project_10.ClassVarDecP).parse(project_10.lex(src))
示例#24
0
def test_keyword():
    tokens = project_10.lex("do")

    assert tokens == [("keyword", "do")]
示例#25
0
def parse_subroutineDec(src):
    return project_10.SubroutineDecP.parse(project_10.lex(src))
示例#26
0
def test_lex_array_test():
    tokens = project_10.lex(ARRAY_TEST)

    assert tokens == [
        # 0
        ("keyword", "class"),
        ("identifier", "Main"),
        ("symbol", "{"),
        ("keyword", "function"),
        ("keyword", "void"),
        ("identifier", "main"),
        ("symbol", "("),
        ("symbol", ")"),
        ("symbol", "{"),
        ("keyword", "var"),
        # 10
        ("identifier", "Array"),
        ("identifier", "a"),
        ("symbol", ";"),
        ("keyword", "var"),
        ("keyword", "int"),
        ("identifier", "length"),
        ("symbol", ";"),
        ("keyword", "var"),
        ("keyword", "int"),
        ("identifier", "i"),
        # 20
        ("symbol", ","),
        ("identifier", "sum"),
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "length"),
        ("symbol", "="),
        ("identifier", "Keyboard"),
        ("symbol", "."),
        ("identifier", "readInt"),
        ("symbol", "("),
        # 30
        ("stringConstant", "HOW MANY NUMBERS? "),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "a"),
        ("symbol", "="),
        ("identifier", "Array"),
        ("symbol", "."),
        ("identifier", "new"),
        ("symbol", "("),
        # 40
        ("identifier", "length"),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "i"),
        ("symbol", "="),
        ("integerConstant", "0"),
        ("symbol", ";"),
        ("keyword", "while"),
        ("symbol", "("),
        # 50
        ("identifier", "i"),
        ("symbol", "<"),
        ("identifier", "length"),
        ("symbol", ")"),
        ("symbol", "{"),
        ("keyword", "let"),
        ("identifier", "a"),
        ("symbol", "["),
        ("identifier", "i"),
        ("symbol", "]"),
        # 60
        ("symbol", "="),
        ("identifier", "Keyboard"),
        ("symbol", "."),
        ("identifier", "readInt"),
        ("symbol", "("),
        ("stringConstant", "ENTER THE NEXT NUMBER: "),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "i"),
        # 70
        ("symbol", "="),
        ("identifier", "i"),
        ("symbol", "+"),
        ("integerConstant", "1"),
        ("symbol", ";"),
        ("symbol", "}"),
        ("keyword", "let"),
        ("identifier", "i"),
        ("symbol", "="),
        ("integerConstant", "0"),
        # 80
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "sum"),
        ("symbol", "="),
        ("integerConstant", "0"),
        ("symbol", ";"),
        ("keyword", "while"),
        ("symbol", "("),
        ("identifier", "i"),
        ("symbol", "<"),
        # 90
        ("identifier", "length"),
        ("symbol", ")"),
        ("symbol", "{"),
        ("keyword", "let"),
        ("identifier", "sum"),
        ("symbol", "="),
        ("identifier", "sum"),
        ("symbol", "+"),
        ("identifier", "a"),
        ("symbol", "["),
        # 100
        ("identifier", "i"),
        ("symbol", "]"),
        ("symbol", ";"),
        ("keyword", "let"),
        ("identifier", "i"),
        ("symbol", "="),
        ("identifier", "i"),
        ("symbol", "+"),
        ("integerConstant", "1"),
        ("symbol", ";"),
        # 110
        ("symbol", "}"),
        ("keyword", "do"),
        ("identifier", "Output"),
        ("symbol", "."),
        ("identifier", "printString"),
        ("symbol", "("),
        ("stringConstant", "THE AVERAGE IS: "),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "do"),
        # 120
        ("identifier", "Output"),
        ("symbol", "."),
        ("identifier", "printInt"),
        ("symbol", "("),
        ("identifier", "sum"),
        ("symbol", "/"),
        ("identifier", "length"),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "do"),
        # 130
        ("identifier", "Output"),
        ("symbol", "."),
        ("identifier", "println"),
        ("symbol", "("),
        ("symbol", ")"),
        ("symbol", ";"),
        ("keyword", "return"),
        ("symbol", ";"),
        ("symbol", "}"),
        ("symbol", "}"),
    ]