bus-scheme 0.6 → 0.7
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/Manifest.txt +2 -0
- data/README.txt +6 -7
- data/bin/bus +2 -2
- data/lib/array_extensions.rb +6 -10
- data/lib/bus_scheme.rb +18 -46
- data/lib/definitions.rb +38 -0
- data/lib/eval.rb +2 -26
- data/lib/lambda.rb +32 -0
- data/test/test_eval.rb +11 -61
- data/test/test_helper.rb +17 -0
- data/test/test_lambda.rb +60 -0
- metadata +9 -6
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -37,17 +37,16 @@ $ bus foo.scm # load a file -- todo
|
|
37
37
|
|
38
38
|
== Todo
|
39
39
|
|
40
|
-
Bus Scheme is currently missing
|
40
|
+
Bus Scheme is currently missing pieces of functionality:
|
41
41
|
|
42
|
-
*
|
43
|
-
*
|
44
|
-
*
|
45
|
-
* eval input from command line, stdin
|
42
|
+
* changes to closure variables don't affect original scope
|
43
|
+
* optimize tail call recursion
|
44
|
+
* continuations (?!?)
|
46
45
|
* parse cons cells
|
47
46
|
* parse character literals
|
48
|
-
*
|
47
|
+
* parse quote, unquote
|
49
48
|
|
50
|
-
Failing tests for
|
49
|
+
Failing tests for some of these are already included (commented out,
|
51
50
|
mostly) in the relevant test files.
|
52
51
|
|
53
52
|
== Requirements
|
data/bin/bus
CHANGED
@@ -7,8 +7,8 @@ if ARGV.empty?
|
|
7
7
|
BusScheme.repl
|
8
8
|
elsif ARGV.first == '-e' and ARGV.length == 2
|
9
9
|
puts BusScheme.eval_string(ARGV[1])
|
10
|
-
elsif ARGV.length == 1 and File.exist?(ARGV.first)
|
11
|
-
puts BusScheme.load
|
10
|
+
elsif ARGV.length == 1 and File.exist?(ARGV.first)
|
11
|
+
puts BusScheme.eval_form([:load, ARGV.first])
|
12
12
|
else
|
13
13
|
puts "Bus Scheme: a scheme interpreter written on the bus.
|
14
14
|
Usage: bus [file | -e \"form\"]
|
data/lib/array_extensions.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
class Array
|
2
|
+
def to_hash
|
3
|
+
{}.affect do |hash|
|
4
|
+
self.each { |pair| hash[pair.first] = pair.last }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
2
8
|
# Lisp-style list access
|
3
9
|
def rest
|
4
10
|
self[1 .. -1]
|
@@ -6,14 +12,4 @@ class Array
|
|
6
12
|
|
7
13
|
alias_method :car, :first
|
8
14
|
alias_method :cdr, :rest
|
9
|
-
|
10
|
-
# Treat the array as a lambda and call it with given args
|
11
|
-
def call(*args)
|
12
|
-
BusScheme::eval_lambda(self, args)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Simple predicate for convenience
|
16
|
-
def lambda?
|
17
|
-
first == :lambda
|
18
|
-
end
|
19
15
|
end
|
data/lib/bus_scheme.rb
CHANGED
@@ -11,71 +11,38 @@ require 'object_extensions'
|
|
11
11
|
require 'array_extensions'
|
12
12
|
require 'parser'
|
13
13
|
require 'eval'
|
14
|
+
require 'definitions'
|
15
|
+
require 'lambda'
|
14
16
|
|
15
17
|
module BusScheme
|
16
|
-
|
17
|
-
class EvalError < StandardError; end
|
18
|
-
class ArgumentError < StandardError; end
|
19
|
-
|
20
|
-
VERSION = "0.6"
|
21
|
-
|
22
|
-
PRIMITIVES = {
|
23
|
-
'#t'.intern => true, # :'#t' screws up emacs' ruby parser
|
24
|
-
'#f'.intern => false,
|
25
|
-
|
26
|
-
:+ => lambda { |*args| args.inject(0) { |sum, i| sum + i } },
|
27
|
-
:- => lambda { |x, y| x - y },
|
28
|
-
'/'.intern => lambda { |x, y| x / y },
|
29
|
-
:* => lambda { |*args| args.inject(1) { |product, i| product * i } },
|
30
|
-
|
31
|
-
:> => lambda { |x, y| x > y },
|
32
|
-
:< => lambda { |x, y| x < y },
|
33
|
-
|
34
|
-
:intern => lambda { |x| x.intern },
|
35
|
-
:concat => lambda { |x, y| x + y },
|
36
|
-
:substring => lambda { |x, from, to| x[from .. to] },
|
37
|
-
|
38
|
-
:exit => lambda { exit }, :quit => lambda { exit },
|
39
|
-
}
|
40
|
-
|
41
|
-
SPECIAL_FORMS = {
|
42
|
-
:quote => lambda { |arg| arg },
|
43
|
-
:if => lambda { |condition, yes, *no| eval_form(condition) ? eval_form(yes) : eval_form([:begin] + no) },
|
44
|
-
:begin => lambda { |*args| args.map{ |arg| eval_form(arg) }.last },
|
45
|
-
:set! => lambda { },
|
46
|
-
:lambda => lambda { |args, *form| [:lambda, args] + form },
|
47
|
-
:define => lambda { |sym, definition| BusScheme[sym] = eval_form(definition); sym },
|
48
|
-
}
|
18
|
+
VERSION = "0.7"
|
49
19
|
|
50
20
|
SYMBOL_TABLE = {}.merge(PRIMITIVES).merge(SPECIAL_FORMS)
|
51
|
-
|
21
|
+
LOCAL_SCOPES = []
|
52
22
|
PROMPT = '> '
|
53
23
|
|
54
|
-
#
|
55
|
-
def self.
|
56
|
-
|
24
|
+
# what scope is appropraite for this symbol
|
25
|
+
def self.scope_of(symbol)
|
26
|
+
([LOCAL_SCOPES.last] + Lambda.environment + [SYMBOL_TABLE]).compact.detect { |scope| scope.has_key?(symbol) }
|
57
27
|
end
|
58
|
-
|
28
|
+
|
59
29
|
# symbol lookup
|
60
30
|
def self.[](symbol)
|
61
|
-
|
31
|
+
scope = scope_of(symbol)
|
32
|
+
raise EvalError.new("Undefined symbol: #{symbol}") if scope.nil?
|
33
|
+
scope[symbol]
|
62
34
|
end
|
63
35
|
|
64
36
|
# symbol assignment to value
|
65
37
|
def self.[]=(symbol, value)
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
# remove symbols from all scopes
|
70
|
-
def self.clear_symbols(*symbols)
|
71
|
-
SCOPES.map{ |scope| symbols.map{ |sym| scope.delete sym } }
|
38
|
+
(scope_of(symbol) || SYMBOL_TABLE)[symbol] = value
|
72
39
|
end
|
73
40
|
|
74
41
|
# symbol special form predicate
|
75
42
|
def self.special_form?(symbol)
|
76
43
|
SPECIAL_FORMS.has_key?(symbol)
|
77
44
|
end
|
78
|
-
|
45
|
+
|
79
46
|
# Read-Eval-Print-Loop
|
80
47
|
def self.repl
|
81
48
|
loop do
|
@@ -83,6 +50,11 @@ module BusScheme
|
|
83
50
|
puts BusScheme.eval_string(Readline.readline(PROMPT))
|
84
51
|
rescue Interrupt
|
85
52
|
puts 'Type "(quit)" to leave Bus Scheme.'
|
53
|
+
rescue BusSchemeError => e
|
54
|
+
puts "Error: #{e}"
|
55
|
+
rescue StandardError => e
|
56
|
+
puts "You found a bug in Bus Scheme!"
|
57
|
+
puts "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
86
58
|
end
|
87
59
|
end
|
88
60
|
end
|
data/lib/definitions.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module BusScheme
|
2
|
+
class BusSchemeError < StandardError; end
|
3
|
+
class ParseError < BusSchemeError; end
|
4
|
+
class EvalError < BusSchemeError; end
|
5
|
+
class ArgumentError < BusSchemeError; end
|
6
|
+
|
7
|
+
PRIMITIVES = {
|
8
|
+
'#t'.intern => true, # :'#t' screws up emacs' ruby parser
|
9
|
+
'#f'.intern => false,
|
10
|
+
|
11
|
+
:+ => lambda { |*args| args.inject(0) { |sum, i| sum + i } },
|
12
|
+
:- => lambda { |x, y| x - y },
|
13
|
+
:* => lambda { |*args| args.inject(1) { |product, i| product * i } },
|
14
|
+
'/'.intern => lambda { |x, y| x / y },
|
15
|
+
|
16
|
+
:> => lambda { |x, y| x > y },
|
17
|
+
:< => lambda { |x, y| x < y },
|
18
|
+
|
19
|
+
:intern => lambda { |x| x.intern },
|
20
|
+
:concat => lambda { |x, y| x + y },
|
21
|
+
:substring => lambda { |x, from, to| x[from .. to] },
|
22
|
+
|
23
|
+
:load => lambda { |filename| eval_string(File.read(filename)) },
|
24
|
+
:exit => lambda { exit }, :quit => lambda { exit },
|
25
|
+
}
|
26
|
+
|
27
|
+
# if we add in macros, can some of these be defined in scheme?
|
28
|
+
SPECIAL_FORMS = {
|
29
|
+
:quote => lambda { |arg| arg },
|
30
|
+
# TODO: check that nil, () and #f all behave according to spec
|
31
|
+
:if => lambda { |q, yes, *no| eval_form(q) ? eval_form(yes) : eval_form([:begin] + no) },
|
32
|
+
:begin => lambda { |*args| args.map{ |arg| eval_form(arg) }.last },
|
33
|
+
:set! => lambda { |sym, value| BusScheme[sym] and
|
34
|
+
BusScheme[sym] = eval_form(value); sym },
|
35
|
+
:lambda => lambda { |args, *form| Lambda.new(args, form) },
|
36
|
+
:define => lambda { |sym, definition| BusScheme[sym] = eval_form(definition); sym },
|
37
|
+
}
|
38
|
+
end
|
data/lib/eval.rb
CHANGED
@@ -12,9 +12,8 @@ module BusScheme
|
|
12
12
|
elsif form.is_a? Array
|
13
13
|
apply(form.first, *form.rest)
|
14
14
|
elsif form.is_a? Symbol
|
15
|
-
raise "Undefined symbol: #{form}" unless in_scope?(form)
|
16
15
|
BusScheme[form]
|
17
|
-
else
|
16
|
+
else # well it must be a literal then
|
18
17
|
form
|
19
18
|
end
|
20
19
|
end
|
@@ -22,30 +21,7 @@ module BusScheme
|
|
22
21
|
# Call a function with given args
|
23
22
|
def apply(function, *args)
|
24
23
|
args.map!{ |arg| eval_form(arg) } unless special_form?(function)
|
25
|
-
|
26
|
-
# refactor me
|
27
|
-
if function.is_a?(Array) and function.lambda?
|
28
|
-
function.call(*args)
|
29
|
-
else
|
30
|
-
raise "Undefined symbol: #{function}" unless in_scope?(function)
|
31
|
-
BusScheme[function].call(*args)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# All the super lambda magic happens (or fails to happen) here
|
36
|
-
def eval_lambda(lambda, args)
|
37
|
-
raise BusScheme::EvalError unless lambda.shift == :lambda
|
38
|
-
|
39
|
-
arg_list = lambda.shift
|
40
|
-
raise BusScheme::ArgumentError if !arg_list.is_a?(Array) or arg_list.length != args.length
|
41
|
-
|
42
|
-
SCOPES << {} # new scope
|
43
|
-
until arg_list.empty?
|
44
|
-
BusScheme[arg_list.shift] = args.shift
|
45
|
-
end
|
46
|
-
|
47
|
-
# using affect as a non-return-value-affecting callback
|
48
|
-
BusScheme[:begin].call(*lambda).affect { SCOPES.pop }
|
24
|
+
eval_form(function).call(*args)
|
49
25
|
end
|
50
26
|
end
|
51
27
|
end
|
data/lib/lambda.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module BusScheme
|
2
|
+
class Lambda
|
3
|
+
@@current = nil
|
4
|
+
|
5
|
+
# create new lambda object
|
6
|
+
def initialize(arg_names, body)
|
7
|
+
@arg_names, @body, @environment = [arg_names, body, LOCAL_SCOPES]
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :environment
|
11
|
+
|
12
|
+
# execute lambda with given arg_values
|
13
|
+
def call(*arg_values)
|
14
|
+
raise BusScheme::ArgumentError if @arg_names.length != arg_values.length
|
15
|
+
with_local_scope(@arg_names.zip(arg_values).to_hash) { BusScheme[:begin].call(*@body) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.environment
|
19
|
+
@@current ? @@current.environment : []
|
20
|
+
end
|
21
|
+
|
22
|
+
# execute a block with a given local scope
|
23
|
+
def with_local_scope(scope, &block)
|
24
|
+
BusScheme::LOCAL_SCOPES << scope
|
25
|
+
@@current = self
|
26
|
+
block.call.affect do
|
27
|
+
BusScheme::LOCAL_SCOPES.delete(scope)
|
28
|
+
@@current = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/test/test_eval.rb
CHANGED
@@ -35,7 +35,7 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_define
|
38
|
-
|
38
|
+
clear_symbols :foo
|
39
39
|
eval("(define foo 5)")
|
40
40
|
assert_equal 5, BusScheme[:foo]
|
41
41
|
eval("(define foo (quote (5 5 5))")
|
@@ -44,7 +44,6 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
44
44
|
|
45
45
|
def test_define_returns_defined_term
|
46
46
|
assert_evals_to :foo, "(define foo 2)"
|
47
|
-
# can't use the eval convenience testing method since it assumes strings are unparsed
|
48
47
|
assert_equal 2, eval("foo")
|
49
48
|
end
|
50
49
|
|
@@ -72,7 +71,7 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
72
71
|
end
|
73
72
|
|
74
73
|
def test_blows_up_with_undefined_symbol
|
75
|
-
assert_raises(
|
74
|
+
assert_raises(BusScheme::EvalError) { eval("undefined-symbol") }
|
76
75
|
end
|
77
76
|
|
78
77
|
def test_variable_substitution
|
@@ -94,65 +93,16 @@ class BusSchemeEvalTest < Test::Unit::TestCase
|
|
94
93
|
end
|
95
94
|
|
96
95
|
def test_set!
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
assert_equal :lambda, BusScheme[:foo].first
|
104
|
-
assert_evals_to 2, [:foo]
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_lambda_with_arg
|
108
|
-
eval("(define foo (lambda (x) (+ x 1)))")
|
109
|
-
assert_evals_to 2, [:foo, 1]
|
110
|
-
end
|
111
|
-
|
112
|
-
def test_eval_literal_lambda
|
113
|
-
assert_evals_to 4, "((lambda (x) (* x x)) 2)"
|
114
|
-
end
|
115
|
-
|
116
|
-
def test_lambda_with_incorrect_arity
|
117
|
-
eval("(define foo (lambda (x) (+ x 1)))")
|
118
|
-
assert_raises(BusScheme::ArgumentError) { assert_evals_to 2, [:foo, 1, 3] }
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_lambda_args_dont_stay_in_scope
|
122
|
-
BusScheme.clear_symbols(:x, :foo)
|
123
|
-
eval("(define foo (lambda (x) (+ x 1)))")
|
124
|
-
assert !BusScheme.in_scope?(:x)
|
125
|
-
assert_evals_to 2, [:foo, 1]
|
126
|
-
assert !BusScheme.in_scope?(:x)
|
127
|
-
end
|
128
|
-
|
129
|
-
# def test_lexical_scoping
|
130
|
-
# assert_raises(BusScheme::EvalError) do
|
131
|
-
# eval "???"
|
132
|
-
# end
|
133
|
-
# end
|
134
|
-
|
135
|
-
# def test_lambda_closures
|
136
|
-
# eval "(define foo (lambda (x) ((lambda (y) (+ x y)) (* x 2))))"
|
137
|
-
# assert_evals_to 3, [:foo, 1]
|
138
|
-
# end
|
139
|
-
|
140
|
-
# def test_load_file
|
141
|
-
# eval "(load \"#{File.dirname(__FILE__)}/foo.scm\")"
|
142
|
-
# assert_evals_to 3, :foo
|
143
|
-
# end
|
144
|
-
|
145
|
-
private
|
146
|
-
|
147
|
-
def eval(form) # convenience method that accepts string or form
|
148
|
-
if form.is_a?(String)
|
149
|
-
BusScheme.eval_string(form)
|
150
|
-
else
|
151
|
-
BusScheme.eval_form(form)
|
152
|
-
end
|
96
|
+
clear_symbols(:foo)
|
97
|
+
# can only set! existing variables
|
98
|
+
assert_raises(BusScheme::EvalError) { eval "(set! foo 7)" }
|
99
|
+
eval "(define foo 3)"
|
100
|
+
eval "(set! foo 7)"
|
101
|
+
assert_evals_to 7, :foo
|
153
102
|
end
|
154
103
|
|
155
|
-
def
|
156
|
-
|
104
|
+
def test_load_file
|
105
|
+
eval "(load \"#{File.dirname(__FILE__)}/foo.scm\")"
|
106
|
+
assert_evals_to 3, :foo
|
157
107
|
end
|
158
108
|
end
|
data/test/test_helper.rb
CHANGED
@@ -8,3 +8,20 @@ end
|
|
8
8
|
$LOAD_PATH << File.dirname(__FILE__) + '/../lib/'
|
9
9
|
require 'test/unit'
|
10
10
|
require 'bus_scheme'
|
11
|
+
|
12
|
+
def eval(form) # convenience method that accepts string or form
|
13
|
+
if form.is_a?(String)
|
14
|
+
BusScheme.eval_string(form)
|
15
|
+
else
|
16
|
+
BusScheme.eval_form(form)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def assert_evals_to(expected, form)
|
21
|
+
assert_equal expected, eval(form)
|
22
|
+
end
|
23
|
+
|
24
|
+
# remove symbols from all scopes
|
25
|
+
def clear_symbols(*symbols)
|
26
|
+
(BusScheme::LOCAL_SCOPES << BusScheme::SYMBOL_TABLE).map{ |scope| symbols.map{ |sym| scope.delete sym } }
|
27
|
+
end
|
data/test/test_lambda.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class BusScheme::Lambda
|
5
|
+
attr_accessor :body, :arg_names, :environment
|
6
|
+
end
|
7
|
+
|
8
|
+
class BusSchemeLambdaTest < Test::Unit::TestCase
|
9
|
+
def test_simple_lambda
|
10
|
+
l = eval("(lambda () (+ 1 1))")
|
11
|
+
assert l.is_a?(BusScheme::Lambda)
|
12
|
+
assert_equal [[:+, 1, 1]], l.body
|
13
|
+
assert_equal [], l.arg_names
|
14
|
+
|
15
|
+
eval("(define foo (lambda () (+ 1 1)))")
|
16
|
+
assert BusScheme[:foo].is_a?(BusScheme::Lambda)
|
17
|
+
assert_evals_to 2, [:foo]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_lambda_with_arg
|
21
|
+
eval("(define foo (lambda (x) (+ x 1)))")
|
22
|
+
assert_evals_to 2, [:foo, 1]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_eval_literal_lambda
|
26
|
+
assert_evals_to 4, "((lambda (x) (* x x)) 2)"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_lambda_with_incorrect_arity
|
30
|
+
eval("(define foo (lambda (x) (+ x 1)))")
|
31
|
+
assert_raises(BusScheme::ArgumentError) { assert_evals_to 2, [:foo, 1, 3] }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_lambda_args_dont_stay_in_scope
|
35
|
+
clear_symbols(:x, :foo)
|
36
|
+
eval("(define foo (lambda (x) (+ x 1)))")
|
37
|
+
assert_nil BusScheme.scope_of(:x)
|
38
|
+
assert_evals_to 2, [:foo, 1]
|
39
|
+
assert_nil BusScheme.scope_of(:x)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_lambda_calls_lambda
|
43
|
+
eval "(define f (lambda (x) (+ 3 x)))"
|
44
|
+
eval "(define g (lambda (y) (* 3 y)))"
|
45
|
+
assert_evals_to 12, "(f (g 3))"
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_lambda_closures
|
49
|
+
eval "(define foo (lambda (x) ((lambda (y) (+ x y)) (* x 2))))"
|
50
|
+
assert_evals_to 3, [:foo, 1]
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_changes_to_enclosed_variables_are_in_effect_after_lambda_execution
|
54
|
+
assert_evals_to 2, "((lambda (x) (begin ((lambda () (set! x 2))) x)) 1)"
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_implicit_begin
|
58
|
+
assert_evals_to 3, "((lambda () (intern \"hi\") (+ 2 2) (* 1 3)))"
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bus-scheme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
5
|
-
platform:
|
4
|
+
version: "0.7"
|
5
|
+
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Hagelberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-01-10 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
22
|
+
version: 1.4.0
|
23
23
|
version:
|
24
24
|
description: Bus Scheme is a Scheme written in Ruby, but implemented on the bus! Every programmer must implement Scheme as a rite of passage; this is mine. Note that all the implementation of Bus Scheme must be written while on a bus. Documentation, tests, and administrivia may be accomplished elsewhere, but all actual implementation code is strictly bus-driven. Patches are welcome as long as they were written while riding a bus. (If your daily commute does not involve a bus but you want to submit a patch, we may be able to work something out regarding code written on trains, ferries, or perhaps even carpool lanes.) Bus Scheme is primarily a toy; using it for anything serious is (right now) ill-advised. Bus Scheme aims for general Scheme usefulness optimized for learning and fun. It's not targeting R5RS or anything like that. == Install * sudo gem install bus-scheme
|
25
25
|
email: technomancy@gmail.com
|
@@ -39,6 +39,8 @@ files:
|
|
39
39
|
- lib/array_extensions.rb
|
40
40
|
- lib/bus_scheme.rb
|
41
41
|
- lib/eval.rb
|
42
|
+
- lib/lambda.rb
|
43
|
+
- lib/definitions.rb
|
42
44
|
- lib/object_extensions.rb
|
43
45
|
- lib/parser.rb
|
44
46
|
- test/foo.scm
|
@@ -68,11 +70,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
70
|
requirements: []
|
69
71
|
|
70
72
|
rubyforge_project: bus-scheme
|
71
|
-
rubygems_version: 0.
|
73
|
+
rubygems_version: 1.0.0
|
72
74
|
signing_key:
|
73
75
|
specification_version: 2
|
74
76
|
summary: Bus Scheme is a Scheme in Ruby, imlemented on the bus.
|
75
77
|
test_files:
|
78
|
+
- test/test_lambda.rb
|
76
79
|
- test/test_parser.rb
|
77
|
-
- test/test_helper.rb
|
78
80
|
- test/test_eval.rb
|
81
|
+
- test/test_helper.rb
|