heist 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|