コード例 #1
0
def test_if_expression():
    source = "if (x < y) { x }"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.IfExpression

    assert stmt.expression.condition.left.value == "x"

    assert stmt.expression.condition.operator == "<"

    assert stmt.expression.condition.right.value == "y"

    # TODO Finish defining me please

    assert len(stmt.expression.consequence.statements) == 1
コード例 #2
0
def start():
    env = object.Environment()
    while True:
        line = input(prompt)
        l = Lexer(line)
        p = Parser(l)
        program = p.parse_program()
        val = evaluator.eval(program, env)
        print(val)
コード例 #3
0
def test_string_literal_expression():
    source = '"hello world";'
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    assert isinstance(stmt.expression, ast.StringLiteral)
    assert stmt.expression.value == "hello world"
コード例 #4
0
def test_parsing_empty_hash_literal():
    source = "{}"

    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    hash_literal = stmt.expression
    assert isinstance(hash_literal, ast.HashLiteral)
    assert len(hash_literal.pairs) == 0
コード例 #5
0
def test_function_parameter_parsing(source, expected):
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert type(stmt) == ast.ExpressionStatement
    assert type(stmt.expression) == ast.FunctionLiteral

    func: ast.FunctionLiteral = stmt.expression

    assert len(func.params) == len(expected)
コード例 #6
0
def test_call_expression_parsing():
    source = "add(1, 2 * 3, 4 + 5);"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert isinstance(stmt, ast.ExpressionStatement)

    assert isinstance(stmt.expression, ast.CallExpression)

    assert stmt.expression.function.value == "add"

    assert len(stmt.expression.arguments) == 3

    assert stmt.expression == ast.CallExpression(
        token=Token(tok_type="(", literal="("),
        function=ast.Identifier(token=Token(tok_type="IDENT", literal="add"),
                                value="add"),
        arguments=[
            ast.IntegerLiteral(token=Token(tok_type="INT", literal="1"),
                               value=1),
            ast.InfixExpression(
                token=Token(tok_type="*", literal="*"),
                left=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                    literal="2"),
                                        value=2),
                operator="*",
                right=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                     literal="3"),
                                         value=3),
            ),
            ast.InfixExpression(
                token=Token(tok_type="+", literal="+"),
                left=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                    literal="4"),
                                        value=4),
                operator="+",
                right=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                     literal="5"),
                                         value=5),
            ),
        ],
    )

    assert str(stmt.expression) == "add(1, (2 * 3), (4 + 5))"
コード例 #7
0
    def test_let_statements(self):
        input = '''
            let x = 5;
            let y = 10;
            let foobar = 838383;
        '''

        parser = Parser(input)

        program = parser.parse_program()

        assert program is not None
        assert len(program.statements) == 3
コード例 #8
0
def test_parsing_array_literal():
    source = "[1, 2 * 2, 3 + 3];"
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    array = stmt.expression
    assert isinstance(array, ast.ArrayLiteral)
    assert len(array.elements) == 3
    literal = array.elements[0]
    assert literal.value == 1
    assert literal.token_literal() == "1"
コード例 #9
0
def test_parsing_index_expressions():
    source = "myArray[1 + 1]"
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    expression = stmt.expression
    assert isinstance(expression, ast.IndexExpression)
    left = expression.left
    assert isinstance(left, ast.Identifier)
    assert left.value == "myArray"
    assert left.token_literal() == "myArray"
    check_infix_expression(expression.index, 1, "+", "1")
コード例 #10
0
def test_let_statements(source, expected_identifier, expected_value):
    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert program is not None

    assert len(program.statements) == 1

    stmt = program.statements[0]

    check_let_statement(stmt, expected_identifier)

    assert stmt.value.value == expected_value
コード例 #11
0
def test_parsing_hash_literal():
    source = '{"one": 1, "two": 2, "three": 3}'
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    hash_literal = stmt.expression
    assert isinstance(hash_literal, ast.HashLiteral)

    assert len(hash_literal.pairs) == 3

    expected = {"one": 1, "two": 2, "three": 3}

    for key, value in hash_literal.pairs.items():
        assert isinstance(key, ast.StringLiteral)
        check_integer_literal(value, expected[str(key)])
コード例 #12
0
def test_prefix_expressions(source, operator, expected):
    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.PrefixExpression

    assert stmt.expression.operator == operator

    assert stmt.expression.right.value == expected
コード例 #13
0
def test_function_literal_parsing():

    source = "fn(x, y) { x + y; }"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.FunctionLiteral

    assert [str(s) for s in stmt.expression.params] == ["x", "y"]
コード例 #14
0
def test_return_statements():
    source = """
    return 5;
    return 10;
    return 993322;
    """

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert program is not None

    assert len(program.statements) == 3

    for stmt in program.statements:
        assert type(stmt) == ast.ReturnStatement
        assert stmt.token_literal() == "return"
コード例 #15
0
def test_integer_literals():
    source = "5;"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.IntegerLiteral

    literal = stmt.expression

    assert literal.value == 5
    assert literal.token_literal() == "5"
コード例 #16
0
def test_identifier_expression():
    source = "foobar;"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.Identifier

    ident = stmt.expression

    assert ident.value == "foobar"
    assert ident.token_literal() == "foobar"
コード例 #17
0
def test_boolean_expression():
    source = "true;"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert type(stmt) == ast.ExpressionStatement

    assert type(stmt.expression) == ast.Boolean

    ident = stmt.expression

    assert ident.value == True
    assert ident.token_literal() == "true"
コード例 #18
0
def test_parsing_hash_literal_with_expressions():
    source = '{"one": 0 + 1, "two": 10 - 8, "three": 15 / 5}'
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    stmt = program.statements[0]
    assert isinstance(stmt, ast.ExpressionStatement)
    hash_literal = stmt.expression
    assert isinstance(hash_literal, ast.HashLiteral)

    assert len(hash_literal.pairs) == 3

    tests = {
        "one": lambda e: check_infix_expression(e, 0, "+", 1),
        "two": lambda e: check_infix_expression(e, 10, "-", 8),
        "three": lambda e: check_infix_expression(e, 15, "/", 5),
    }

    for key, value in hash_literal.pairs.items():
        assert isinstance(key, ast.StringLiteral)
        test_fn = tests[str(key)]
        test_fn(value)
コード例 #19
0
def main():

    hist_file = Path("~/.monkeyhist").expanduser()

    # Create history file if it doesn't exist already
    if not hist_file.exists():
        hist_file.touch()

    session = PromptSession(history=FileHistory(hist_file),
                            completer=monkey_completer,
                            style=style)

    env = {}

    while True:
        try:
            scanned = session.prompt(">> ",
                                     lexer=PygmentsLexer(JavascriptLexer))
        except KeyboardInterrupt:
            continue
        except EOFError:
            break
        else:
            lexer = Lexer(scanned)
            parser = Parser(lexer)
            program = parser.parse_program()
            if parser.errors:
                for error in parser.errors:
                    print(error)
            evaluated = Eval(program, env)
            session.completer = WordCompleter(
                list(set(token.keywords) | set(env)))
            if evaluated is not None:
                print(evaluated.inspect())

    print("Farewell!")
コード例 #20
0
def check_eval(source: str) -> monkey_object.Object:
    lexer = Lexer(source)
    parser = Parser(lexer)
    program = parser.parse_program()
    return Eval(program, {})
コード例 #21
0
def test_parse_identifier():
    parser = Parser(Lexer("a"))
    p = parser.parse_program()
    assert len(p.statements) == 1
    assert p.statements[0].token.type == token.IDENT
    assert p.statements[0].token.literal == 'a'
コード例 #22
0
def test_operator_precedence_parsing(source, expected):
    l = Lexer(source)
    p = Parser(l)
    program = p.parse_program()
    assert p.errors == []
    assert str(program) == expected