Ejemplo n.º 1
0
def test_cond():
    """Ensure we evaluate cond properly."""
    env = prelude.env()
    call = wtypes.List([
        wtypes.List([
            wtypes.String('two'),
            wtypes.List(
                [wtypes.Integer(2),
                 wtypes.Integer(2),
                 wtypes.Symbol('eq?')])
        ]),
        wtypes.List([
            wtypes.String('one'),
            wtypes.List(
                [wtypes.Integer(1),
                 wtypes.Integer(1),
                 wtypes.Symbol('eq?')])
        ]),
        wtypes.List([
            wtypes.String('not-one'),
            wtypes.List(
                [wtypes.Integer(2),
                 wtypes.Integer(1),
                 wtypes.Symbol('eq?')])
        ]),
        wtypes.Symbol('cond')
    ])
    result = call.eval(env)
    assert result == wtypes.String('one')
Ejemplo n.º 2
0
def test_get_nearest():
    """Ensure we get bindings past the top frame."""
    env = wisp.env.Environment()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('apple'))
    env.add_frame()
    env.add_frame()

    assert env[wtypes.Symbol('a')] == wtypes.String('apple')
Ejemplo n.º 3
0
def test_atom():
    """Ensure atom indicates atomicity."""
    env = prelude.env()

    assert env[wtypes.Symbol('atom?')].call([wtypes.Integer(1)],
                                            env) == wtypes.Bool(True)

    assert env[wtypes.Symbol('atom?')].call([quoted_list([wtypes.Integer(1)])],
                                            env) == wtypes.Bool(False)
Ejemplo n.º 4
0
def test_empty_car_and_cdr():
    """Ensure car and cdr raise an error on empty lists."""
    env = prelude.env()

    with pytest.raises(exceptions.WispException):
        env[wtypes.Symbol('car')].call([quoted_list([])], env)

    with pytest.raises(exceptions.WispException):
        env[wtypes.Symbol('cdr')].call([quoted_list([])], env)
Ejemplo n.º 5
0
def test_define():
    """Ensure define binds values to symbols."""
    env = prelude.env()

    res = env[wtypes.Symbol('define')].call(
        [wtypes.Symbol('a'),
         quoted_list([wtypes.String('apple')])], env)
    assert res == wtypes.Symbol('a')
    assert env[wtypes.Symbol('a')] == wtypes.List([wtypes.String('apple')])
Ejemplo n.º 6
0
def test_equal():
    """Ensure equal tests equality properly."""
    assert prelude.env()[wtypes.Symbol('eq?')].call(
        [wtypes.Integer(4), wtypes.Integer(4)], {}) == wtypes.Bool(True)

    assert prelude.env()[wtypes.Symbol('eq?')].call(
        [wtypes.Integer(4), wtypes.Integer(2)], {}) == wtypes.Bool(False)

    assert prelude.env()[wtypes.Symbol('eq?')].call(
        [wtypes.Integer(4), wtypes.String('abc')], {}) == wtypes.Bool(False)
Ejemplo n.º 7
0
def test_parse_list():
    """Ensure we can parse lists."""
    assert parser.parse_expr.parse('(1    abc "abc" #t #f +)') == wtypes.List([
        wtypes.Integer(1),
        wtypes.Symbol('abc'),
        wtypes.String('abc'),
        wtypes.Bool(True),
        wtypes.Bool(False),
        wtypes.Symbol('+'),
    ])
Ejemplo n.º 8
0
def test_set():
    """Ensure set mutates bindings."""
    env = prelude.env()

    # ensure we can't set non-existent bindings
    bad_call = wtypes.List(
        [wtypes.Integer(1),
         wtypes.Symbol('x'),
         wtypes.Symbol('set!')])
    with pytest.raises(exceptions.WispException):
        assert bad_call.eval(env)

    # ensure we can set previously-existent bindings
    define_call = wtypes.List(
        [wtypes.Integer(1),
         wtypes.Symbol('x'),
         wtypes.Symbol('define')])
    define_call.eval(env)
    assert wtypes.Symbol('x').eval(env) == wtypes.Integer(1)

    set_call = wtypes.List(
        [wtypes.Integer(2),
         wtypes.Symbol('x'),
         wtypes.Symbol('set!')])
    set_call.eval(env)
    assert wtypes.Symbol('x').eval(env) == wtypes.Integer(2)
Ejemplo n.º 9
0
def test_set_bindings():
    """Ensure we set bindings in the current frame."""
    env = wisp.env.Environment()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('apple'))

    env.add_frame()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('aardvark'))

    env[wtypes.Symbol('a')] = wtypes.String('adorno')

    assert env[wtypes.Symbol('a')] == wtypes.String('adorno')

    env.pop_frame()
    assert env[wtypes.Symbol('a')] == wtypes.String('apple')
Ejemplo n.º 10
0
def cond(args: typing.List[wtypes.Expression],
         env: wisp.env.Environment) -> wtypes.Expression:
    """Return the expression associated with the first test to return true."""
    for arg in args:
        if not isinstance(arg, wtypes.List):
            raise exceptions.WispException('invalid cond form: %s' % args)
        elif len(arg.items) != 2:
            raise exceptions.WispException('invalid cond form: %s' % args)

        body, test = arg.items
        if (test == wtypes.Symbol('else') or
                test.eval(env) == wtypes.Bool(True)):
            return body.eval(env)
    else:
        return wtypes.Symbol('unspecified return value')
Ejemplo n.º 11
0
def test_begin():
    """Ensure begin return the last expression."""
    env = prelude.env()
    call = wtypes.List([
        wtypes.List([
            wtypes.Integer(1),
            wtypes.Integer(2),
            wtypes.Symbol('+'),
        ]),
        wtypes.List([
            wtypes.Integer(1),
            wtypes.Integer(1),
            wtypes.Symbol('+'),
        ]),
        wtypes.Symbol('begin')
    ])
    assert call.eval(env) == wtypes.Integer(3)
Ejemplo n.º 12
0
def test_bad_lambda():
    """Ensure we handle lambdas which raise exceptions."""
    env = prelude.env()

    # define a lambda calling a non-existent symbol
    bad_lambda = env[wtypes.Symbol('lambda')].call([
        wtypes.List([wtypes.Symbol('x')]),
        wtypes.List([wtypes.Symbol('snakes')])
    ], env)

    # raise an exception when we call it
    call = wtypes.List([wtypes.Integer(2), bad_lambda])
    with pytest.raises(exceptions.WispException):
        call.eval(env)

    # ensure we didn't pollute even though the call raised an exception
    with pytest.raises(exceptions.WispException):
        env[wtypes.Symbol('x')]
Ejemplo n.º 13
0
def test_cdr():
    """Ensure cdr takes the rest."""
    env = prelude.env()
    res = env[wtypes.Symbol('cdr')].call([
        quoted_list([wtypes.Integer(1),
                     wtypes.Integer(2),
                     wtypes.Integer(3)])
    ], env)
    assert res == wtypes.List([wtypes.Integer(2), wtypes.Integer(3)])
Ejemplo n.º 14
0
def test_eval_list():
    """Ensure lists are evaluated as post-fix function calls."""
    env = wisp.env.Environment({'+': wtypes.Function(
        lambda xs, _: wtypes.Integer(xs[0].val + xs[1].val)
    )})
    res = wtypes.List([
            wtypes.Integer(1), wtypes.Integer(2), wtypes.Symbol('+')
    ]).eval(env)
    assert res == wtypes.Integer(3)
Ejemplo n.º 15
0
def test_cons():
    """Ensure cons sticks things together."""
    env = prelude.env()
    res = env[wtypes.Symbol('cons')].call([
        wtypes.Integer(1),
        quoted_list([wtypes.Integer(2), wtypes.Integer(3)])
    ], env)
    assert res == wtypes.List(
        [wtypes.Integer(1),
         wtypes.Integer(2),
         wtypes.Integer(3)])
Ejemplo n.º 16
0
def test_local_global_scope():
    """Ensure we return the local and global scope properly."""
    env = wisp.env.Environment()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('apple'))

    env.add_frame()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('aardvark'))

    env.add_frame()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('adorno'))

    assert env.global_scope() == {'a': wtypes.String('apple')}
    assert env.local_scope() == {'a': wtypes.String('adorno')}

    env.pop_frame()
    assert env.global_scope() == {'a': wtypes.String('apple')}
    assert env.local_scope() == {'a': wtypes.String('aardvark')}

    env.pop_frame()
    assert env.global_scope() == {'a': wtypes.String('apple')}
    assert env.local_scope() == {}
Ejemplo n.º 17
0
def test_cond_with_else():
    """Ensure we handle else expressions."""
    env = prelude.env()
    call = wtypes.List([
        wtypes.List([wtypes.String('else-case'),
                     wtypes.Symbol('else')]),
        wtypes.List([
            wtypes.String('not-two'),
            wtypes.List(
                [wtypes.Integer(3),
                 wtypes.Integer(2),
                 wtypes.Symbol('eq?')])
        ]),
        wtypes.List([
            wtypes.String('not-one'),
            wtypes.List(
                [wtypes.Integer(2),
                 wtypes.Integer(1),
                 wtypes.Symbol('eq?')])
        ]),
        wtypes.Symbol('cond')
    ])
    result = call.eval(env)
    assert result == wtypes.String('else-case')
Ejemplo n.º 18
0
def test_get_add_binding():
    """Ensure we get the binding from the top frame."""
    env = wisp.env.Environment()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('apple'))

    env.add_frame()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('aardvark'))

    env.add_frame()
    env.add_binding(wtypes.Symbol('a'), wtypes.String('adorno'))

    assert env[wtypes.Symbol('a')] == wtypes.String('adorno')

    env.pop_frame()
    assert env[wtypes.Symbol('a')] == wtypes.String('aardvark')

    env.pop_frame()
    assert env[wtypes.Symbol('a')] == wtypes.String('apple')
Ejemplo n.º 19
0
def test_lambda():
    """Ensure lambdas can be defined and called."""
    env = prelude.env()

    # define a lambda performing x - y
    sub_lambda = env[wtypes.Symbol('lambda')].call([
        wtypes.List([wtypes.Symbol('x'),
                     wtypes.Symbol('y')]),
        wtypes.List(
            [wtypes.Symbol('y'),
             wtypes.Symbol('x'),
             wtypes.Symbol('-')]),
    ], env)

    # ensure we can call the above lambda
    call = wtypes.List([wtypes.Integer(1), wtypes.Integer(3), sub_lambda])
    res = call.eval(env)
    assert res == wtypes.Integer(2)

    # ensure we didn't pollute the environment with bindings from the call.
    with pytest.raises(exceptions.WispException):
        env[wtypes.Symbol('x')]
Ejemplo n.º 20
0
def test_mul():
    """Ensure mul maths properly."""
    res = prelude.env()[wtypes.Symbol('*')].call(
        [wtypes.Integer(3), wtypes.Integer(2)], {})
    assert res == wtypes.Integer(6)
Ejemplo n.º 21
0
def test_eval_missing_symbol():
    """Ensure an error is raised on missing symbols."""
    env = wisp.env.Environment({'a': wtypes.String('def')})
    with pytest.raises(exceptions.WispException):
        wtypes.Symbol('b').eval(env)
Ejemplo n.º 22
0
def test_eval_symbol():
    """Ensure symbols evaluate to their bound value."""
    env = wisp.env.Environment({'a': wtypes.String('def')})
    assert wtypes.Symbol('a').eval(env) == wtypes.String('def')
Ejemplo n.º 23
0
def test_parse_symbol():
    """Ensure we can parse symbols."""
    assert parser.parse_expr.parse('abc') == wtypes.Symbol('abc')
Ejemplo n.º 24
0
def test_add():
    """Ensure add maths properly."""
    res = prelude.env()[wtypes.Symbol('+')].call(
        [wtypes.Integer(1), wtypes.Integer(2)], {})
    assert res == wtypes.Integer(3)
Ejemplo n.º 25
0
def test_sub():
    """Ensure sub maths properly."""
    res = prelude.env()[wtypes.Symbol('-')].call(
        [wtypes.Integer(3), wtypes.Integer(1)], {})
    assert res == wtypes.Integer(2)
Ejemplo n.º 26
0
def test_quote():
    """Ensure quote does nothing."""
    assert prelude.env()[wtypes.Symbol('quote')].call(
        [wtypes.Symbol('abc')], {}) == wtypes.Symbol('abc')
Ejemplo n.º 27
0
def quoted_list(elems):
    """Build a quoted list consisting of the given elements, safe from eval."""
    return wtypes.List([wtypes.List(elems), wtypes.Symbol('quote')])
Ejemplo n.º 28
0
def test_recursion():
    """Ensure we can handle simple recursion."""
    env = prelude.env()
    fib_def = wtypes.List([
        wtypes.List([
            wtypes.List([
                wtypes.List([
                    wtypes.List([
                        wtypes.List([
                            wtypes.List([
                                wtypes.Integer(2),
                                wtypes.Symbol('n'),
                                wtypes.Symbol('-')
                            ]),
                            wtypes.Symbol('fib')
                        ]),
                        wtypes.List([
                            wtypes.List([
                                wtypes.Integer(1),
                                wtypes.Symbol('n'),
                                wtypes.Symbol('-')
                            ]),
                            wtypes.Symbol('fib')
                        ]),
                        wtypes.Symbol('+')
                    ]),
                    wtypes.Symbol('else')
                ]),
                wtypes.List([
                    wtypes.Integer(1),
                    wtypes.List([
                        wtypes.Integer(1),
                        wtypes.Symbol('n'),
                        wtypes.Symbol('eq?')
                    ])
                ]),
                wtypes.List([
                    wtypes.Integer(0),
                    wtypes.List([
                        wtypes.Integer(0),
                        wtypes.Symbol('n'),
                        wtypes.Symbol('eq?')
                    ])
                ]),
                wtypes.Symbol('cond')
            ]),
            wtypes.List([wtypes.Symbol('n')]),
            wtypes.Symbol('lambda')
        ]),
        wtypes.Symbol('fib'),
        wtypes.Symbol('define'),
    ])
    fib_def.eval(env)

    call = wtypes.List([wtypes.Integer(0), wtypes.Symbol('fib')])
    assert call.eval(env) == wtypes.Integer(0)

    call = wtypes.List([wtypes.Integer(1), wtypes.Symbol('fib')])
    assert call.eval(env) == wtypes.Integer(1)

    call = wtypes.List([wtypes.Integer(5), wtypes.Symbol('fib')])
    assert call.eval(env) == wtypes.Integer(5)

    call = wtypes.List([wtypes.Integer(6), wtypes.Symbol('fib')])
    assert call.eval(env) == wtypes.Integer(8)

    call = wtypes.List([wtypes.Integer(7), wtypes.Symbol('fib')])
    assert call.eval(env) == wtypes.Integer(13)
Ejemplo n.º 29
0
def test_closures():
    """Ensure we handle closures properly."""
    env = prelude.env()
    counter_def = wtypes.List([
        wtypes.List([
            wtypes.List([
                wtypes.List([
                    wtypes.Symbol('x'),
                    wtypes.List([
                        wtypes.List([
                            wtypes.Integer(1),
                            wtypes.Symbol('x'),
                            wtypes.Symbol('+')
                        ]),
                        wtypes.Symbol('x'),
                        wtypes.Symbol('set!')
                    ]),
                    wtypes.Symbol('begin')
                ]),
                wtypes.List([]),
                wtypes.Symbol('lambda')
            ]),
            wtypes.List([wtypes.Symbol('x')]),
            wtypes.Symbol('lambda')
        ]),
        wtypes.Symbol('make-counter'),
        wtypes.Symbol('define'),
    ])
    counter_def.eval(env)

    counter = wtypes.List([
        wtypes.List([wtypes.Integer(0),
                     wtypes.Symbol('make-counter')]),
        wtypes.Symbol('c'),
        wtypes.Symbol('define'),
    ])
    counter.eval(env)

    call = wtypes.List([wtypes.Symbol('c')])

    assert call.eval(env) == wtypes.Integer(1)
    assert call.eval(env) == wtypes.Integer(2)
    assert call.eval(env) == wtypes.Integer(3)

    # ensure 'x' from the closure hasn't leaked into the global scope.
    with pytest.raises(exceptions.WispException):
        env[wtypes.Symbol('x')]
Ejemplo n.º 30
0
def test_div():
    """Ensure div maths properly."""
    res = prelude.env()[wtypes.Symbol('/')].call(
        [wtypes.Integer(4), wtypes.Integer(2)], {})
    assert res == wtypes.Integer(2)