flea 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/build.yml +30 -0
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +30 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +65 -0
- data/MIT-LICENSE +1 -1
- data/README.md +345 -0
- data/bin/flea +17 -15
- data/flea-language-spec/{README.rdoc → README.md} +2 -2
- data/flea-language-spec/test-cases/01-display-and-basic-literals/05-display-list-literal-using-quote.scm +1 -1
- data/flea-language-spec/test-cases/02-variables/05-define-with-list.scm +1 -1
- data/flea-language-spec/test-cases/04-quoting/01-quoting.scm +5 -0
- data/flea.gemspec +34 -0
- data/lib/flea/environment.rb +20 -18
- data/lib/flea/interpreter.rb +44 -44
- data/lib/flea/standard_library/display.scm +7 -1
- data/lib/flea/standard_library/null.scm +1 -1
- data/lib/flea/standard_library/read.scm +1 -1
- data/lib/flea/version.rb +5 -0
- data/lib/flea.rb +6 -4
- metadata +110 -138
- data/README.rdoc +0 -274
- data/Rakefile +0 -36
- data/VERSION +0 -1
- data/flea-language-spec/test-cases/04-comma-quoting/01-comma-quoting.scm +0 -5
- data/spec/flea/environment_spec.rb +0 -114
- data/spec/flea/interpreter_spec.rb +0 -85
- data/spec/flea/standard_library/addition_operator_spec.rb +0 -23
- data/spec/flea/standard_library/append_spec.rb +0 -17
- data/spec/flea/standard_library/begin_spec.rb +0 -20
- data/spec/flea/standard_library/car_spec.rb +0 -17
- data/spec/flea/standard_library/cdr_spec.rb +0 -17
- data/spec/flea/standard_library/cons_spec.rb +0 -25
- data/spec/flea/standard_library/display_spec.rb +0 -36
- data/spec/flea/standard_library/division_operator_spec.rb +0 -29
- data/spec/flea/standard_library/equality_operator_spec.rb +0 -45
- data/spec/flea/standard_library/gets_spec.rb +0 -23
- data/spec/flea/standard_library/greater_than_spec.rb +0 -29
- data/spec/flea/standard_library/if_spec.rb +0 -59
- data/spec/flea/standard_library/lambda_spec.rb +0 -70
- data/spec/flea/standard_library/less_than_spec.rb +0 -29
- data/spec/flea/standard_library/list_predicate_spec.rb +0 -25
- data/spec/flea/standard_library/list_spec.rb +0 -24
- data/spec/flea/standard_library/list_tail_spec.rb +0 -17
- data/spec/flea/standard_library/mutiplication_operator_spec.rb +0 -23
- data/spec/flea/standard_library/null_spec.rb +0 -26
- data/spec/flea/standard_library/quote_spec.rb +0 -20
- data/spec/flea/standard_library/rand_spec.rb +0 -25
- data/spec/flea/standard_library/read_spec.rb +0 -23
- data/spec/flea/standard_library/set_spec.rb +0 -23
- data/spec/flea/standard_library/string_to_num_spec.rb +0 -28
- data/spec/flea/standard_library/subtraction_operator_spec.rb +0 -24
- data/spec/spec_helper.rb +0 -10
data/README.rdoc
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
= Flea
|
2
|
-
|
3
|
-
Flea is a tiny Lisp interpreter implemented in Ruby. Flea is not designed to be a production language, instead it is designed to be an example of how simple it can be to bootstrap the core of a small flexible language. Flea essentially defines an informal subset of Scheme, just enough to be fun and interesting.
|
4
|
-
|
5
|
-
=== A Quick Example
|
6
|
-
|
7
|
-
This is the classic 'guess the number' program implemented in Flea:
|
8
|
-
|
9
|
-
(define number (+ (rand 9) 1))
|
10
|
-
|
11
|
-
(display "\n\nI'm thinking of a number between 1 and 10,\n")
|
12
|
-
(display "try to guess it!\n\n")
|
13
|
-
|
14
|
-
(define user-guess
|
15
|
-
(lambda ()
|
16
|
-
(display "Take a guess - ")
|
17
|
-
(define guess (string-to-num (gets)))
|
18
|
-
(if (equal? guess number)
|
19
|
-
(display "Good guess!\n")
|
20
|
-
(begin
|
21
|
-
(if (greater-than? guess number)
|
22
|
-
(display "Lower!\n")
|
23
|
-
(display "Higher!\n"))
|
24
|
-
(user-guess)))))
|
25
|
-
|
26
|
-
(user-guess)
|
27
|
-
|
28
|
-
=== Installation
|
29
|
-
|
30
|
-
For ease of use the Flea is packaged as a RubyGem. Providing you already have Ruby and RubyGems installing Flea is as easy as entering the following command in a terminal:
|
31
|
-
|
32
|
-
gem install flea
|
33
|
-
|
34
|
-
Mac OS X and most Unix/Linux distributions come with an installation of Ruby and RubyGems. If you do not have Ruby and RubyGems installed please check the {Ruby website for instructions}[http://www.ruby-lang.org/en/downloads/].
|
35
|
-
|
36
|
-
=== Usage
|
37
|
-
|
38
|
-
After Flea is installed you can run a program by typing the following on the command line:
|
39
|
-
|
40
|
-
flea /path/to/program
|
41
|
-
|
42
|
-
You can also launch Flea's interactive shell by simply calling `flea` with no arguments.
|
43
|
-
|
44
|
-
=== Author & Credits
|
45
|
-
|
46
|
-
Author:: {Aaron Gough}[mailto:aaron@aarongough.com]
|
47
|
-
|
48
|
-
Copyright (c) 2010 {Aaron Gough}[http://thingsaaronmade.com/] ({thingsaaronmade.com}[http://thingsaaronmade.com/]), released under the MIT license
|
49
|
-
|
50
|
-
---
|
51
|
-
|
52
|
-
== API Documentation and More Info
|
53
|
-
|
54
|
-
=== More Info
|
55
|
-
|
56
|
-
Flea's core is only about 100 lines of code, and provides a simple interface that is used to build the rest of the language. Flea is highly extensible because of its foreign function interface which allows Ruby Proc objects to be defined and then executed within the context of the Flea interpreter. The entire standard library of the language is implemented using this foreign function interface. For example, here is the implementation of the multiplication operator:
|
57
|
-
|
58
|
-
(define *
|
59
|
-
(native_function "
|
60
|
-
Proc.new() do |arguments, interpreter|
|
61
|
-
tmp = arguments.map {|item| interpreter.evaluate(item)}
|
62
|
-
tmp.inject {|sum, n| sum * n}
|
63
|
-
end
|
64
|
-
"))
|
65
|
-
|
66
|
-
=== API
|
67
|
-
|
68
|
-
Flea comes with a small but thoughtful standard library that includes functions for:
|
69
|
-
|
70
|
-
==== Output
|
71
|
-
|
72
|
-
(display) Outputs data to STDOUT:
|
73
|
-
|
74
|
-
(display "test")
|
75
|
-
# => test
|
76
|
-
|
77
|
-
(display '(1 2 3))
|
78
|
-
# => (1 2 3)
|
79
|
-
|
80
|
-
==== Input
|
81
|
-
|
82
|
-
(read) Reads and parses an s-expression from STDIN:
|
83
|
-
|
84
|
-
(read) # user enters '(1 2 3)'
|
85
|
-
# => (1 2 3)
|
86
|
-
|
87
|
-
(gets) Reads a string from STDIN:
|
88
|
-
|
89
|
-
(gets) # user enters '(1 2 3)'
|
90
|
-
# => "(1 2 3)"
|
91
|
-
|
92
|
-
==== Variables
|
93
|
-
|
94
|
-
(define) Sets a variable:
|
95
|
-
|
96
|
-
(define test 1)
|
97
|
-
(display test)
|
98
|
-
# => 1
|
99
|
-
|
100
|
-
(set!) Re-defines an existing variable:
|
101
|
-
|
102
|
-
(define test 1)
|
103
|
-
(set! test 2)
|
104
|
-
(display test)
|
105
|
-
# => 2
|
106
|
-
|
107
|
-
==== Numeric operations
|
108
|
-
|
109
|
-
(+) Add one or more numbers:
|
110
|
-
|
111
|
-
(+ 1 2 3)
|
112
|
-
# => 6
|
113
|
-
|
114
|
-
(-) Subtract one or more numbers:
|
115
|
-
|
116
|
-
(- 10 2 1)
|
117
|
-
# => 7
|
118
|
-
|
119
|
-
(*) Multiply one or more numbers:
|
120
|
-
|
121
|
-
(* 10 2 4)
|
122
|
-
# => 80
|
123
|
-
|
124
|
-
(/) Divide one or more numbers:
|
125
|
-
|
126
|
-
(/ 100 2 2)
|
127
|
-
# => 25
|
128
|
-
|
129
|
-
(greater-than?) Returns true if it's first argument is greater than all the others, false otherwise:
|
130
|
-
|
131
|
-
(greater-than? 10 2 3 4)
|
132
|
-
# => #t
|
133
|
-
|
134
|
-
(greater-than? 1 2 3 4)
|
135
|
-
# => #f
|
136
|
-
|
137
|
-
(less-than?) Returns true if it's first argument is smaller than all the others, false otherwise:
|
138
|
-
|
139
|
-
(less-than? 1 3 4 5)
|
140
|
-
# => #t
|
141
|
-
|
142
|
-
(less-than? 50 2 45 100)
|
143
|
-
# => #f
|
144
|
-
|
145
|
-
(equal?) and (=) Return true if all their arguments are the same, false otherwise:
|
146
|
-
|
147
|
-
(equal? 1 1 1)
|
148
|
-
# => #t
|
149
|
-
|
150
|
-
(= 1 2 3)
|
151
|
-
# => #f
|
152
|
-
|
153
|
-
==== List creation and manipulation
|
154
|
-
|
155
|
-
(list) Creates a new list from it's arguments:
|
156
|
-
|
157
|
-
(list (+ 1 2) "test" (rand 10))
|
158
|
-
# => (3 "test" 5)
|
159
|
-
|
160
|
-
(list?) Returns true if it's first argument is a list, false otherwise:
|
161
|
-
|
162
|
-
(list? '())
|
163
|
-
# => #t
|
164
|
-
|
165
|
-
(list? 1)
|
166
|
-
# => #f
|
167
|
-
|
168
|
-
(list-tail) Returns a new list created by removing the first n elements of the provided list:
|
169
|
-
|
170
|
-
(define a '(1 2 3 4 5 6))
|
171
|
-
(list-tail a 3)
|
172
|
-
# => (4 5 6)
|
173
|
-
|
174
|
-
(car) Returns the first item of a list:
|
175
|
-
|
176
|
-
(car '(1 2 3))
|
177
|
-
# => 1
|
178
|
-
|
179
|
-
(cdr) Returns the remainder of a list:
|
180
|
-
|
181
|
-
(cdr '(1 2 3))
|
182
|
-
# => (2 3)
|
183
|
-
|
184
|
-
(cons) Creates a new list by using it's first argument as the CAR it's second argument as the CDR:
|
185
|
-
|
186
|
-
(cons '(1 2 3) 3)
|
187
|
-
# => ((1 2 3) 3)
|
188
|
-
|
189
|
-
(cons 1 2)
|
190
|
-
# => (1 2)
|
191
|
-
|
192
|
-
(cons 1 (2 3 4))
|
193
|
-
# => (1 2 3 4)
|
194
|
-
|
195
|
-
(append) Creates a new list by concatenating it's arguments, it's first argument must be a list:
|
196
|
-
|
197
|
-
(append '(1 2) '(3 4) 5)
|
198
|
-
# => (1 2 3 4 5)
|
199
|
-
|
200
|
-
(null?) Returns true if it's first argument is null (the empty list):
|
201
|
-
|
202
|
-
(null '())
|
203
|
-
# => #t
|
204
|
-
|
205
|
-
(null '(1 2 3))
|
206
|
-
# => #f
|
207
|
-
|
208
|
-
(null? 1)
|
209
|
-
# => #f
|
210
|
-
|
211
|
-
==== Conditionals
|
212
|
-
|
213
|
-
(if) If it's first argument is true then it will execute it's first code block, otherwise it will execute the second code block (if any):
|
214
|
-
|
215
|
-
(if (equal? 1 1)
|
216
|
-
(display "true")
|
217
|
-
(display "false"))
|
218
|
-
# => true
|
219
|
-
|
220
|
-
(if (equal? 2 1)
|
221
|
-
(display "true")
|
222
|
-
(display "false"))
|
223
|
-
# => false
|
224
|
-
|
225
|
-
==== Function creation
|
226
|
-
|
227
|
-
(lambda) Creates a new function:
|
228
|
-
|
229
|
-
(define adder
|
230
|
-
(lambda (a)
|
231
|
-
(+ a 10)))
|
232
|
-
|
233
|
-
(adder 5)
|
234
|
-
# => 15
|
235
|
-
|
236
|
-
For more info on lambda syntax read the {R5RS Scheme specification}[http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.1.4]
|
237
|
-
|
238
|
-
==== Type conversion
|
239
|
-
|
240
|
-
(string-to-num) Converts a string containing a number into a numeric literal:
|
241
|
-
|
242
|
-
(string-to-num "123")
|
243
|
-
# => 123
|
244
|
-
|
245
|
-
==== Misc
|
246
|
-
|
247
|
-
(rand) Returns a random number less than or equal to it's first argument:
|
248
|
-
|
249
|
-
(rand 10)
|
250
|
-
# => 1
|
251
|
-
|
252
|
-
(rand 10)
|
253
|
-
# => 6
|
254
|
-
|
255
|
-
==== Foreign function interface
|
256
|
-
|
257
|
-
(native_function) Takes a string representing a Ruby Proc object and returns it in a form that is able to be called like any other Flea function. The proc must take two arguments (arguments and interpreter):
|
258
|
-
|
259
|
-
(define test
|
260
|
-
(native_function "
|
261
|
-
Proc.new() do |arguments, interpreter|
|
262
|
-
puts "Arguments class: " + arguments.class
|
263
|
-
puts "Arguments: " + arguments.inspect
|
264
|
-
puts "Interpreter class: " + interpreter.class
|
265
|
-
puts "foo"
|
266
|
-
end
|
267
|
-
")
|
268
|
-
|
269
|
-
(test 1 2 3 4)
|
270
|
-
# => Arguments class: Array
|
271
|
-
Arguments: [1, 2, 3, 4]
|
272
|
-
Interpreter class: Flea::Interpreter
|
273
|
-
foo
|
274
|
-
|
data/Rakefile
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'any-spec'
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'jeweler'
|
7
|
-
Jeweler::Tasks.new do |gemspec|
|
8
|
-
gemspec.name = "flea"
|
9
|
-
gemspec.summary = "A tiny but flexible Lisp interpreter written in Ruby"
|
10
|
-
gemspec.description = "Flea is an extremely simple, but extremely extensible Lisp interpreter written in Ruby."
|
11
|
-
gemspec.email = "aaron@aarongough.com"
|
12
|
-
gemspec.homepage = "http://github.com/aarongough/flea"
|
13
|
-
gemspec.authors = ["Aaron Gough"]
|
14
|
-
gemspec.rdoc_options << '--line-numbers' << '--inline-source'
|
15
|
-
gemspec.extra_rdoc_files = ['README.rdoc', 'MIT-LICENSE']
|
16
|
-
gemspec.add_dependency "sexpistol"
|
17
|
-
gemspec.add_development_dependency "any-spec"
|
18
|
-
gemspec.executables << 'flea'
|
19
|
-
end
|
20
|
-
rescue LoadError
|
21
|
-
puts "Jeweler not available. Install it with: gem install jeweler"
|
22
|
-
end
|
23
|
-
|
24
|
-
task :test => [:spec, :anyspec]
|
25
|
-
|
26
|
-
task :anyspec do
|
27
|
-
test_runner = AnySpec::TestRunner.new("./bin/flea", "./flea-language-spec/flea-language-spec.yaml")
|
28
|
-
test_runner.run_tests
|
29
|
-
end
|
30
|
-
|
31
|
-
desc "Run the specs for Flea"
|
32
|
-
RSpec::Core::RakeTask.new do |t|
|
33
|
-
t.rspec_opts = "-c"
|
34
|
-
t.fail_on_error = false
|
35
|
-
t.verbose = false
|
36
|
-
end
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.0
|
@@ -1,114 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe "Flea" do
|
4
|
-
describe "::Environment" do
|
5
|
-
|
6
|
-
include Flea
|
7
|
-
|
8
|
-
describe ".new" do
|
9
|
-
it "should return an environment object" do
|
10
|
-
Environment.new.should be_an Environment
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should return an environment object with no parent" do
|
14
|
-
environment = Environment.new
|
15
|
-
environment.parent.should be_nil
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should return an environment object with the specified parent" do
|
19
|
-
parent_environment = mock("Environment")
|
20
|
-
environment = Environment.new(parent_environment)
|
21
|
-
environment.parent.should be parent_environment
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should add base variables for #t and #f" do
|
25
|
-
environment = Environment.new
|
26
|
-
environment.should have_variable :"#t"
|
27
|
-
environment.should have_variable :"#f"
|
28
|
-
environment.find(:"#t").should be_true
|
29
|
-
environment.find(:"#f").should be_false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#has_variable?" do
|
34
|
-
context "without a parent" do
|
35
|
-
before :each do
|
36
|
-
@environment = Environment.new
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should return false if the variable is not set in the current environment" do
|
40
|
-
@environment.should_not have_variable :test
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should return true if the variable is set in the current environment" do
|
44
|
-
@environment.define(:test, 1)
|
45
|
-
@environment.should have_variable :test
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context "with a parent" do
|
50
|
-
before :each do
|
51
|
-
@parent_environment = Environment.new
|
52
|
-
@environment = Environment.new(@parent_environment)
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should return false if the variable is not set in the parent environment" do
|
56
|
-
@environment.should_not have_variable :test
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should return true if the variable is set in the parent environment" do
|
60
|
-
@parent_environment.define(:test, 1)
|
61
|
-
@environment.should have_variable :test
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe "#define" do
|
67
|
-
it "should set a variable to the supplied value" do
|
68
|
-
env = Environment.new
|
69
|
-
result = env.define(:test, 1)
|
70
|
-
env.should have_variable :test
|
71
|
-
env.find(:test).should == 1
|
72
|
-
result.should == 1
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "#find" do
|
77
|
-
context "without a parent" do
|
78
|
-
before :each do
|
79
|
-
@environment = Environment.new
|
80
|
-
@environment.define(:test, 1)
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should find a variable in the current environment" do
|
84
|
-
@environment.find(:test).should == 1
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should return nil when variable is not set" do
|
88
|
-
@environment.find(:fake).should be_nil
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "with a parent" do
|
93
|
-
before :each do
|
94
|
-
@parent_environment = Environment.new
|
95
|
-
@environment = Environment.new(@parent_environment)
|
96
|
-
@parent_environment.define(:test, 1)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should find a variable in the parent environment" do
|
100
|
-
@environment.find(:test).should == 1
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should return a variable from the current environment if it is set in both current and parent" do
|
104
|
-
@environment.define(:test, 5)
|
105
|
-
@environment.find(:test).should == 5
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should return nil when variable is not set in the current or parent environment" do
|
109
|
-
@environment.find(:fake).should be_nil
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe "Flea" do
|
4
|
-
describe "::Interpreter" do
|
5
|
-
|
6
|
-
include Flea
|
7
|
-
|
8
|
-
describe "#new" do
|
9
|
-
it "should return an Interpreter" do
|
10
|
-
Interpreter.new.should be_an Interpreter
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should allow setting the base environment to use" do
|
14
|
-
environment = mock("Environment")
|
15
|
-
interpreter = Interpreter.new(
|
16
|
-
:base_environment => environment,
|
17
|
-
:load_standard_library => false
|
18
|
-
)
|
19
|
-
interpreter.base_environment.should be environment
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe ".run" do
|
24
|
-
it "should run a program and return the last output from the program" do
|
25
|
-
interpreter = Interpreter.new
|
26
|
-
result = interpreter.run("(define test 1)")
|
27
|
-
result.should == 1
|
28
|
-
interpreter.base_environment.should have_variable :test
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe ".parse" do
|
33
|
-
it "should return an abstract syntax tree representing the supplied program" do
|
34
|
-
ast = Interpreter.new.parse("(define test 1)")
|
35
|
-
ast.should == [[:define, :test, 1]]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe ".evaluate" do
|
40
|
-
before :each do
|
41
|
-
@environment = mock("Environment")
|
42
|
-
@interpreter = Interpreter.new(
|
43
|
-
:base_environment => @environment,
|
44
|
-
:load_standard_library => false
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should return the value of a variable" do
|
49
|
-
@environment.should_receive(:find).with(:test).and_return(1)
|
50
|
-
result = @interpreter.evaluate(:test)
|
51
|
-
result.should == 1
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should define a variable in the current environment" do
|
55
|
-
@environment.should_receive(:define).with(:test, 1).and_return(1)
|
56
|
-
result = @interpreter.evaluate([:define, :test, 1])
|
57
|
-
result.should == 1
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should create a native function" do
|
61
|
-
result = @interpreter.evaluate([:native_function, "
|
62
|
-
Proc.new() do |arguments, interpreter|
|
63
|
-
1
|
64
|
-
end
|
65
|
-
"])
|
66
|
-
result.should be_a Proc
|
67
|
-
result.call.should == 1
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should call a native function" do
|
71
|
-
@environment.should_receive(:find).with(:foo).and_return(Proc.new {|a,b| "bar"})
|
72
|
-
result = @interpreter.evaluate([:foo, 1, 2, 3])
|
73
|
-
result.should == "bar"
|
74
|
-
end
|
75
|
-
|
76
|
-
[1, 1.0, "string"].each do |literal|
|
77
|
-
it "should return literal '#{literal}' as is" do
|
78
|
-
result = @interpreter.evaluate(literal)
|
79
|
-
result.should be literal
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "addition operator" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should add several numbers" do
|
10
|
-
result = @interpreter.run('(+ 1 2 3)')
|
11
|
-
result.should == 6
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should evaluate its arguments before adding them" do
|
15
|
-
result = @interpreter.run('
|
16
|
-
(define a 2)
|
17
|
-
(+ a a a)
|
18
|
-
')
|
19
|
-
result.should == 6
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "append" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "union of two lists" do
|
10
|
-
result = @interpreter.run('
|
11
|
-
(append (quote (1 2 3)) (quote (1 2 3)))
|
12
|
-
')
|
13
|
-
result.should == [1, 2, 3, 1, 2, 3]
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "begin" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should execute each expression after the begin call and return final value" do
|
10
|
-
result = @interpreter.run('
|
11
|
-
(begin
|
12
|
-
(define test 1)
|
13
|
-
(set! test 2))
|
14
|
-
')
|
15
|
-
result.should == 2
|
16
|
-
@interpreter.base_environment.find(:test).should == 2
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "car" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should return first item of list" do
|
10
|
-
result = @interpreter.run('
|
11
|
-
(car (quote (10 2 2)))
|
12
|
-
')
|
13
|
-
result.should == 10
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "cdr" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should return remainder of list" do
|
10
|
-
result = @interpreter.run('
|
11
|
-
(cdr (quote (10 2 2)))
|
12
|
-
')
|
13
|
-
result.should == [2, 2]
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "cons" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should create a list from an atom and an empty list" do
|
10
|
-
result = @interpreter.run("(cons 'a '())")
|
11
|
-
result.should == [:a]
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should create a list from a pair of lists" do
|
15
|
-
result = @interpreter.run("(cons '(a) '(b c d))")
|
16
|
-
result.should == [[:a], :b, :c, :d]
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should push an atom on an existing list" do
|
20
|
-
result = @interpreter.run('(cons "a" \'(b c ))')
|
21
|
-
result.should == ["a", :b, :c]
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
-
|
3
|
-
describe "Standard Library" do
|
4
|
-
describe "display" do
|
5
|
-
before :each do
|
6
|
-
@interpreter = Flea::Interpreter.new
|
7
|
-
@old_stdout = $stdout
|
8
|
-
@buffer = StringIO.new
|
9
|
-
$stdout = @buffer
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should output simple literal" do
|
13
|
-
@interpreter.run('(display 1)')
|
14
|
-
@buffer.string.should == "1"
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should output a list" do
|
18
|
-
@interpreter.run('(display (quote (1 2 3)))')
|
19
|
-
@buffer.string.should == "(1 2 3)"
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should output true and false using Scheme external representation" do
|
23
|
-
@interpreter.run('(display #t)(display #f)')
|
24
|
-
@buffer.string.should == "#t#f"
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return the same value that it displayed" do
|
28
|
-
result = @interpreter.run('(display "abc")')
|
29
|
-
result.should == "abc"
|
30
|
-
end
|
31
|
-
|
32
|
-
after :each do
|
33
|
-
$stdout = @old_stdout
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|