bus-scheme 0.7.5 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +1 -1
- data/Manifest.txt +12 -0
- data/R5RS.diff +30 -0
- data/README.txt +91 -32
- data/Rakefile +30 -3
- data/bin/bus +1 -1
- data/examples/fib.scm +6 -0
- data/lib/array_extensions.rb +8 -5
- data/lib/bus_scheme.rb +58 -17
- data/lib/cons.rb +43 -3
- data/lib/eval.rb +53 -20
- data/lib/lambda.rb +51 -41
- data/lib/object_extensions.rb +58 -1
- data/lib/parser.rb +93 -64
- data/lib/primitives.rb +63 -43
- data/lib/scheme/core.scm +18 -15
- data/lib/scheme/list.scm +12 -0
- data/lib/scheme/predicates.scm +19 -0
- data/lib/scheme/test.scm +12 -0
- data/lib/stack_frame.rb +57 -0
- data/test/test_core.rb +9 -21
- data/test/test_eval.rb +56 -11
- data/test/test_helper.rb +26 -5
- data/test/test_lambda.rb +83 -21
- data/test/test_list_functions.scm +11 -0
- data/test/test_parser.rb +66 -31
- data/test/test_predicates.scm +24 -0
- data/test/test_primitives.rb +34 -88
- data/test/test_primitives.scm +55 -0
- data/test/test_stack_frame.rb +30 -0
- data/test/test_web.rb +116 -0
- data/test/test_xml.rb +69 -0
- data/test/tracer.scm +4 -0
- data/tutorials/getting_started.html +204 -0
- metadata +21 -6
data/lib/scheme/core.scm
CHANGED
@@ -1,35 +1,38 @@
|
|
1
|
-
(define
|
2
|
-
(lambda (sym) (send sym
|
1
|
+
(define string->symbol
|
2
|
+
(lambda (sym) (send sym 'sym)))
|
3
|
+
|
4
|
+
(define number->string
|
5
|
+
(lambda (number) (send number 'to_s)))
|
3
6
|
|
4
7
|
(define substring
|
5
8
|
(lambda (string to from) (send string (quote []) to from)))
|
6
9
|
|
7
10
|
(define null?
|
8
|
-
(lambda (expr) (
|
11
|
+
(lambda (expr) (or
|
12
|
+
(= expr ()) ;; hacky?
|
13
|
+
(= expr (ruby "nil")))))
|
9
14
|
|
10
15
|
(define >
|
11
|
-
(lambda (x y) (send x
|
16
|
+
(lambda (x y) (send x '> y)))
|
12
17
|
|
13
18
|
(define <
|
14
|
-
(lambda (x y) (send x
|
19
|
+
(lambda (x y) (send x '< y)))
|
15
20
|
|
16
21
|
(define =
|
17
|
-
(lambda (x y) (send x
|
18
|
-
|
19
|
-
(define and
|
20
|
-
(lambda (x y) (if x (if y y #f) #f)))
|
21
|
-
|
22
|
-
(define or
|
23
|
-
(lambda (x y) (if x x (if y y #f))))
|
22
|
+
(lambda (x y) (send x '== y)))
|
24
23
|
|
25
24
|
(define not
|
26
25
|
(lambda (expr) (if expr #f #t)))
|
27
26
|
|
28
27
|
(define car
|
29
|
-
(lambda (lst) (send lst
|
28
|
+
(lambda (lst) (send lst 'first)))
|
30
29
|
|
31
30
|
(define cdr
|
32
|
-
(lambda (lst) (send lst
|
31
|
+
(lambda (lst) (send lst 'rest)))
|
33
32
|
|
33
|
+
;; and friends
|
34
34
|
(define cadr
|
35
|
-
(lambda (lst) (car (cdr lst))))
|
35
|
+
(lambda (lst) (car (cdr lst))))
|
36
|
+
|
37
|
+
;; cond
|
38
|
+
(define else #t)
|
data/lib/scheme/list.scm
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
(define length (lambda (l)
|
2
|
+
(if (null? l) 0 (+ 1 (length (cdr l))))))
|
3
|
+
|
4
|
+
(define append
|
5
|
+
(lambda (l1 l2)
|
6
|
+
(if (null? l1)
|
7
|
+
l2
|
8
|
+
(cons (car l1) (append (cdr l1) l2)))))
|
9
|
+
|
10
|
+
(define reverse
|
11
|
+
(lambda (l)
|
12
|
+
(if (null? l) '() (append (reverse (cdr l)) (list (car l))))))
|
@@ -0,0 +1,19 @@
|
|
1
|
+
(define isa? (lambda (x type)
|
2
|
+
(send x 'is_a? (ruby type))))
|
3
|
+
|
4
|
+
(define boolean? (lambda (x) (or (= x #t)
|
5
|
+
(= x #f))))
|
6
|
+
(define symbol? (lambda (x) (isa? x "Sym")))
|
7
|
+
(define cons? (lambda (x) (isa? x "Cons")))
|
8
|
+
(define pair? cons?)
|
9
|
+
|
10
|
+
(define string? (lambda (x) (and (isa? x "String")
|
11
|
+
(not (isa? x "Sym")))))
|
12
|
+
(define number? (lambda (x) (isa? x "Fixnum")))
|
13
|
+
(define vector? (lambda (x) (isa? x "Array")))
|
14
|
+
(define procedure? (lambda (x) (isa? x "Lambda")))
|
15
|
+
(define char? (lambda (x) (and (isa? x "String")
|
16
|
+
(= 1 (length x)))))
|
17
|
+
|
18
|
+
;;; TODO:
|
19
|
+
;;; port?
|
data/lib/scheme/test.scm
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
(define assert
|
2
|
+
(lambda (bool)
|
3
|
+
(if bool
|
4
|
+
#t
|
5
|
+
(fail "Assertion failed."))))
|
6
|
+
|
7
|
+
(define assert-equal
|
8
|
+
(lambda (expected actual)
|
9
|
+
(if (= expected actual)
|
10
|
+
#t
|
11
|
+
(fail (concat "Expected " (send expected 'inspect) ", got "
|
12
|
+
(send actual 'inspect))))))
|
data/lib/stack_frame.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module BusScheme
|
2
|
+
class StackFrame < Hash
|
3
|
+
attr_reader :called_as, :file, :line, :called_from
|
4
|
+
|
5
|
+
# takes a hash and a parent
|
6
|
+
def initialize(locals, parent, called_as)
|
7
|
+
@parent, @called_as = [parent, called_as]
|
8
|
+
@file = @called_as.respond_to?(:file) ? @called_as.file : '(eval)'
|
9
|
+
@line = @called_as.respond_to?(:line) ? @called_as.line : 0
|
10
|
+
@called_as = '(anonymous)' if called_as.is_a?(Cons) or called_as.is_a?(Array)
|
11
|
+
|
12
|
+
@called_from = if BusScheme.stack.empty? or !BusScheme.stack.last.respond_to? :called_as
|
13
|
+
'(top-level)'
|
14
|
+
else
|
15
|
+
BusScheme.stack.last.called_as
|
16
|
+
end
|
17
|
+
|
18
|
+
locals.each { |k, v| immediate_set k, v }
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :immediate_has_key?, :has_key?
|
22
|
+
alias_method :immediate_set, :[]=
|
23
|
+
alias_method :immediate_lookup, :[]
|
24
|
+
|
25
|
+
# Just your regular hash stuff, only it takes the parent into account
|
26
|
+
def has_key?(symbol)
|
27
|
+
immediate_has_key?(symbol) or @parent && @parent.has_key?(symbol)
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](symbol)
|
31
|
+
if immediate_has_key?(symbol)
|
32
|
+
immediate_lookup(symbol)
|
33
|
+
else
|
34
|
+
@parent && @parent[symbol]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def []=(symbol, value)
|
39
|
+
if !immediate_has_key?(symbol) and @parent && @parent.has_key?(symbol)
|
40
|
+
@parent[symbol] = value
|
41
|
+
else
|
42
|
+
immediate_set symbol, value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def trace
|
47
|
+
"#{@file}:#{@line} in #{@called_from}" unless filtered?
|
48
|
+
end
|
49
|
+
|
50
|
+
# special forms should not be shown in stack traces
|
51
|
+
# neither should 'begin'
|
52
|
+
def filtered?
|
53
|
+
return false unless @called_as
|
54
|
+
@called_as.special_form or @called_as == :begin.sym
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/test/test_core.rb
CHANGED
@@ -14,30 +14,18 @@ class CoreTest < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_string_functions
|
17
|
-
assert_evals_to :hi, [
|
18
|
-
assert_evals_to 'lo', [:substring, 'hello', 3, 5]
|
17
|
+
assert_evals_to :hi.sym, ['string->symbol'.sym, 'hi']
|
18
|
+
assert_evals_to 'lo', [:substring.sym, 'hello', 3, 5]
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_list_functions
|
22
|
-
assert_evals_to :foo, "(car (cons (quote foo) (quote bar)))"
|
23
|
-
assert_evals_to :bar, "(cdr (cons (quote foo) (quote bar)))"
|
24
|
-
assert_equal(
|
25
|
-
[:foo, :bar].to_list)
|
26
|
-
assert_evals_to(
|
22
|
+
assert_evals_to :foo.sym, "(car (cons (quote foo) (quote bar)))"
|
23
|
+
assert_evals_to :bar.sym, "(cdr (cons (quote foo) (quote bar)))"
|
24
|
+
assert_equal(Cons.new(:foo.sym, Cons.new(:bar.sym, nil)),
|
25
|
+
[:foo.sym, :bar.sym].to_list)
|
26
|
+
assert_evals_to(Cons.new(2, Cons.new(3, nil)),
|
27
27
|
"(list 2 3)")
|
28
|
-
assert_evals_to "bar", "(cadr (list \"foo\" \"bar\")"
|
29
|
-
assert_evals_to [1, :foo].to_list, "(list 1 'foo)"
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_boolean_logic
|
33
|
-
assert_evals_to true, "(and #t #t)"
|
34
|
-
assert_evals_to false, "(and #t #f)"
|
35
|
-
assert_evals_to false, "(and #f #t)"
|
36
|
-
assert_evals_to false, "(and #f #f)"
|
37
|
-
|
38
|
-
assert_evals_to true, "(or #t #t)"
|
39
|
-
assert_evals_to true, "(or #t #f)"
|
40
|
-
assert_evals_to true, "(or #f #t)"
|
41
|
-
assert_evals_to false, "(or #f #f)"
|
28
|
+
assert_evals_to "bar", "(cadr (list \"foo\" \"bar\"))"
|
29
|
+
assert_evals_to [1, :foo.sym].to_list, "(list 1 'foo)"
|
42
30
|
end
|
43
31
|
end
|
data/test/test_eval.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__)
|
2
2
|
require 'test_helper'
|
3
|
+
require 'timeout'
|
3
4
|
|
4
5
|
class BusSchemeEvalTest < Test::Unit::TestCase
|
5
6
|
def test_eval_empty_list
|
@@ -12,13 +13,13 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def test_set_symbol
|
15
|
-
BusScheme
|
16
|
-
assert BusScheme
|
16
|
+
BusScheme.current_scope[:hi] = 'hi'
|
17
|
+
assert BusScheme.current_scope[:hi]
|
17
18
|
end
|
18
19
|
|
19
20
|
def test_eval_symbol
|
20
|
-
BusScheme
|
21
|
-
assert_evals_to 13, :hi
|
21
|
+
BusScheme.current_scope[:hi.sym] = 13
|
22
|
+
assert_evals_to 13, :hi.sym
|
22
23
|
end
|
23
24
|
|
24
25
|
def test_eval_string
|
@@ -26,25 +27,69 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def test_eval_function_call
|
29
|
-
assert_evals_to 2,
|
30
|
+
assert_evals_to 2, "(+ 1 1)"
|
30
31
|
end
|
31
32
|
|
32
33
|
def test_nested_arithmetic
|
33
|
-
assert_evals_to 6,
|
34
|
+
assert_evals_to 6, "(+ 1 (+ 1 (* 2 2)))"
|
34
35
|
end
|
35
36
|
|
36
37
|
def test_blows_up_with_undefined_symbol
|
37
|
-
assert_raises(
|
38
|
+
assert_raises(EvalError) { eval("undefined-symbol") }
|
38
39
|
end
|
39
40
|
|
40
41
|
def test_variable_substitution
|
41
42
|
eval "(define foo 7)"
|
42
|
-
assert_evals_to 7, :foo
|
43
|
-
assert_evals_to 21, [
|
43
|
+
assert_evals_to 7, :foo.sym
|
44
|
+
assert_evals_to 21, [:*.sym, 3, :foo.sym]
|
44
45
|
end
|
45
46
|
|
46
47
|
def test_single_quote
|
47
|
-
assert_evals_to :foo, "'foo"
|
48
|
-
assert_evals_to [:foo, :biz, :bbb].to_list, "'(foo biz bbb)"
|
48
|
+
assert_evals_to :foo.sym, "'foo"
|
49
|
+
assert_evals_to [:foo.sym, :biz.sym, :bbb.sym].to_list, "'(foo biz bbb)"
|
49
50
|
end
|
51
|
+
|
52
|
+
def test_quote
|
53
|
+
assert_evals_to :hi.sym, "(quote hi)"
|
54
|
+
assert_evals_to [:a.sym, :b.sym, :c.sym].to_list, "'(a b c)"
|
55
|
+
assert_evals_to [:a.sym].to_list, "(list 'a)"
|
56
|
+
assert_evals_to [:a.sym, :b.sym].to_list, "(list 'a 'b)"
|
57
|
+
assert_evals_to [:a.sym, :b.sym, :c.sym].to_list, "(list 'a 'b 'c)"
|
58
|
+
assert_evals_to [:+.sym, 2, 3].to_list, "'(+ 2 3)"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_array_of_args_or_list_of_args
|
62
|
+
assert_evals_to 5, cons(:+.sym, cons(2, cons(3)))
|
63
|
+
assert_evals_to 5, cons(:+.sym, cons(2, cons(3)).to_a)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_eval_multiple_forms
|
67
|
+
assert_raises(EvalError) do
|
68
|
+
BusScheme.eval_string "(+ 2 2) (undefined-symbol)"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_define_after_load
|
73
|
+
BusScheme.eval_string "(load \"#{File.dirname(__FILE__)}/../examples/fib.scm\")
|
74
|
+
(define greeting \"hi\")"
|
75
|
+
assert BusScheme.in_scope?(:greeting.sym)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_funcall_list_means_nth
|
79
|
+
assert_evals_to 3, "((list 1 2 3) 2)"
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_funcall_vector_means_nth
|
83
|
+
assert_evals_to 3, "((vector 1 2 3) 2)"
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_funcall_hash_means_lookup
|
87
|
+
assert_evals_to 3, "((hash (1 1) (2 2) (3 3)) 3)"
|
88
|
+
end
|
89
|
+
|
90
|
+
# def test_tail_call_optimization
|
91
|
+
# Timeout.timeout(1) do
|
92
|
+
# assert_nothing_raised { eval "((lambda (x) (x x)) (lambda (x) (x x)))" }
|
93
|
+
# end
|
94
|
+
# end
|
50
95
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,13 +2,34 @@ $LOAD_PATH << File.dirname(__FILE__) + '/../lib/'
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'bus_scheme'
|
4
4
|
|
5
|
+
module BusScheme
|
6
|
+
def self.reset_stack
|
7
|
+
@@stack = []
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class BusScheme::Lambda
|
12
|
+
attr_accessor :body, :formals, :enclosing_scope
|
13
|
+
end
|
14
|
+
|
15
|
+
class RecursiveHash
|
16
|
+
attr_reader :parent
|
17
|
+
end
|
18
|
+
|
5
19
|
class Test::Unit::TestCase
|
20
|
+
include BusScheme
|
21
|
+
|
6
22
|
# convenience method that accepts string or form
|
7
23
|
def eval(form)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
24
|
+
begin
|
25
|
+
if form.is_a?(String)
|
26
|
+
BusScheme.eval_string(form)
|
27
|
+
else
|
28
|
+
BusScheme.eval(form)
|
29
|
+
end
|
30
|
+
rescue => e
|
31
|
+
BusScheme.reset_stack
|
32
|
+
raise e
|
12
33
|
end
|
13
34
|
end
|
14
35
|
|
@@ -18,6 +39,6 @@ class Test::Unit::TestCase
|
|
18
39
|
|
19
40
|
# remove symbols from all scopes
|
20
41
|
def clear_symbols(*symbols)
|
21
|
-
[BusScheme
|
42
|
+
[BusScheme.current_scope, BusScheme::SYMBOL_TABLE].compact.map{ |scope| symbols.map{ |sym| scope.delete sym } }
|
22
43
|
end
|
23
44
|
end
|
data/test/test_lambda.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__)
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
|
-
class BusScheme::Lambda
|
5
|
-
attr_accessor :body, :arg_names, :environment
|
6
|
-
end
|
7
|
-
|
8
4
|
class BusSchemeLambdaTest < Test::Unit::TestCase
|
9
5
|
def test_simple_lambda
|
10
6
|
l = eval("(lambda () (+ 1 1))")
|
11
|
-
assert l.is_a?(
|
12
|
-
assert_equal [[
|
13
|
-
assert_equal
|
7
|
+
assert l.is_a?(Lambda)
|
8
|
+
assert_equal [[:+.sym, 1, 1].to_list], l.body
|
9
|
+
assert_equal 0, l.formals.length
|
14
10
|
|
15
11
|
eval("(define foo (lambda () (+ 1 1)))")
|
16
|
-
assert BusScheme
|
17
|
-
assert_evals_to 2, [:foo]
|
12
|
+
assert BusScheme[:foo.sym].is_a?(Lambda)
|
13
|
+
assert_evals_to 2, [:foo.sym]
|
18
14
|
end
|
19
15
|
|
20
16
|
def test_lambda_with_arg
|
21
17
|
eval("(define foo (lambda (x) (+ x 1)))")
|
22
|
-
assert_evals_to 2,
|
18
|
+
assert_evals_to 2, "(foo 1)"
|
23
19
|
end
|
24
20
|
|
25
21
|
def test_eval_literal_lambda
|
@@ -28,35 +24,101 @@ class BusSchemeLambdaTest < Test::Unit::TestCase
|
|
28
24
|
|
29
25
|
def test_lambda_with_incorrect_arity
|
30
26
|
eval("(define foo (lambda (x) (+ x 1)))")
|
31
|
-
assert_raises(
|
27
|
+
assert_raises(ArgumentError) { assert_evals_to 2, "(foo 1 3)" }
|
32
28
|
end
|
33
29
|
|
34
30
|
def test_lambda_args_dont_stay_in_scope
|
35
31
|
clear_symbols(:x, :foo)
|
36
32
|
eval("(define foo (lambda (x) (+ x 1)))")
|
37
|
-
|
38
|
-
assert_evals_to 2,
|
39
|
-
|
33
|
+
assert ! BusScheme.in_scope?(:x)
|
34
|
+
assert_evals_to 2, "(foo 1)"
|
35
|
+
assert ! BusScheme.in_scope?(:x)
|
40
36
|
end
|
41
37
|
|
42
38
|
def test_lambda_calls_lambda
|
43
39
|
eval "(define f (lambda (x) (+ 3 x)))"
|
44
40
|
eval "(define g (lambda (y) (* 3 y)))"
|
45
41
|
assert_evals_to 12, "(f (g 3))"
|
42
|
+
assert_evals_to 1, "((lambda () ((lambda () 1))))"
|
46
43
|
end
|
47
44
|
|
45
|
+
def test_enforces_arg_count
|
46
|
+
assert_equal 3, eval("(lambda (x y z) z)").formals.size
|
47
|
+
assert_raises(ArgumentError) do
|
48
|
+
eval "((lambda (x) x))"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
48
52
|
def test_lambda_closures
|
49
|
-
|
50
|
-
|
53
|
+
assert_evals_to 3, "((lambda (x) ((lambda (y) 3) 1)) 1)"
|
54
|
+
eval "(define foo (lambda (xx) ((lambda (y) (+ xx y)) (* xx 2))))"
|
55
|
+
assert foo = BusScheme[:foo.sym]
|
56
|
+
|
57
|
+
assert_evals_to 3, foo.call(1)
|
51
58
|
eval "(define holder ((lambda (x) (lambda () x)) 2))"
|
52
59
|
assert_evals_to 2, "(holder)"
|
53
60
|
end
|
54
61
|
|
55
|
-
def
|
56
|
-
|
62
|
+
def test_changes_to_enclosed_variables_alter_original_bindings
|
63
|
+
BusScheme.reset_stack # TODO: shouldn't reqire this
|
64
|
+
assert_evals_to 2, "((lambda (x) ((lambda () (set! x 2))) x) 1)"
|
65
|
+
assert BusScheme.stack.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_implicit_begin
|
69
|
+
assert_evals_to 3, "((lambda () (string->symbol \"hi\") (+ 2 2) (* 1 3)))"
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_let
|
73
|
+
assert_evals_to 2, "(let ((n 2)) n)"
|
74
|
+
assert_evals_to 5, "(let ((n 2) (m 3)) (+ n m))"
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_shadowed_vars_dont_stay_in_scope
|
78
|
+
assert_evals_to Cons.new(:a.sym, :b.sym), "(let ((f (let ((x (quote a)))
|
79
|
+
(lambda (y) (cons x y)))))
|
80
|
+
(let ((x (quote not-a)))
|
81
|
+
(f (quote b))))"
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_nested_function_calls_dont_affect_caller
|
85
|
+
eval "(define fib (lambda (x)
|
86
|
+
(if (< x 3)
|
87
|
+
1
|
88
|
+
(+ (fib (- x 1)) (fib (- x 2))))))"
|
89
|
+
|
90
|
+
assert BusScheme.in_scope?(:fib.sym)
|
91
|
+
assert_evals_to 5, "(fib 5)"
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_lambda_rest_args
|
95
|
+
eval "(define rest (lambda args args))"
|
96
|
+
assert_evals_to [:a.sym, :b.sym, :c.sym].to_list, "(rest 'a 'b 'c)"
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_stacktrace
|
100
|
+
eval '(load "test/tracer.scm")'
|
101
|
+
assert_equal ["(eval):1 in top-level"], eval("(stacktrace)")
|
102
|
+
|
103
|
+
assert_equal(["test/tracer.scm:1 in f",
|
104
|
+
"test/tracer.scm:4 in g",
|
105
|
+
"(eval):1 in (anonymous)",
|
106
|
+
"(eval):0 in top-level"
|
107
|
+
],
|
108
|
+
eval("((lambda () (g)))"))
|
57
109
|
end
|
58
110
|
|
59
|
-
|
60
|
-
|
61
|
-
|
111
|
+
# TODO: check the stack traces that the scheme tests give
|
112
|
+
|
113
|
+
def test_stack_grows
|
114
|
+
eval "(define stack-growth
|
115
|
+
(lambda () (ruby \"raise 'wtf' if BusScheme.stack.size < 1\")))"
|
116
|
+
eval "(stack-growth)"
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_primitives_live_on_stack
|
120
|
+
BusScheme.define 'stack-growth', lambda { assert BusScheme.stack.size > 1 }
|
121
|
+
assert SYMBOL_TABLE.has_key?('stack-growth'.sym)
|
122
|
+
eval "(stack-growth)"
|
123
|
+
end
|
62
124
|
end
|