示例#1
0
def test_parse_arithmetic():
    result = parser.parse('x * (y + z);')
    assert result == Block([Stmt(BinOp('*', Variable('x'),
                                       BinOp('+', Variable('y'), Variable('z'))))])

    result = parser.parse('z + x * y;')
    assert result == Block([Stmt(BinOp('+', Variable('z'),
                                       BinOp('*', Variable('x'), Variable('y'))))])

    result = parser.parse('z * x + y;')
    assert result == Block([Stmt(BinOp('+',
                                       BinOp('*', Variable('z'), Variable('x')), Variable('y')))])

    result = parser.parse('x > z + x * y;')
    assert result == Block([Stmt(BinOp('>', Variable('x'),
                                       BinOp('+', Variable('z'),
                                             BinOp('*', Variable('x'), Variable('y')))))])

    result = parser.parse('(x + y) / x + 3;')
    assert result == Block([Stmt(BinOp('+',
                                       BinOp(
                                           '/',
                                           BinOp(
                                               '+',
                                               Variable('x'),
                                               Variable('y')),
                                           Variable('x')),
                                       ConstantNum(3.0)))])
示例#2
0
def test_parse_return():
    result = parser.parse('function foo(x, y, z) { return; };')
    assert result == Block([Stmt(FnDef('foo', ['x', 'y', 'z'],
                                       Block([Return()]), None, 0))])

    result = parser.parse('function foo(x, y, z) { return x + y; };')
    assert result == Block([Stmt(FnDef('foo', ['x', 'y', 'z'],
                                       Block([Return(BinOp('+', Variable('x'), Variable('y')))]), None, 0))])
示例#3
0
def test_parse_if():
    result = parser.parse('if (y) { x = 10; }')
    assert result == Block([If(Variable('y'),
                               Block([Assignment('x', ConstantNum(10.0))]))])

    result = parser.parse('if (y) { x = 10; } else { x = 12; }')
    assert result == Block([If(Variable('y'),
                               Block([Assignment('x', ConstantNum(10.0))]),
                               Block([Assignment('x', ConstantNum(12.0))]))])
示例#4
0
def test_paser_assignment():
    result = parser.parse('x_y = x;')
    assert result == \
        Block([Assignment('x_y', Variable('x'))])
    result = parser.parse('PI = 3.14;')
    assert result == \
        Block([Assignment('PI', ConstantNum(3.14))])
    with pytest.raises(parser.ParseError):
        parser.parse('1.0 = x;')
示例#5
0
def test_parse_variable():
    for var_name in ('x', 'X', '_', 'foo', 'Fo', '_123'):
        result = parser.parse('%s;' % var_name)
        assert result == Block([Stmt(Variable(var_name))])
    for invalid_var_name in ('0x', '123ss'):
        with pytest.raises(parser.ParseError):
            parser.parse('%s;' % invalid_var_name)
    for invalid_var_name in ('%',):
        with pytest.raises(parser.ParseError):
            parser.parse('%s;' % invalid_var_name)
    for not_var_name in ('123',):
        assert result != Block([Stmt(Variable(not_var_name))])
示例#6
0
def test_parse_fn_def():
    result = parser.parse('function foo() { };')
    assert result == Block([Stmt(FnDef('foo', [], Block([]), None, 0))])

    result = parser.parse('''

    function foo(x) { x + y; };
    ''', filename='foo.js')
    assert result == Block([Stmt(FnDef('foo', ['x'],
                                       Block(
                                           [Stmt(BinOp('+', Variable('x'), Variable('y')))]),
                                       'foo.js', 2))])

    result = parser.parse('function foo(x){};')
    assert result == Block([Stmt(FnDef('foo', ['x'], Block([]), None, 0))])

    result = parser.parse('function foo(){x;};')
    assert result == Block([Stmt(FnDef('foo', [], Block([
        Stmt(Variable('x'))]), None, 0))])

    result = parser.parse('function foo(x, y, z) { x + y; };')
    assert result == Block([Stmt(FnDef('foo', ['x', 'y', 'z'],
                                       Block([Stmt(BinOp('+', Variable('x'), Variable('y')))]), None, 0))])
示例#7
0
def test_parse_fn_call():
    result = parser.parse('foo();')
    assert result == Block([Stmt(Call(Variable('foo'), []))])

    result = parser.parse('print(x);')
    assert result == Block([Stmt(Call(Variable('print'), [Variable('x')]))])

    result = parser.parse('foo(1);')
    assert result == Block([Stmt(Call(Variable('foo'), [ConstantNum(1.0)]))])

    result = parser.parse('foo(1 + 2);')
    assert result == Block([Stmt(Call(Variable('foo'),
                                      [BinOp('+', ConstantNum(1.0), ConstantNum(2.0))]))])

    result = parser.parse('foo(x + y);')
    assert result == Block([Stmt(Call(Variable('foo'),
                                      [BinOp('+', Variable('x'), Variable('y'))]))])

    result = parser.parse('foo(f(x) + y);')
    assert result == Block([Stmt(Call(Variable('foo'),
                                      [BinOp('+', Call(Variable('f'), [Variable('x')]), Variable('y'))]))])
    result = parser.parse('foo(f(x), y);')
    assert result == Block([Stmt(Call(Variable('foo'),
                                      [Call(Variable('f'), [Variable('x')]), Variable('y')]))])

    result = parser.parse('foo(1, f(x), y);')
    assert result == Block([Stmt(Call(Variable('foo'), [
        ConstantNum(1.0),
        Call(Variable('f'), [Variable('x')]),
        Variable('y')]))])

    result = parser.parse('foo(1, f(x), y, z, y);')
    assert result == Block([Stmt(Call(Variable('foo'), [
        ConstantNum(1.0),
        Call(Variable('f'), [Variable('x')]),
        Variable('y'),
        Variable('z'),
        Variable('y'),
    ]))])
示例#8
0
def test_get_location():
    filename = '_for_test_jit.js'
    source = '''
    function foo(x, y) {
        return x + y;
    };
    x = 3;
    foo(1, x);
    '''
    ast = parser.parse(source, filename=filename)
    bc = CompilerContext.compile_ast(ast, co_filename=filename)
    assert bc.code == to_code([
        LOAD_CONSTANT_FN, 0,
        ASSIGN, 0,
        LOAD_CONSTANT_FN, 0,
        DISCARD_TOP, 0,
        LOAD_CONSTANT_FLOAT, 0,
        ASSIGN, 1,
        LOAD_VAR, 0,
        LOAD_CONSTANT_FLOAT, 1,
        LOAD_VAR, 1,
        CALL, 2,
        DISCARD_TOP, 0,
        RETURN, 0])
    assert bc.co_name == '__main__'
    assert bc.co_filename == '_for_test_jit.js'
    assert bc.co_firstlineno == 0
    inner_bc = bc.constants_fn[0]
    assert inner_bc.code == to_code([
        LOAD_VAR, 0,
        LOAD_VAR, 1,
        BINARY_ADD, 0,
        RETURN, 1])
    assert inner_bc.co_name == 'foo'
    assert inner_bc.co_filename == '_for_test_jit.js'
    assert inner_bc.co_firstlineno == 1
    assert get_printable_location(0, bc.code, bc) == \
        "<code object __main__, file '_for_test_jit.js', line 1> #0 LOAD_CONSTANT_FN"
    assert get_printable_location(2, bc.code, bc) == \
        "<code object __main__, file '_for_test_jit.js', line 1> #2 ASSIGN"
    assert get_printable_location(0, inner_bc.code, inner_bc) == \
        "<code object foo, file '_for_test_jit.js', line 2> #0 LOAD_VAR"
    assert get_printable_location(4, inner_bc.code, inner_bc) == \
        "<code object foo, file '_for_test_jit.js', line 2> #4 BINARY_ADD"
示例#9
0
def test_parse_binop():
    result = parser.parse('x = 1 + 2;')
    assert result == Block([Assignment('x',
                                       BinOp('+', ConstantNum(1.0), ConstantNum(2.0)))])
    result = parser.parse('x = x - 2;')
    assert result == Block([Assignment('x',
                                       BinOp('-', Variable('x'), ConstantNum(2.0)))])
    result = parser.parse('x = 1+2;')
    assert result == Block([Assignment('x',
                                       BinOp('+', ConstantNum(1.0), ConstantNum(2.0)))])
    result = parser.parse('x = x-2;')
    assert result == Block([Assignment('x',
                                       BinOp('-', Variable('x'), ConstantNum(2.0)))])
    result = parser.parse('x = y % 2;')
    assert result == Block([Assignment('x',
                                       BinOp('%', Variable('y'), ConstantNum(2.0)))])
    result = parser.parse('while (x == y) { }')
    assert result == Block([While(
        BinOp('==', Variable('x'), Variable('y')), Block([]))])
示例#10
0
def interpret_source(source, filename=None):
    ast = parser.parse(source, filename=filename)
    bc = bytecode.CompilerContext.compile_ast(ast)
    return interpret(bc)
示例#11
0
def test_parse_while():
    result = parser.parse('while (1) { a = 3; }')
    assert result == Block([While(ConstantNum(1.0),
                                  Block([Assignment('a', ConstantNum(3))]))])
    result = parser.parse('while (1) { }')
    assert result == Block([While(ConstantNum(1.0), Block([]))])
示例#12
0
def test_parse_number():
    for num, value in [
            ('0', 0.0), ('1', 1.0), ('.123', .123), ('123.123', 123.123),
            ('+12', 12.0), ('-.12', -0.12)]:
        result = parser.parse('%s;' % num)
        assert result == Block([Stmt(ConstantNum(value))])