Example #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=[])),
            ]))
Example #2
0
def test_integer_overflow():
    try:
        project_10.lex("12345678")

        assert False
    except:
        pass
Example #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)))
Example #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"]))
Example #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"))
Example #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))))
Example #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))]))
        ]))
Example #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)])))
Example #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")))
Example #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)))
            ]))
Example #11
0
def test_simple_statement():
    tokens = project_10.lex("let x = 10;")

    assert tokens == [
        ("keyword", "let"),
        ("identifier", "x"),
        ("symbol", "="),
        ("integerConstant", "10"),
        ("symbol", ";"),
    ]
Example #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")),
            ])))
Example #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",
    ]
Example #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", "}")]
Example #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"])
Example #16
0
def test_identifier():
    tokens = project_10.lex("done")

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

    assert tokens == []
Example #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" \\')]
Example #19
0
def test_white_space():
    tokens = project_10.lex(" \n\t\n  ")

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

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

    assert tokens == [("symbol", "+")]
Example #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")]
Example #23
0
def parse_classVarDecs(src):
    return parsing.ManyP(project_10.ClassVarDecP).parse(project_10.lex(src))
Example #24
0
def test_keyword():
    tokens = project_10.lex("do")

    assert tokens == [("keyword", "do")]
Example #25
0
def parse_subroutineDec(src):
    return project_10.SubroutineDecP.parse(project_10.lex(src))
Example #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", "}"),
    ]