public
Description: a Scheme written in Ruby, but implemented on the bus!
Homepage: http://bus-scheme.rubyforge.org
Clone URL: git://github.com/technomancy/bus-scheme.git
making the parser be more consistent with using lists instead of arrays
technomancy (author)
Fri May 30 17:19:57 -0700 2008
commit  aa288decc927509e7594dcdf63a5b5a07cb6c165
tree    887ed0414a5c052fa335ebfcc85d14db297e6b79
parent  e2e38bb3a579bff528af27c7b56b410e678b8ab4
...
77
78
79
 
80
81
82
...
77
78
79
80
81
82
83
0
@@ -77,6 +77,7 @@ module BusScheme
0
 
0
     # allows for (mylist 4) => (nth mylist 4)
0
     def call(nth)
0
+ nth = nth.car if nth.is_a? Cons # TODO: remove?
0
       nth == 0 ? @car : @cdr.call(nth - 1)
0
     end
0
     include Callable
...
49
50
51
52
 
53
54
55
...
49
50
51
 
52
53
54
55
0
@@ -49,7 +49,7 @@ module BusScheme
0
       @body = body
0
     end
0
 
0
- def call(*args)
0
+ def call(args)
0
       BusScheme.stack.push StackFrame.new({}, BusScheme.current_scope, @called_as)
0
       begin
0
         val = @body.call(*args)
...
21
22
23
24
25
 
 
 
26
27
28
...
21
22
23
 
 
24
25
26
27
28
29
0
@@ -21,8 +21,9 @@ module Callable
0
     self.call(*args)
0
   end
0
 
0
- def call(*args)
0
- self.[](*args)
0
+ def call(arg)
0
+ arg = arg.car if arg.respond_to? :car # TODO: remove?
0
+ self[arg]
0
   end
0
 end
0
 
...
32
33
34
35
 
 
36
37
 
38
39
40
 
 
 
 
 
 
41
42
 
43
44
45
...
47
48
49
 
 
50
51
52
...
32
33
34
 
35
36
37
 
38
39
40
 
41
42
43
44
45
46
47
 
48
49
50
51
...
53
54
55
56
57
58
59
60
0
@@ -32,14 +32,20 @@ module BusScheme
0
   end
0
   
0
   # Nest a list from a 1-dimensional list of tokens
0
- def parse_list(tokens)
0
+ def parse_list(tokens, level = 0)
0
+ # puts ' ' * level + tokens.inspect
0
     raise IncompleteError if tokens.empty?
0
- return if (element = tokens.shift) == :')'
0
+ element = tokens.shift
0
 
0
     if element == :'('
0
- cons(parse_list(tokens), parse_list(tokens))
0
+ car = parse_list(tokens, level + 2) || cons
0
+ cdr = parse_list(tokens, level + 2)
0
+
0
+ cons(car, cdr)
0
+ elsif element == :')'
0
+ return
0
     else
0
- cons(element, parse_list(tokens))
0
+ cons(element, parse_list(tokens, level + 2))
0
     end
0
   end
0
 
0
@@ -47,6 +53,8 @@ module BusScheme
0
   def parse_dots_into_cons(list)
0
     if(list && list.length > 2 && list.cdr.car == :'.')
0
       cons(:cons.sym, cons(list.car, cons(list.cdr.cdr.car)))
0
+ elsif list.car.nil?
0
+ cons(cons, list.cdr)
0
     else
0
       list
0
     end
...
2
3
4
5
 
6
7
8
9
10
11
 
12
13
14
15
16
 
17
18
...
2
3
4
 
5
6
7
8
9
10
 
11
12
13
14
15
 
16
17
18
0
@@ -2,17 +2,17 @@
0
    (send x 'is_a? (ruby type))))
0
 
0
 (define boolean? (lambda (x) (or (= x #t)
0
- (= x #f))))
0
+ (= x #f))))
0
 (define symbol? (lambda (x) (isa? x "Sym")))
0
 (define cons? (lambda (x) (isa? x "Cons")))
0
 (define pair? cons?)
0
 
0
 (define string? (lambda (x) (and (isa? x "String")
0
- (not (isa? x "Sym")))))
0
+ (not (isa? x "Sym")))))
0
 (define number? (lambda (x) (isa? x "Fixnum")))
0
 (define vector? (lambda (x) (isa? x "Array")))
0
 (define procedure? (lambda (x) (isa? x "Lambda")))
0
 (define char? (lambda (x) (and (isa? x "String")
0
- (= 1 (length x)))))
0
+ (= 1 (length x)))))
0
 
0
 ;;; TODO: port?
...
4
5
6
7
8
9
10
11
 
 
 
 
12
13
14
...
44
45
46
47
 
48
49
50
...
61
62
63
64
65
66
67
68
69
70
71
...
82
83
84
85
86
87
 
 
 
88
89
90
...
4
5
6
 
 
 
 
 
7
8
9
10
11
12
13
...
43
44
45
 
46
47
48
49
...
60
61
62
 
 
 
 
 
63
64
65
...
76
77
78
 
 
 
79
80
81
82
83
84
0
@@ -4,11 +4,10 @@ require 'timeout'
0
 
0
 class BusSchemeEvalTest < Test::Unit::TestCase
0
   def test_eval_empty_list
0
- # assert BusScheme.eval(cons)
0
-
0
- assert BusScheme.eval(cons('begin'.sym, cons))
0
- # assert BusScheme.eval_string('()'), "Empty list should be true"
0
- # assert_evals_to true, "(if () #t #f)"
0
+ assert BusScheme.eval(cons)
0
+# assert BusScheme.eval(cons('begin'.sym, cons))
0
+# assert BusScheme.eval_string('()'), "Empty list should be true"
0
+# assert_evals_to true, "(if () #t #f)"
0
   end
0
 
0
   def test_eval_number
0
@@ -44,7 +43,7 @@ class BusSchemeEvalTest < Test::Unit::TestCase
0
   def test_variable_substitution
0
     eval! "(define foo 7)"
0
     assert_evals_to 7, :foo.sym
0
- assert_evals_to 21, [:*.sym, 3, :foo.sym]
0
+ assert_evals_to 21, cons(:*.sym, cons(3, cons(:foo.sym)))
0
   end
0
 
0
   def test_single_quote
0
@@ -61,11 +60,6 @@ class BusSchemeEvalTest < Test::Unit::TestCase
0
     assert_evals_to [:+.sym, 2, 3].to_list, "'(+ 2 3)"
0
   end
0
 
0
- def test_array_of_args_or_list_of_args
0
- assert_evals_to 5, cons(:+.sym, cons(2, cons(3)))
0
- assert_evals_to 5, cons(:+.sym, cons(2, cons(3)).to_a)
0
- end
0
-
0
   def test_eval_multiple_forms
0
     assert_raises(EvalError) do
0
       eval! "(+ 2 2) (undefined-symbol)"
0
@@ -82,9 +76,9 @@ class BusSchemeEvalTest < Test::Unit::TestCase
0
     assert_evals_to 3, "((list 1 2 3) 2)"
0
   end
0
 
0
- def test_funcall_vector_means_nth
0
- assert_evals_to 3, "((vector 1 2 3) 2)"
0
- end
0
+# def test_funcall_vector_means_nth
0
+# assert_evals_to 3, "((vector 1 2 3) 2)"
0
+# end
0
 
0
   def test_funcall_hash_means_lookup
0
     assert_evals_to 3, "((hash (1 1) (2 2) (3 3)) 3)"
...
61
62
63
64
 
65
66
67
...
61
62
63
 
64
65
66
67
0
@@ -61,7 +61,7 @@ class Test::Unit::TestCase
0
   def trace
0
     BusScheme.trace = true
0
     yield
0
- rescue
0
+ ensure
0
     BusScheme.trace = false
0
   end
0
 end
...
7
8
9
10
 
11
12
13
...
7
8
9
 
10
11
12
13
0
@@ -7,7 +7,7 @@ class BusSchemeLambdaTest < Test::Unit::TestCase
0
     assert l.is_a?(Lambda)
0
     assert_equal [[:+.sym, 1, 1].to_list], l.body
0
     assert_equal 0, l.formals.length
0
-
0
+
0
     eval!("(define foo (lambda () (+ 1 1)))")
0
     assert BusScheme[:foo.sym].is_a?(Lambda)
0
     assert_evals_to 2, [:foo.sym]
...
17
18
19
20
 
21
22
23
...
207
208
209
 
 
 
 
 
 
 
 
 
 
 
 
 
210
211
212
...
17
18
19
 
20
21
22
23
...
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
0
@@ -17,7 +17,7 @@ class BusSchemeParserTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_parses_list
0
- assert_parses_to "()", Cons.new(nil, nil)
0
+ assert_parses_to "()", cons
0
     assert_parses_to "(hey)", [:hey.sym]
0
     assert_parses_to "(hey there)", [:hey.sym, :there.sym]
0
   end
0
@@ -207,6 +207,19 @@ class BusSchemeParserTest < Test::Unit::TestCase
0
     tree = BusScheme.parse("(define foo 23)")
0
     assert_equal "(eval)", tree.cdr.car.file
0
   end
0
+
0
+ def test_parses_empty_list_correctly
0
+ parse "1"
0
+ # want: cons(:lambda.sym, cons(cons, cons(1)))
0
+ tokens = [:'(', :lambda.sym, :'(', :')', 1, :')']
0
+ assert_equal tokens, tokenize("(lambda () 1)")
0
+
0
+ list = parse_tokens [:'(', :lambda.sym, :'(', :')', 1, :')']
0
+ assert_equal [:lambda.sym, [], 1].to_list(true), list
0
+
0
+# list = parse_list(tokenize("(lambda () 1)"))
0
+# assert_equal [:lambda.sym, [], 1].to_list(true), list
0
+ end
0
   
0
   private
0
 

Comments

    No one has commented yet.