Ejemplo n.º 1
0
def test_recursive_macro():
    ctx = ExecutionContext()
    eval_(
        ctx, """(define-syntax my-or
                                 (syntax-rules ()
                                    ((my-or) #f)
                                    ((my-or arg) arg)
                                    ((my-or arg1 arg2)
                                     (if arg1
                                         arg1
                                         (my-or arg2)))
                                    ((my-or arg1 arg2 arg3)
                                     (if arg1
                                         arg1
                                         (my-or arg2 arg3)))))""")

    assert eval_(ctx, "(my-or)").to_boolean() is False
    assert eval_(ctx, "(my-or 12)").to_number() == 12

    #should expand recursively and after that eval
    w_expr = parse_("(my-or 12 42)")
    assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
            "(if 12 12 42)"
    w_expr = parse_("(my-or 12 42 82)")
    assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
            "(if 12 12 (if 42 42 82))"
    assert eval_(ctx, "(my-or 12 42)").to_number() == 12
    assert eval_(ctx, "(my-or #f 42)").to_number() == 42
    assert eval_(ctx, "(my-or #f #f 82)").to_number() == 82
Ejemplo n.º 2
0
def test_recursive_macro():
    ctx = ExecutionContext()
    eval_(ctx, """(define-syntax my-or
                                 (syntax-rules ()
                                    ((my-or) #f)
                                    ((my-or arg) arg)
                                    ((my-or arg1 arg2)
                                     (if arg1
                                         arg1
                                         (my-or arg2)))
                                    ((my-or arg1 arg2 arg3)
                                     (if arg1
                                         arg1
                                         (my-or arg2 arg3)))))""")

    assert eval_(ctx, "(my-or)").to_boolean() is False
    assert eval_(ctx, "(my-or 12)").to_number() == 12

    #should expand recursively and after that eval
    w_expr = parse_("(my-or 12 42)")
    assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
            "(if 12 12 42)"
    w_expr = parse_("(my-or 12 42 82)")
    assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
            "(if 12 12 (if 42 42 82))"
    assert eval_(ctx, "(my-or 12 42)").to_number() == 12
    assert eval_(ctx, "(my-or #f 42)").to_number() == 42
    assert eval_(ctx, "(my-or #f #f 82)").to_number() == 82
def test_loop():
    ctx = ExecutionContext()

    eval_(ctx, "(define k 'none)")
    eval_(ctx, "(define num 'none)")
    w_result = eval_(
        ctx,
        """
        (call/cc
            (lambda (return)
                (letrec ((loop
                          (lambda (n)
                            (if (zero? n)
                                0
                                (begin
                                  (call/cc (lambda (cc)
                                             (set! k cc)
                                             (return n)))
                                  (set! num n)
                                  (loop (- n 1)))))))
                      (loop 10))))""",
    )

    assert w_result.to_number() == 10
    assert isinstance(ctx.get("k"), Continuation)
    assert ctx.get("num").to_string() == "none"

    for i in range(9, -1, -1):
        w_result = eval_(ctx, "(k)")
        assert w_result.to_number() == i
        assert ctx.get("num").to_number() == i + 1

    w_result = eval_(ctx, "(k)")
    assert w_result.to_number() == 0
    assert ctx.get("num").to_number() == 1
Ejemplo n.º 4
0
def test_loop():
    ctx = ExecutionContext()

    eval_(ctx, "(define k 'none)")
    eval_(ctx, "(define num 'none)")
    w_result = eval_(
        ctx, """
        (call/cc
            (lambda (return)
                (letrec ((loop
                          (lambda (n)
                            (if (zero? n)
                                0
                                (begin
                                  (call/cc (lambda (cc)
                                             (set! k cc)
                                             (return n)))
                                  (set! num n)
                                  (loop (- n 1)))))))
                      (loop 10))))""")

    assert w_result.to_number() == 10
    assert isinstance(ctx.get("k"), Continuation)
    assert ctx.get("num").to_string() == "none"

    for i in range(9, -1, -1):
        w_result = eval_(ctx, "(k)")
        assert w_result.to_number() == i
        assert ctx.get("num").to_number() == i + 1

    w_result = eval_(ctx, "(k)")
    assert w_result.to_number() == 0
    assert ctx.get("num").to_number() == 1
Ejemplo n.º 5
0
def test_let_define():
    ctx = ExecutionContext()

    eval_(
        ctx, """(define oo
                          (let ((cont (call/cc (lambda (k) k))))
                               cont))""")
    assert isinstance(ctx.get("oo"), Continuation)
    eval_(ctx, "(oo +)")
    assert ctx.get("oo") is ctx.get("+")
Ejemplo n.º 6
0
def test_ctx():
    w_fnum = W_Integer(12)
    w_symb = W_Symbol("symb")

    ctx = ExecutionContext()
    ctx.put("v1", w_fnum)
    ctx.put("symb", w_symb)

    assert w_symb is ctx.get("symb")
    assert w_fnum is ctx.get("v1")
    py.test.raises(UnboundVariable, ctx.get, "no_such_key")
Ejemplo n.º 7
0
def test_ctx():
    w_fnum = W_Integer(12)
    w_symb = W_Symbol("symb")

    ctx = ExecutionContext()
    ctx.put("v1", w_fnum)
    ctx.put("symb", w_symb)

    assert w_symb is ctx.get("symb")
    assert w_fnum is ctx.get("v1")
    py.test.raises(UnboundVariable, ctx.get, "no_such_key")
def test_let_define():
    ctx = ExecutionContext()

    eval_(
        ctx,
        """(define oo
                          (let ((cont (call/cc (lambda (k) k))))
                               cont))""",
    )
    assert isinstance(ctx.get("oo"), Continuation)
    eval_(ctx, "(oo +)")
    assert ctx.get("oo") is ctx.get("+")
Ejemplo n.º 9
0
def test_if_evaluation():
    ctx = ExecutionContext()
    eval_(ctx, "(define then #f)")
    eval_(ctx, "(define else #f)")
    eval_(ctx, "(if #t (define then #t) (define else #t))")
    assert ctx.get("then").to_boolean() is True
    assert ctx.get("else").to_boolean() is False

    eval_(ctx, "(define then #f)")
    eval_(ctx, "(define else #f)")
    eval_(ctx, "(if #f (define then #t) (define else #t))")
    assert ctx.get("then").to_boolean() is False
    assert ctx.get("else").to_boolean() is True
Ejemplo n.º 10
0
def test_if_evaluation():
    ctx = ExecutionContext()
    eval_(ctx, "(define then #f)")
    eval_(ctx, "(define else #f)")
    eval_(ctx, "(if #t (define then #t) (define else #t))")
    assert ctx.get("then").to_boolean() is True
    assert ctx.get("else").to_boolean() is False

    eval_(ctx, "(define then #f)")
    eval_(ctx, "(define else #f)")
    eval_(ctx, "(if #f (define then #t) (define else #t))")
    assert ctx.get("then").to_boolean() is False
    assert ctx.get("else").to_boolean() is True
Ejemplo n.º 11
0
def test_lambda_call():
    ctx = ExecutionContext()

    eval_(ctx, "(define c1 'none)")
    eval_(ctx, "(define c2 'none)")
    eval_(
        ctx, """(define fun (lambda (x y z)
                                (call/cc (lambda (k)
                                           (set! c1 k)))
                                (+ x y z)))""")

    assert ctx.get("c1").to_string() == "none"
    assert ctx.get("c2").to_string() == "none"

    eval_(
        ctx, """(fun (call/cc (lambda (k)
                                  (set! c2 k)
                                  1))
                       2 3)""")

    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 6

    w_result = eval_(ctx, "(c2 0)")
    assert w_result.to_number() == 5
    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 5

    w_result = eval_(ctx, "(c2 5)")
    assert w_result.to_number() == 10
    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 10
Ejemplo n.º 12
0
def test_ctx_define():
    ctx = ExecutionContext()
    eval_(ctx, "(define v1 42)")
    assert ctx.get("v1").to_number() == 42
    w_num = eval_(ctx, "v1")
    assert w_num.to_number() == 42

    eval_(ctx, "(define v2 2.1)")
    assert ctx.get("v2").to_number() == 2.1

    w_num = eval_(ctx, "(+ 1 v1 v2)")
    assert w_num.to_number() == 45.1

    eval_(ctx, "(define v2 3.1)")
    w_num = eval_(ctx, "(+ 1 v1 v2)")
    assert w_num.to_number() == 46.1
Ejemplo n.º 13
0
def test_ctx_define():
    ctx = ExecutionContext()
    eval_(ctx, "(define v1 42)")
    assert ctx.get("v1").to_number() == 42
    w_num = eval_(ctx, "v1")
    assert w_num.to_number() == 42

    eval_(ctx, "(define v2 2.1)")
    assert ctx.get("v2").to_number() == 2.1

    w_num = eval_(ctx, "(+ 1 v1 v2)")
    assert w_num.to_number() == 45.1

    eval_(ctx, "(define v2 3.1)")
    w_num = eval_(ctx, "(+ 1 v1 v2)")
    assert w_num.to_number() == 46.1
Ejemplo n.º 14
0
def test_hefty1_computation():
    ctx = ExecutionContext()

    eval_(ctx, "(define side-effects '())")
    eval_(
        ctx, """
        (define (hefty-computation do-other-stuff)
            (letrec
              ((loop (lambda (n)
                  (set! side-effects (cons (list 'hefty-a n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-b n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-c n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (if (zero? n)
                      '()
                      (loop (- n 1))))))
               (loop 1)))""")

    eval_(
        ctx, """
        (define (superfluous-computation do-other-stuff)
            (letrec
              ((loop (lambda ()
                        (set! side-effects (cons 'break side-effects))
                        (set! do-other-stuff (call/cc do-other-stuff))
                        (loop))))
              (loop)))""")

    eval_(ctx, "(hefty-computation superfluous-computation)")

    assert ctx.get("side-effects").to_string() == \
            """(break (hefty-c 0) break (hefty-b 0) break (hefty-a 0) break (hefty-c 1) break (hefty-b 1) break (hefty-a 1))"""
Ejemplo n.º 15
0
def test_begin():
    ctx = ExecutionContext()
    w_global = W_Integer(0)
    ctx.put("var", w_global)
    w_result = eval_(ctx, "(begin (set! var 11) (+ var 33))")
    assert w_result.to_number() == 44
    assert ctx.get("var").to_number() == 11
Ejemplo n.º 16
0
def test_begin():
    ctx = ExecutionContext()
    w_global = W_Integer(0)
    ctx.put("var", w_global)
    w_result = eval_(ctx, "(begin (set! var 11) (+ var 33))")
    assert w_result.to_number() == 44
    assert ctx.get("var").to_number() == 11
Ejemplo n.º 17
0
def test_sete():
    ctx = ExecutionContext()
    eval_(ctx, "(define x 42)")
    loc1 = ctx.get_location("x")
    eval_(ctx, "(set! x 43)")
    loc2 = ctx.get_location("x")
    assert ctx.get("x").to_number() == 43
    assert loc1 is loc2
    py.test.raises(UnboundVariable, eval_, ctx, "(set! y 42)")
Ejemplo n.º 18
0
def test_sete():
    ctx = ExecutionContext()
    eval_(ctx, "(define x 42)")
    loc1 = ctx.get_location("x")
    eval_(ctx, "(set! x 43)")
    loc2 = ctx.get_location("x")
    assert ctx.get("x").to_number() == 43
    assert loc1 is loc2
    py.test.raises(UnboundVariable, eval_, ctx, "(set! y 42)")
Ejemplo n.º 19
0
def test_syntax_rules_literals():
    ctx = ExecutionContext()

    # => is literal, should be matched exactly
    # w_transformer created in ctx
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")

    w_expr = parse_("(foo 12 boo)")
    py.test.raises(MatchError, w_transformer.match, ctx, w_expr)

    w_expr = parse_("(foo bar boo)")
    py.test.raises(MatchError, w_transformer.match, ctx, w_expr)

    # exact match
    w_expr = parse_("(foo => boo)")

    # within the same context
    assert w_transformer.match(ctx, w_expr)[0].to_boolean()

    w_42 = W_Number(42)

    # different lexical scope, not the same bindings for => in ctx and closure
    closure = ctx.copy()
    closure.put("=>", w_42)
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)

    # different lexical scope, not the same bindings for => in ctx and closure
    ctx.put("=>", W_Number(12))
    assert ctx.get("=>") is not closure.get("=>")
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)

    # the same object for => in ctx and closure, but different bindings
    # <arigo> I think this should also raise MatchError.  When R5RS says
    # "same binding" it probably means bound to the same *location*, not
    # just that there is the same object in both locations
    ctx.put("=>", w_42)
    assert ctx.get("=>") is closure.get("=>")
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)
Ejemplo n.º 20
0
def test_syntax_rules_literals():
    ctx = ExecutionContext()

    # => is literal, should be matched exactly
    # w_transformer created in ctx
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")

    w_expr = parse_("(foo 12 boo)")
    py.test.raises(MatchError, w_transformer.match, ctx, w_expr)

    w_expr = parse_("(foo bar boo)")
    py.test.raises(MatchError, w_transformer.match, ctx, w_expr)

    # exact match
    w_expr = parse_("(foo => boo)")

    # within the same context
    assert w_transformer.match(ctx, w_expr)[0].to_boolean()

    w_42 = W_Number(42)

    # different lexical scope, not the same bindings for => in ctx and closure
    closure = ctx.copy()
    closure.put("=>", w_42)
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)

    # different lexical scope, not the same bindings for => in ctx and closure
    ctx.put("=>", W_Number(12))
    assert ctx.get("=>") is not closure.get("=>")
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)

    # the same object for => in ctx and closure, but different bindings
    # <arigo> I think this should also raise MatchError.  When R5RS says
    # "same binding" it probably means bound to the same *location*, not
    # just that there is the same object in both locations
    ctx.put("=>", w_42)
    assert ctx.get("=>") is closure.get("=>")
    w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
    py.test.raises(MatchError, w_transformer.match, closure, w_expr)
Ejemplo n.º 21
0
def test_deep_recursion():
    ctx = ExecutionContext()
    eval_(ctx, "(define a 0)")
    eval_(ctx, """
        (define loop (lambda (n)
                        (set! a (+ a 1))
                        (if (= n 0)
                            n
                            (loop (- n 1)))))""")

    eval_(ctx, "(loop 2000)")
    assert ctx.get("a").to_number() == 2001
Ejemplo n.º 22
0
def test_evaluator():
    ctx = ExecutionContext()
    eval_(ctx, "(define a 0)")
    w_obj = parse("(let () (set! a 42) a)")[0]
    (w_expr, new_ctx) = w_obj.eval_tr(ctx)
    assert ctx.get("a").to_number() == 42
    assert isinstance(w_expr, W_Symbol)
    assert new_ctx is not ctx
    assert isinstance(new_ctx, ExecutionContext)
    (w_obj, newer_ctx) = w_expr.eval_tr(new_ctx)
    assert isinstance(w_obj, W_Number)
    assert w_obj.to_number() == 42
    assert newer_ctx is None
Ejemplo n.º 23
0
def test_deep_recursion():
    ctx = ExecutionContext()
    eval_(ctx, "(define a 0)")
    eval_(
        ctx, """
        (define loop (lambda (n)
                        (set! a (+ a 1))
                        (if (= n 0)
                            n
                            (loop (- n 1)))))""")

    eval_(ctx, "(loop 2000)")
    assert ctx.get("a").to_number() == 2001
Ejemplo n.º 24
0
def test_evaluator():
    ctx = ExecutionContext()
    eval_(ctx, "(define a 0)")
    w_obj = parse("(let () (set! a 42) a)")[0]
    (w_expr, new_ctx) = w_obj.eval_tr(ctx)
    assert ctx.get("a").to_number() == 42
    assert isinstance(w_expr, W_Symbol)
    assert new_ctx is not ctx
    assert isinstance(new_ctx, ExecutionContext)
    (w_obj, newer_ctx) = w_expr.eval_tr(new_ctx)
    assert isinstance(w_obj, W_Number)
    assert w_obj.to_number() == 42
    assert newer_ctx is None
Ejemplo n.º 25
0
def test_lambda_fac():
    ctx = ExecutionContext()
    eval_(ctx, """
        (define fac
            (lambda (n)
                (if (= n 1)
                    n
                    (* (fac (- n 1)) n))))""")
    assert isinstance(ctx.get("fac"), W_Lambda)
    w_result = eval_(ctx, "(fac 4)")
    assert w_result.to_number() == 24

    w_result = eval_(ctx, "(fac 5)")
    assert w_result.to_number() == 120
Ejemplo n.º 26
0
def test_let():
    ctx = ExecutionContext()
    w_global = W_Integer(0)
    ctx.put("var", w_global)
    w_result = eval_(ctx, "(let ((var 42) (x (+ 2 var))) (+ var x))")
    assert w_result.to_number() == 44
    assert ctx.get("var") is w_global

    w_result = eval_(ctx, """
        (let ((x (lambda () 1)))
            (let ((y (lambda () (x)))
                  (x (lambda () 2))) (y)))""")
    assert w_result.to_number() == 1

    py.test.raises(UnboundVariable, eval_noctx, "(let ((y 0) (x y)) x)")
Ejemplo n.º 27
0
def test_callcc_callcc():
    ctx = ExecutionContext()
    w_procedure = eval_(ctx, "(call/cc call/cc)")
    assert isinstance(w_procedure, W_Procedure)
    print w_procedure

    eval_(ctx, "(define cont 'none)")
    w_result = eval_(
        ctx, """((call/cc call/cc) (lambda (k)
                                                     (set! cont k)
                                                     'done))""")
    assert w_result.to_string() == "done"
    assert isinstance(eval_(ctx, "cont"), W_Procedure)
    eval_(ctx, "(cont +)")
    assert eval_(ctx, "cont") is ctx.get("+")
Ejemplo n.º 28
0
def test_lambda_fac():
    ctx = ExecutionContext()
    eval_(
        ctx, """
        (define fac
            (lambda (n)
                (if (= n 1)
                    n
                    (* (fac (- n 1)) n))))""")
    assert isinstance(ctx.get("fac"), W_Lambda)
    w_result = eval_(ctx, "(fac 4)")
    assert w_result.to_number() == 24

    w_result = eval_(ctx, "(fac 5)")
    assert w_result.to_number() == 120
Ejemplo n.º 29
0
def test_ctx_sets():
    w_fnum = W_Integer(42)
    w_fnum2 = W_Integer(43)
    w_fnum3 = W_Integer(44)

    ctx = ExecutionContext()
    ctx.put("v1", w_fnum)

    ctx2 = ctx.copy()
    assert w_fnum is ctx2.get("v1")
    ctx.set("v1", w_fnum2)
    assert w_fnum2 is ctx2.get("v1")
    assert w_fnum2 is ctx.get("v1")

    ctx2.put("v1", w_fnum3)
    assert w_fnum3 is ctx2.get("v1")
Ejemplo n.º 30
0
def test_let():
    ctx = ExecutionContext()
    w_global = W_Integer(0)
    ctx.put("var", w_global)
    w_result = eval_(ctx, "(let ((var 42) (x (+ 2 var))) (+ var x))")
    assert w_result.to_number() == 44
    assert ctx.get("var") is w_global

    w_result = eval_(
        ctx, """
        (let ((x (lambda () 1)))
            (let ((y (lambda () (x)))
                  (x (lambda () 2))) (y)))""")
    assert w_result.to_number() == 1

    py.test.raises(UnboundVariable, eval_noctx, "(let ((y 0) (x y)) x)")
Ejemplo n.º 31
0
def test_ctx_sets():
    w_fnum = W_Integer(42)
    w_fnum2 = W_Integer(43)
    w_fnum3 = W_Integer(44)

    ctx = ExecutionContext()
    ctx.put("v1", w_fnum)

    ctx2 = ctx.copy()
    assert w_fnum is ctx2.get("v1")
    ctx.set("v1", w_fnum2)
    assert w_fnum2 is ctx2.get("v1")
    assert w_fnum2 is ctx.get("v1")

    ctx2.put("v1", w_fnum3)
    assert w_fnum3 is ctx2.get("v1")
def test_callcc_callcc():
    ctx = ExecutionContext()
    w_procedure = eval_(ctx, "(call/cc call/cc)")
    assert isinstance(w_procedure, W_Procedure)
    print w_procedure

    eval_(ctx, "(define cont 'none)")
    w_result = eval_(
        ctx,
        """((call/cc call/cc) (lambda (k)
                                                     (set! cont k)
                                                     'done))""",
    )
    assert w_result.to_string() == "done"
    assert isinstance(eval_(ctx, "cont"), W_Procedure)
    eval_(ctx, "(cont +)")
    assert eval_(ctx, "cont") is ctx.get("+")
Ejemplo n.º 33
0
def test_macro_expand():
    ctx = ExecutionContext()
    eval_(ctx, """(define-syntax foo (syntax-rules ()
                                          ((foo) #t)
                                          ((foo arg) arg)))""")
    eval_(ctx, """(define-syntax bar (syntax-rules ()
                                          ((bar) (foo))
                                          ((bar arg) (foo arg))))""")

    w_expr = parse_("(bar 42)")
    assert ctx.get("bar").expand(ctx, w_expr).to_string() == "(foo 42)"
    assert eval_(ctx, "(bar 42)").to_number() == 42

    eval_(ctx, """(define-syntax foo (syntax-rules ()
                                          ((foo) #t)))""")
    eval_(ctx, """(define-syntax bar (syntax-rules ()
                                          ((bar) (quote (foo)))))""")
    assert eval_(ctx, "(bar)").to_string() == "(foo)"
def test_hefty2_computation():
    ctx = ExecutionContext()

    eval_(ctx, "(define side-effects '())")
    eval_(
        ctx,
        """
        (define (hefty-computation do-other-stuff)
            (letrec
              ((loop (lambda (n)
                  (set! side-effects (cons (list 'hefty-a n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-b n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-c n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (if (zero? n)
                      '()
                      (loop (- n 1))))))
               (loop 1)))""",
    )

    eval_(
        ctx,
        """
        (define (superfluous-computation do-other-stuff)
            (letrec
              ((loop (lambda ()
                  (lst-loop '(straight quarter-past half quarter-til))
                  (loop)))
               (lst-loop (lambda (lst) 
                  (if (pair? lst)
                      (let ((graphic (car lst)))
                        (set! side-effects (cons graphic side-effects))
                        (set! do-other-stuff (call/cc do-other-stuff))
                        (lst-loop (cdr lst)))))))
              (loop)))""",
    )

    eval_(ctx, "(hefty-computation superfluous-computation)")
    assert (
        ctx.get("side-effects").to_string()
        == """(quarter-past (hefty-c 0) straight (hefty-b 0) quarter-til (hefty-a 0) half (hefty-c 1) quarter-past (hefty-b 1) straight (hefty-a 1))"""
    )
Ejemplo n.º 35
0
def test_syntax_rules_hygenic_expansion():
    ctx = ExecutionContext()

    w_transformer = eval_(ctx, """(syntax-rules ()
                                     ((dotimes count body)
                                      (letrec ((loop
                                       (lambda (counter)
                                         (if (= counter 0)
                                             #f
                                             (begin
                                                body
                                                (loop (- counter 1)))))))
                                        (loop count))))""")

    w_expr = parse_("(dotimes 5 (set! counter (+ counter 1)))")
    py.test.raises(UnboundVariable, w_transformer.expand_eval, ctx, w_expr)

    eval_(ctx, "(define counter 0)")
    w_expr = parse_("(dotimes 5 (set! counter (+ counter 1)))")
    w_transformer.expand_eval(ctx, w_expr)
    assert ctx.get("counter").to_number() == 5
def test_hefty1_computation():
    ctx = ExecutionContext()

    eval_(ctx, "(define side-effects '())")
    eval_(
        ctx,
        """
        (define (hefty-computation do-other-stuff)
            (letrec
              ((loop (lambda (n)
                  (set! side-effects (cons (list 'hefty-a n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-b n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-c n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (if (zero? n)
                      '()
                      (loop (- n 1))))))
               (loop 1)))""",
    )

    eval_(
        ctx,
        """
        (define (superfluous-computation do-other-stuff)
            (letrec
              ((loop (lambda ()
                        (set! side-effects (cons 'break side-effects))
                        (set! do-other-stuff (call/cc do-other-stuff))
                        (loop))))
              (loop)))""",
    )

    eval_(ctx, "(hefty-computation superfluous-computation)")

    assert (
        ctx.get("side-effects").to_string()
        == """(break (hefty-c 0) break (hefty-b 0) break (hefty-a 0) break (hefty-c 1) break (hefty-b 1) break (hefty-a 1))"""
    )
Ejemplo n.º 37
0
def test_syntax_rules_hygenic_expansion():
    ctx = ExecutionContext()

    w_transformer = eval_(
        ctx, """(syntax-rules ()
                                     ((dotimes count body)
                                      (letrec ((loop
                                       (lambda (counter)
                                         (if (= counter 0)
                                             #f
                                             (begin
                                                body
                                                (loop (- counter 1)))))))
                                        (loop count))))""")

    w_expr = parse_("(dotimes 5 (set! counter (+ counter 1)))")
    py.test.raises(UnboundVariable, w_transformer.expand_eval, ctx, w_expr)

    eval_(ctx, "(define counter 0)")
    w_expr = parse_("(dotimes 5 (set! counter (+ counter 1)))")
    w_transformer.expand_eval(ctx, w_expr)
    assert ctx.get("counter").to_number() == 5
Ejemplo n.º 38
0
def test_macro_expand():
    ctx = ExecutionContext()
    eval_(
        ctx, """(define-syntax foo (syntax-rules ()
                                          ((foo) #t)
                                          ((foo arg) arg)))""")
    eval_(
        ctx, """(define-syntax bar (syntax-rules ()
                                          ((bar) (foo))
                                          ((bar arg) (foo arg))))""")

    w_expr = parse_("(bar 42)")
    assert ctx.get("bar").expand(ctx, w_expr).to_string() == "(foo 42)"
    assert eval_(ctx, "(bar 42)").to_number() == 42

    eval_(
        ctx, """(define-syntax foo (syntax-rules ()
                                          ((foo) #t)))""")
    eval_(
        ctx, """(define-syntax bar (syntax-rules ()
                                          ((bar) (quote (foo)))))""")
    assert eval_(ctx, "(bar)").to_string() == "(foo)"
Ejemplo n.º 39
0
def test_hefty2_computation():
    ctx = ExecutionContext()

    eval_(ctx, "(define side-effects '())")
    eval_(
        ctx, """
        (define (hefty-computation do-other-stuff)
            (letrec
              ((loop (lambda (n)
                  (set! side-effects (cons (list 'hefty-a n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-b n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (set! side-effects (cons (list 'hefty-c n) side-effects))
                  (set! do-other-stuff (call/cc do-other-stuff))
                  (if (zero? n)
                      '()
                      (loop (- n 1))))))
               (loop 1)))""")

    eval_(
        ctx, """
        (define (superfluous-computation do-other-stuff)
            (letrec
              ((loop (lambda ()
                  (lst-loop '(straight quarter-past half quarter-til))
                  (loop)))
               (lst-loop (lambda (lst) 
                  (if (pair? lst)
                      (let ((graphic (car lst)))
                        (set! side-effects (cons graphic side-effects))
                        (set! do-other-stuff (call/cc do-other-stuff))
                        (lst-loop (cdr lst)))))))
              (loop)))""")

    eval_(ctx, "(hefty-computation superfluous-computation)")
    assert ctx.get("side-effects").to_string() == \
            """(quarter-past (hefty-c 0) straight (hefty-b 0) quarter-til (hefty-a 0) half (hefty-c 1) quarter-past (hefty-b 1) straight (hefty-a 1))"""
def test_lambda_call():
    ctx = ExecutionContext()

    eval_(ctx, "(define c1 'none)")
    eval_(ctx, "(define c2 'none)")
    eval_(
        ctx,
        """(define fun (lambda (x y z)
                                (call/cc (lambda (k)
                                           (set! c1 k)))
                                (+ x y z)))""",
    )

    assert ctx.get("c1").to_string() == "none"
    assert ctx.get("c2").to_string() == "none"

    eval_(
        ctx,
        """(fun (call/cc (lambda (k)
                                  (set! c2 k)
                                  1))
                       2 3)""",
    )

    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 6

    w_result = eval_(ctx, "(c2 0)")
    assert w_result.to_number() == 5
    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 5

    w_result = eval_(ctx, "(c2 5)")
    assert w_result.to_number() == 10
    w_result = eval_(ctx, "(c1)")
    assert w_result.to_number() == 10