heist 0.3.2 → 0.3.3
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/History.txt +12 -0
- data/{README.txt → README.rdoc} +131 -148
- data/bin/heist +35 -10
- data/lib/heist.rb +3 -3
- data/lib/heist/builtin/compiled_library.rb +1 -0
- data/lib/heist/builtin/lib/character.scm +74 -0
- data/lib/heist/builtin/lib/list.scm +149 -0
- data/lib/heist/builtin/lib/logic.scm +17 -0
- data/lib/heist/builtin/lib/numeric.scm +184 -0
- data/lib/heist/builtin/lib/string.scm +117 -0
- data/lib/heist/builtin/lib/util.scm +18 -0
- data/lib/heist/builtin/lib/vector.scm +27 -0
- data/lib/{builtin → heist/builtin}/primitives.rb +0 -0
- data/lib/{builtin → heist/builtin}/syntax.scm +52 -52
- data/lib/{parser → heist/parser}/nodes.rb +0 -0
- data/lib/{parser → heist/parser}/ruby.rb +0 -0
- data/lib/{parser → heist/parser}/scheme.rb +0 -0
- data/lib/{parser → heist/parser}/scheme.tt +0 -0
- data/lib/{repl.rb → heist/repl.rb} +0 -0
- data/lib/{runtime → heist/runtime}/binding.rb +5 -0
- data/lib/{runtime → heist/runtime}/callable/continuation.rb +6 -1
- data/lib/{runtime → heist/runtime}/callable/function.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro.rb +1 -1
- data/lib/{runtime → heist/runtime}/callable/macro/expansion.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro/matches.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro/tree.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/syntax.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/character.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/cons.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/expression.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/identifier.rb +0 -0
- data/lib/heist/runtime/data/value.rb +14 -0
- data/lib/{runtime → heist/runtime}/data/vector.rb +0 -0
- data/lib/{runtime → heist/runtime}/frame.rb +3 -0
- data/lib/{runtime → heist/runtime}/runtime.rb +2 -2
- data/lib/{runtime → heist/runtime}/scope.rb +0 -0
- data/lib/{runtime → heist/runtime}/stack.rb +0 -0
- data/lib/{runtime → heist/runtime}/stackless.rb +0 -0
- data/lib/{stdlib → heist/stdlib}/benchmark.scm +0 -0
- data/lib/{stdlib → heist/stdlib}/birdhouse.scm +0 -0
- data/lib/{trie.rb → heist/trie.rb} +0 -0
- data/spec/heist_spec.rb +88 -0
- data/{test → spec}/helpers/lib.scm +0 -0
- data/{test → spec}/helpers/macro-helpers.scm +0 -0
- data/{test → spec}/helpers/vars.scm +0 -0
- data/{test → spec}/plt-macros.txt +0 -0
- data/{test → spec}/scheme_tests/arithmetic.scm +0 -0
- data/{test → spec}/scheme_tests/benchmarks.scm +0 -0
- data/{test → spec}/scheme_tests/booleans.scm +0 -0
- data/{test → spec}/scheme_tests/closures.scm +0 -0
- data/{test → spec}/scheme_tests/conditionals.scm +0 -0
- data/{test → spec}/scheme_tests/continuations.scm +14 -1
- data/{test → spec}/scheme_tests/define_functions.scm +0 -0
- data/{test → spec}/scheme_tests/define_values.scm +0 -0
- data/{test → spec}/scheme_tests/delay.scm +0 -0
- data/{test → spec}/scheme_tests/equivalence.scm +0 -0
- data/{test → spec}/scheme_tests/file_loading.scm +0 -0
- data/{test → spec}/scheme_tests/functional.scm +3 -0
- data/{test → spec}/scheme_tests/hygienic.scm +0 -0
- data/{test → spec}/scheme_tests/let.scm +0 -0
- data/{test → spec}/scheme_tests/lists.scm +0 -0
- data/{test → spec}/scheme_tests/macros.scm +0 -0
- data/{test → spec}/scheme_tests/numbers.scm +0 -0
- data/{test → spec}/scheme_tests/protection.scm +0 -0
- data/spec/scheme_tests/quoting.scm +14 -0
- data/{test → spec}/scheme_tests/strings.scm +0 -0
- data/{test → spec}/scheme_tests/unhygienic.scm +0 -0
- data/{test → spec}/scheme_tests/vectors.scm +0 -0
- data/spec/spec_helper.rb +4 -0
- metadata +98 -113
- data/Manifest.txt +0 -64
- data/Rakefile +0 -43
- data/lib/bin_spec.rb +0 -25
- data/lib/builtin/library.rb +0 -1
- data/lib/builtin/library.scm +0 -605
- data/test/test_heist.rb +0 -148
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== Version 0.3.3 (2011-10-24)
|
2
|
+
In memory of John McCarthy, inventor of Lisp. His work made language hacking
|
3
|
+
accessible, and this project would not exist without it.
|
4
|
+
|
5
|
+
http://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)
|
6
|
+
|
7
|
+
* Add the R6RS (fold-left) and (fold-right) procedures
|
8
|
+
* Allow continuations to be called using (apply)
|
9
|
+
* Stop re-evaluating data passed to a continuation and injected into a macro
|
10
|
+
* Split built-in library into files by data type (Fargo uses them)
|
11
|
+
|
12
|
+
|
1
13
|
=== Version 0.3.2 (2010-01-16)
|
2
14
|
|
3
15
|
* Built-in library code is executed in a protected scope so that redefinitions of
|
data/{README.txt → README.rdoc}
RENAMED
@@ -2,35 +2,33 @@
|
|
2
2
|
|
3
3
|
http://github.com/jcoglan/heist
|
4
4
|
|
5
|
-
Heist is a Scheme interpreter written in Ruby. It provides an executable
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
Heist is a Scheme interpreter written in Ruby. It provides an executable for
|
6
|
+
running Scheme code directly, and also allows the interpreter to be easily
|
7
|
+
embedded in, and extended using, Ruby applications. It nominally targets R5RS,
|
8
|
+
though is likely to be more liberal than other implementations.
|
9
9
|
|
10
10
|
|
11
11
|
== What is Scheme?
|
12
12
|
|
13
|
-
Scheme is a dialect of Lisp, one of the oldest programming languages still
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
Scheme in particular is important for its influence on current languages,
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
It is a functional language, in that it supports first-class functions
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
source code) make it ideal for creating new syntactic forms and embedded
|
33
|
-
languages.
|
13
|
+
Scheme is a dialect of Lisp, one of the oldest programming languages still in
|
14
|
+
use today. Lisp was the first language to implement conditionals, first class
|
15
|
+
functions (lambdas), closures and recursion. Some Lisp features, such as
|
16
|
+
closures and macros, have yet to penetrate mainstream languages and it has been
|
17
|
+
observed that mainstream languages are slowly converging on the feature set of
|
18
|
+
Lisp.
|
19
|
+
|
20
|
+
Scheme in particular is important for its influence on current languages, in
|
21
|
+
particular JavaScript and Ruby (JavaScript is remarkably similar to Scheme if
|
22
|
+
you ignore the syntactic differences). It is also used in the much-praised book
|
23
|
+
"Structure and Interpretation of Computer Programs", wherein it is used to
|
24
|
+
explore some of the theory surrounding interpreters.
|
25
|
+
|
26
|
+
It is a functional language, in that it supports first-class functions and many
|
27
|
+
constructs that would be syntax in other languages resemble function calls in
|
28
|
+
Scheme. However it is not purely functional as it allows side effects, and is
|
29
|
+
more procedural in nature than Haskell and its ilk. Like other Lisps, its lack
|
30
|
+
of predefined syntax and its support for macros (functions that rewrite source
|
31
|
+
code) make it ideal for creating new syntactic forms and embedded languages.
|
34
32
|
|
35
33
|
|
36
34
|
== Features
|
@@ -104,58 +102,53 @@ Currently implemented R5RS features include:
|
|
104
102
|
<tt>for-each</tt>, <tt>eval</tt>, <tt>load</tt>
|
105
103
|
* Input/output: <tt>display</tt>, <tt>newline</tt>
|
106
104
|
|
107
|
-
In addition to the above R5RS features, the following are provided. Heist
|
108
|
-
|
105
|
+
In addition to the above R5RS features, the following are provided. Heist allows
|
106
|
+
the behaviour of some of these features to be configured on a
|
109
107
|
per-runtime-environment basis.
|
110
108
|
|
111
|
-
* <b>More-helpful-than-usual REPL</b>. Heist's REPL does not clutter
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
a file without modification.
|
109
|
+
* <b>More-helpful-than-usual REPL</b>. Heist's REPL does not clutter your
|
110
|
+
display with prompts and other such cruft. It indents your code automatically,
|
111
|
+
supports tab completion, and output is printed as comments so it's simple to
|
112
|
+
copy code out of a REPL session into a file without modification.
|
116
113
|
* <b>Transparent lazy evaluation (call by need)</b>. Expressions are not
|
117
|
-
evaluated before being passed as arguments, instead they are
|
118
|
-
|
119
|
-
* <b>Unhygienic macros</b>. Scheme mandates hygienic macros that
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
constant performance overhead, so if you don't need them you can
|
126
|
-
switch them off.
|
114
|
+
evaluated before being passed as arguments, instead they are evaluated as and
|
115
|
+
when the called function requires their values.
|
116
|
+
* <b>Unhygienic macros</b>. Scheme mandates hygienic macros that preserve
|
117
|
+
lexical scoping, but other Lisps use a simpler system that does not impose
|
118
|
+
this restriction. Heist allows hygiene to be disabled, its author not having
|
119
|
+
the requisite experience to decide which system he prefers yet.
|
120
|
+
* <b>Optional continuations</b>. Supporting continuations incurs a constant
|
121
|
+
performance overhead, so if you don't need them you can switch them off.
|
127
122
|
|
128
123
|
|
129
124
|
== Installation and Usage
|
130
125
|
|
131
|
-
|
132
|
-
sudo gem install heist
|
126
|
+
gem install heist
|
133
127
|
|
134
128
|
Heist can be run from the command line or embedded in Ruby applications. To
|
135
129
|
run a Scheme file:
|
136
130
|
|
137
131
|
heist path/to/file.scm
|
138
132
|
|
139
|
-
To start
|
133
|
+
To start a REPL session:
|
140
134
|
|
141
135
|
heist -i
|
142
136
|
|
143
|
-
Both these commands accept a number of runtime configuration options;
|
144
|
-
|
137
|
+
Both these commands accept a number of runtime configuration options; run
|
138
|
+
<tt>heist -h</tt> for more information.
|
145
139
|
|
146
140
|
|
147
141
|
=== Embed in your Ruby app
|
148
142
|
|
149
|
-
To embed Heist in a Ruby application, you need to create an instance of
|
150
|
-
|
143
|
+
To embed Heist in a Ruby application, you need to create an instance of the
|
144
|
+
runtime:
|
151
145
|
|
152
|
-
require 'rubygems'
|
153
146
|
require 'heist'
|
154
147
|
scheme = Heist::Runtime.new(options)
|
155
148
|
|
156
|
-
<tt>options</tt> is an optional argument and is a hash that specifies
|
157
|
-
|
158
|
-
|
149
|
+
<tt>options</tt> is an optional argument and is a hash that specifies the
|
150
|
+
behaviour of optional parts of the runtime. For example, to enable lazy
|
151
|
+
evaluation:
|
159
152
|
|
160
153
|
scheme = Heist::Runtime.new(:lazy => true)
|
161
154
|
|
@@ -163,14 +156,13 @@ The full list of options is:
|
|
163
156
|
|
164
157
|
* <tt>:continuations</tt> - sets whether continuations and <tt>(call/cc)</tt>
|
165
158
|
are enabled. Default is <tt>false</tt>.
|
166
|
-
* <tt>:lazy</tt> - sets whether evaluation is lazy. By default this option
|
167
|
-
|
159
|
+
* <tt>:lazy</tt> - sets whether evaluation is lazy. By default this option is
|
160
|
+
<tt>false</tt> and evaluation is eager.
|
168
161
|
* <tt>:unhygienic</tt> - set this to <tt>true</tt> to disable macro hygiene.
|
169
162
|
|
170
|
-
Bear in mind that continuations and lazy evaluation are not currently
|
171
|
-
|
172
|
-
|
173
|
-
use of macros.
|
163
|
+
Bear in mind that continuations and lazy evaluation are not currently compatible;
|
164
|
+
enabling continuations forces eager evaluation. Also note that lazy evaluation
|
165
|
+
has a slightly unpredictable effect on the use of macros.
|
174
166
|
|
175
167
|
To run a Scheme file using the runtime, just call:
|
176
168
|
|
@@ -179,26 +171,25 @@ To run a Scheme file using the runtime, just call:
|
|
179
171
|
|
180
172
|
=== Create Scheme functions using Ruby
|
181
173
|
|
182
|
-
Every runtime gets its own copy of all the built-in functions. You can add
|
183
|
-
|
184
|
-
|
185
|
-
method:
|
174
|
+
Every runtime gets its own copy of all the built-in functions. You can add your
|
175
|
+
own functions written in Ruby and Heist will make them available as Scheme
|
176
|
+
procedures. For example, for running tests I do this in my +setup+ method:
|
186
177
|
|
187
|
-
|
188
|
-
|
189
|
-
|
178
|
+
@runtime = Heist::Runtime.new
|
179
|
+
@runtime.define 'assert-equal' do |expected, actual|
|
180
|
+
actual.should == expected
|
190
181
|
end
|
191
182
|
|
192
|
-
This lets me write, for example, <tt>(assert-equal 7 (+ 3 4))</tt> in my
|
193
|
-
|
194
|
-
|
183
|
+
This lets me write, for example, <tt>(assert-equal 7 (+ 3 4))</tt> in my tests.
|
184
|
+
You can place arbitrary Ruby code in your functions, so this is an easy way to
|
185
|
+
expose Ruby functionality to the Scheme environment.
|
195
186
|
|
196
187
|
|
197
188
|
=== Run Ruby data as Scheme code
|
198
189
|
|
199
|
-
Heist can interpret Scheme code provided as Ruby data, allowing you
|
200
|
-
|
201
|
-
|
190
|
+
Heist can interpret Scheme code provided as Ruby data, allowing you to write and
|
191
|
+
manipulate Lisp-style expressions inline with Ruby code. For example, using our
|
192
|
+
<tt>Heist::Runtime</tt> instance from above:
|
202
193
|
|
203
194
|
scheme.exec [:define, [:square, :x], [:*, :x, :x]]
|
204
195
|
|
@@ -206,81 +197,76 @@ For example, using our <tt>Heist::Runtime</tt> instance from above:
|
|
206
197
|
#=> 81
|
207
198
|
|
208
199
|
Arrays map directly to Scheme lists, symbols map to identifiers, strings,
|
209
|
-
numbers and booleans are treated as literals, and any other data is
|
210
|
-
|
211
|
-
|
200
|
+
numbers and booleans are treated as literals, and any other data is interpreted
|
201
|
+
verbatim. So, you can use any piece of Ruby data in these expressions as long as
|
202
|
+
the functions you're calling can operate on it.
|
212
203
|
|
213
204
|
Due to syntactic limitations, some Scheme constructs cannot be used in this
|
214
|
-
interface. Quoting syntax is out, so the expression <tt>'(1 2 3)</tt> would
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
205
|
+
interface. Quoting syntax is out, so the expression <tt>'(1 2 3)</tt> would need
|
206
|
+
to be written <tt>[:quote, [1, 2, 3]]</tt>. Dotted pairs and improper lists are
|
207
|
+
also not available, though you can work around this to some extent using
|
208
|
+
<tt>:cons</tt>. Vectors should be written as <tt>[:vector, 1, 2, 3]</tt> for
|
209
|
+
example. Characters can be generated using the <tt>char</tt> procedure with a
|
210
|
+
unit-length string, for example <tt>[:char, "Z"]</tt> produces the character
|
211
|
+
<tt>#\\Z</tt>.
|
221
212
|
|
222
213
|
|
223
214
|
== Notes
|
224
215
|
|
225
|
-
This is alpha-quality software. While every attempt has been made to run
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
216
|
+
This is alpha-quality software. While every attempt has been made to run valid
|
217
|
+
Scheme code, error handling is at present very weak. Anything explicitly
|
218
|
+
documented in this file can be assumed to work according to the Scheme standard,
|
219
|
+
or according to the information presented here, and can be assumed to be
|
220
|
+
reasonably stable.
|
230
221
|
|
231
222
|
=== Ruby-based syntax
|
232
223
|
|
233
|
-
I have not documented how to write your own syntax using Ruby because
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
224
|
+
I have not documented how to write your own syntax using Ruby because it
|
225
|
+
requires far too much knowledge of Heist's plumbing at present (I suspect this
|
226
|
+
may be unavoidable). Besides, we have macros so if you want new syntax we've got
|
227
|
+
you covered. In fact, writing syntax using macros makes sure that new syntactic
|
228
|
+
forms support continuations correctly, and Heist itself eschews Ruby-based
|
229
|
+
syntax where possible.
|
239
230
|
|
240
231
|
=== Valid symbols
|
241
232
|
|
242
|
-
Heist is extremely liberal as regards symbols. Any sequence of
|
243
|
-
|
244
|
-
|
245
|
-
is considered a valid symbol.
|
233
|
+
Heist is extremely liberal as regards symbols. Any sequence of characters that
|
234
|
+
does not contain any spaces or parentheses and that is not a boolean literal, a
|
235
|
+
number, a character literal or a string is considered a valid symbol.
|
246
236
|
|
247
237
|
=== Vectors and quoting
|
248
238
|
|
249
239
|
Vectors do not need to be quoted, for example the expression <tt>#(1 2 3)</tt>
|
250
|
-
evaluates to itself. If a vector is quoted, it is made immutable and
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
each unquoted vector is copied on evaluation.
|
240
|
+
evaluates to itself. If a vector is quoted, it is made immutable and a quoted
|
241
|
+
vector expression returns the same in-memory object every time it is evaluated.
|
242
|
+
In contrast, an unquoted vector returns a new vector object every time it is
|
243
|
+
evaluated. Unquoted vectors are not frozen as this makes macro transformations
|
244
|
+
hard to implement, and because we cannot let the <tt>vector-set!</tt> procedure
|
245
|
+
modify the parse tree each unquoted vector is copied on evaluation.
|
257
246
|
|
258
247
|
=== Macros
|
259
248
|
|
260
|
-
Macros are slightly more liberal than R5RS, in that this is a valid
|
261
|
-
macro:
|
249
|
+
Macros are slightly more liberal than R5RS, in that this is a valid macro:
|
262
250
|
|
263
251
|
(define-syntax my-let (syntax-rules ()
|
264
252
|
[(my-let (name value) ... body ...)
|
265
253
|
(let [(name value) ...]
|
266
254
|
body ...)]))
|
267
255
|
|
268
|
-
You are allowed to use ellipses in infix positions, as long as the
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
<tt>3</tt> using this macro:
|
256
|
+
You are allowed to use ellipses in infix positions, as long as the pattern that
|
257
|
+
follows the ellipsis matches input that the preceeding pattern would fail to
|
258
|
+
match. This is, the ellipsis acts as a greedy star operator in regular
|
259
|
+
expressions. In the above, <tt>(name value) ... body ...</tt> matches zero or
|
260
|
+
more two-element lists followed by zero or more expressions of any type. The
|
261
|
+
following expression evaluates to <tt>3</tt> using this macro:
|
275
262
|
|
276
263
|
(my-let (x 2) (y 3) y)
|
277
264
|
|
278
|
-
Speaking of macros, there is no distinct macro expansion stage in
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
aliased and used anonymously:
|
265
|
+
Speaking of macros, there is no distinct macro expansion stage in Heist. Macros
|
266
|
+
are expanded as they are encountered at runtime, and their expansions are
|
267
|
+
inlined into the AST to improve performance: the same macro use is never
|
268
|
+
expanded more than once. Macros (and native syntactic forms) are first-class, so
|
269
|
+
they can be easily aliased and used anonymously:
|
284
270
|
|
285
271
|
(define when if)
|
286
272
|
|
@@ -288,18 +274,16 @@ aliased and used anonymously:
|
|
288
274
|
(+ 3 4)) ; => 7
|
289
275
|
|
290
276
|
It's not clear whether it would be useful to choose syntactic forms
|
291
|
-
conditionally, certainly this will not work with macros as the
|
292
|
-
|
293
|
-
expansion generated.
|
277
|
+
conditionally, certainly this will not work with macros as the inlining process
|
278
|
+
will overwrite conditional code using the first expansion generated.
|
294
279
|
|
295
280
|
=== Laziness
|
296
281
|
|
297
|
-
Lazy evaluation mode is mainly useful for doing lambda calculus
|
298
|
-
|
299
|
-
|
300
|
-
the
|
301
|
-
|
302
|
-
<tt>Y</tt>:
|
282
|
+
Lazy evaluation mode is mainly useful for doing lambda calculus without being
|
283
|
+
concerned about the difference between normal and applicative order, which for
|
284
|
+
example affects the expression for the Y combinator. It displays some
|
285
|
+
interesting properties, such as the fact that this is a perfectly reasonable
|
286
|
+
definition for <tt>Y</tt>:
|
303
287
|
|
304
288
|
(define (Y f)
|
305
289
|
(f (Y f)))
|
@@ -320,23 +304,22 @@ as the fact that this is a perfectly reasonable definition for
|
|
320
304
|
|
321
305
|
(The MIT License)
|
322
306
|
|
323
|
-
Copyright (c) 2009 James Coglan
|
324
|
-
|
325
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
IN
|
340
|
-
|
341
|
-
|
342
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
307
|
+
Copyright (c) 2009-2011 James Coglan
|
308
|
+
|
309
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
310
|
+
this software and associated documentation files (the 'Software'), to deal in
|
311
|
+
the Software without restriction, including without limitation the rights to use,
|
312
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
313
|
+
Software, and to permit persons to whom the Software is furnished to do so,
|
314
|
+
subject to the following conditions:
|
315
|
+
|
316
|
+
The above copyright notice and this permission notice shall be included in all
|
317
|
+
copies or substantial portions of the Software.
|
318
|
+
|
319
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
320
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
321
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
322
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
323
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
324
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
325
|
+
|
data/bin/heist
CHANGED
@@ -1,16 +1,41 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require
|
2
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
3
|
+
require dir + '/../lib/heist'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
require 'oyster'
|
6
|
+
spec = Oyster.spec do
|
7
|
+
name "heist -- Ruby-powered Scheme interpreter, v. #{Heist::VERSION}"
|
8
|
+
author 'James Coglan <jcoglan@googlemail.com>'
|
9
|
+
|
10
|
+
synopsis <<-EOS
|
11
|
+
heist -i [OPTIONS]
|
12
|
+
heist FILE_NAME [OPTIONS]
|
13
|
+
EOS
|
14
|
+
|
15
|
+
flag :interactive, :desc =>
|
16
|
+
'Start an interactive Scheme session'
|
17
|
+
|
18
|
+
flag :lazy, :default => false, :desc =>
|
19
|
+
'Use lazy evaluation order'
|
20
|
+
|
21
|
+
flag :continuations, :default => false, :desc =>
|
22
|
+
'Enable first-class continuations and (call/cc)'
|
23
|
+
|
24
|
+
flag :unhygienic, :default => false, :desc =>
|
25
|
+
'Use Common Lisp-style unhygienic macros'
|
8
26
|
end
|
9
27
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
28
|
+
|
29
|
+
begin
|
30
|
+
options = spec.parse
|
31
|
+
|
32
|
+
if options[:interactive] or options[:unclaimed].empty?
|
33
|
+
Heist::REPL.new(options).run
|
34
|
+
else
|
35
|
+
env = Heist::Runtime.new(options)
|
36
|
+
env.run(File.expand_path(options[:unclaimed].first))
|
37
|
+
end
|
38
|
+
|
39
|
+
rescue Oyster::HelpRendered
|
15
40
|
end
|
16
41
|
|