heist 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History.txt +12 -0
  2. data/{README.txt → README.rdoc} +131 -148
  3. data/bin/heist +35 -10
  4. data/lib/heist.rb +3 -3
  5. data/lib/heist/builtin/compiled_library.rb +1 -0
  6. data/lib/heist/builtin/lib/character.scm +74 -0
  7. data/lib/heist/builtin/lib/list.scm +149 -0
  8. data/lib/heist/builtin/lib/logic.scm +17 -0
  9. data/lib/heist/builtin/lib/numeric.scm +184 -0
  10. data/lib/heist/builtin/lib/string.scm +117 -0
  11. data/lib/heist/builtin/lib/util.scm +18 -0
  12. data/lib/heist/builtin/lib/vector.scm +27 -0
  13. data/lib/{builtin → heist/builtin}/primitives.rb +0 -0
  14. data/lib/{builtin → heist/builtin}/syntax.scm +52 -52
  15. data/lib/{parser → heist/parser}/nodes.rb +0 -0
  16. data/lib/{parser → heist/parser}/ruby.rb +0 -0
  17. data/lib/{parser → heist/parser}/scheme.rb +0 -0
  18. data/lib/{parser → heist/parser}/scheme.tt +0 -0
  19. data/lib/{repl.rb → heist/repl.rb} +0 -0
  20. data/lib/{runtime → heist/runtime}/binding.rb +5 -0
  21. data/lib/{runtime → heist/runtime}/callable/continuation.rb +6 -1
  22. data/lib/{runtime → heist/runtime}/callable/function.rb +0 -0
  23. data/lib/{runtime → heist/runtime}/callable/macro.rb +1 -1
  24. data/lib/{runtime → heist/runtime}/callable/macro/expansion.rb +0 -0
  25. data/lib/{runtime → heist/runtime}/callable/macro/matches.rb +0 -0
  26. data/lib/{runtime → heist/runtime}/callable/macro/tree.rb +0 -0
  27. data/lib/{runtime → heist/runtime}/callable/syntax.rb +0 -0
  28. data/lib/{runtime → heist/runtime}/data/character.rb +0 -0
  29. data/lib/{runtime → heist/runtime}/data/cons.rb +0 -0
  30. data/lib/{runtime → heist/runtime}/data/expression.rb +0 -0
  31. data/lib/{runtime → heist/runtime}/data/identifier.rb +0 -0
  32. data/lib/heist/runtime/data/value.rb +14 -0
  33. data/lib/{runtime → heist/runtime}/data/vector.rb +0 -0
  34. data/lib/{runtime → heist/runtime}/frame.rb +3 -0
  35. data/lib/{runtime → heist/runtime}/runtime.rb +2 -2
  36. data/lib/{runtime → heist/runtime}/scope.rb +0 -0
  37. data/lib/{runtime → heist/runtime}/stack.rb +0 -0
  38. data/lib/{runtime → heist/runtime}/stackless.rb +0 -0
  39. data/lib/{stdlib → heist/stdlib}/benchmark.scm +0 -0
  40. data/lib/{stdlib → heist/stdlib}/birdhouse.scm +0 -0
  41. data/lib/{trie.rb → heist/trie.rb} +0 -0
  42. data/spec/heist_spec.rb +88 -0
  43. data/{test → spec}/helpers/lib.scm +0 -0
  44. data/{test → spec}/helpers/macro-helpers.scm +0 -0
  45. data/{test → spec}/helpers/vars.scm +0 -0
  46. data/{test → spec}/plt-macros.txt +0 -0
  47. data/{test → spec}/scheme_tests/arithmetic.scm +0 -0
  48. data/{test → spec}/scheme_tests/benchmarks.scm +0 -0
  49. data/{test → spec}/scheme_tests/booleans.scm +0 -0
  50. data/{test → spec}/scheme_tests/closures.scm +0 -0
  51. data/{test → spec}/scheme_tests/conditionals.scm +0 -0
  52. data/{test → spec}/scheme_tests/continuations.scm +14 -1
  53. data/{test → spec}/scheme_tests/define_functions.scm +0 -0
  54. data/{test → spec}/scheme_tests/define_values.scm +0 -0
  55. data/{test → spec}/scheme_tests/delay.scm +0 -0
  56. data/{test → spec}/scheme_tests/equivalence.scm +0 -0
  57. data/{test → spec}/scheme_tests/file_loading.scm +0 -0
  58. data/{test → spec}/scheme_tests/functional.scm +3 -0
  59. data/{test → spec}/scheme_tests/hygienic.scm +0 -0
  60. data/{test → spec}/scheme_tests/let.scm +0 -0
  61. data/{test → spec}/scheme_tests/lists.scm +0 -0
  62. data/{test → spec}/scheme_tests/macros.scm +0 -0
  63. data/{test → spec}/scheme_tests/numbers.scm +0 -0
  64. data/{test → spec}/scheme_tests/protection.scm +0 -0
  65. data/spec/scheme_tests/quoting.scm +14 -0
  66. data/{test → spec}/scheme_tests/strings.scm +0 -0
  67. data/{test → spec}/scheme_tests/unhygienic.scm +0 -0
  68. data/{test → spec}/scheme_tests/vectors.scm +0 -0
  69. data/spec/spec_helper.rb +4 -0
  70. metadata +98 -113
  71. data/Manifest.txt +0 -64
  72. data/Rakefile +0 -43
  73. data/lib/bin_spec.rb +0 -25
  74. data/lib/builtin/library.rb +0 -1
  75. data/lib/builtin/library.scm +0 -605
  76. data/test/test_heist.rb +0 -148
@@ -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
@@ -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
- for running Scheme code directly, and also allows the interpreter to be
7
- easily embedded in, and extended using, Ruby applications. It nominally
8
- targets R5RS, though is likely to be more liberal than other implementations.
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
- in use today. Lisp was the first language to implement conditionals, first
15
- class functions (lambdas), closures and recursion. Some Lisp features, such
16
- as closures and macros, have yet to penetrate mainstream languages and it
17
- has been observed that mainstream languages are slowly converging on the
18
- feature set of Lisp.
19
-
20
- Scheme in particular is important for its influence on current languages,
21
- in particular JavaScript and Ruby (JavaScript is remarkably similar to
22
- Scheme if you ignore the syntactic differences). It is also used in the
23
- much-praised book "Structure and Interpretation of Computer Programs",
24
- wherein it is used to explore some of the theory surrounding interpreters.
25
-
26
- It is a functional language, in that it supports first-class functions
27
- and many constructs that would be syntax in other languages resemble
28
- function calls in Scheme. However it is not purely functional as it
29
- allows side effects, and is more procedural in nature than, say, a
30
- declarative language such as Haskell. Like other Lisps, its lack of
31
- predefined syntax and its support for macros (functions that rewrite
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
- allows the behaviour of some of these features to be configured on a
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
- your display with prompts and other such cruft. It indents your
113
- code automatically, supports tab completion, and output is printed
114
- as comments so it's simple to copy code out of a REPL session into
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
- evaluated as and when the called function requires their values.
119
- * <b>Unhygienic macros</b>. Scheme mandates hygienic macros that
120
- preserve lexical scoping, but other Lisps use a simpler system that
121
- does not impose this restriction. Heist allows hygiene to be
122
- disabled, its author not having the requisite experience to decide
123
- which system he prefers yet.
124
- * <b>Optional continuations</b>. Supporting continuations incurs a
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
- sudo gem install hoe
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 an REPL session:
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
- run <tt>heist -h</tt> for more information.
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
- the runtime:
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
- the behaviour of optional parts of the runtime. For example, to enable
158
- lazy evaluation:
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
- is <tt>false</tt> and evaluation is eager.
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
- compatible; enabling continuations forces eager evaluation. Also
172
- note that lazy evaluation has a slightly unpredictable effect on the
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
- your own functions written in Ruby and Heist will make them available as
184
- Scheme procedures. For example, for running tests I do this in my +setup+
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
- @@env = Heist::Runtime.new
188
- @@env.define('assert-equal') do |expected, actual|
189
- assert_equal(expected, actual)
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
- tests. You can place arbitrary Ruby code in your functions, so this is
194
- an easy way to expose Ruby functionality to the Scheme environment.
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
- to write and manipulate Lisp-style expressions inline with Ruby code.
201
- For example, using our <tt>Heist::Runtime</tt> instance from above:
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
- interpreted verbatim. So, you can use any piece of Ruby data in these
211
- expressions as long as the functions you're calling can operate on it.
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
- need to be written <tt>[:quote, [1, 2, 3]]</tt>. Dotted pairs and improper
216
- lists are also not available, though you can work around this to some extent
217
- using <tt>:cons</tt>. Vectors should be written as <tt>[:vector, 1, 2, 3]</tt>
218
- for example. Characters can be generated using the <tt>char</tt> procedure
219
- with a unit-length string, for example <tt>[:char, "Z"]</tt> produces the
220
- character <tt>#\\Z</tt>.
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
- valid Scheme code, error handling is at present very weak. Anything
227
- explicitly documented in this file can be assumed to work according to
228
- the Scheme standard, or according to the information presented here,
229
- and can be assumed to be reasonably stable.
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
- it requires far too much knowledge of Heist's plumbing at present (I
235
- suspect this may be unavoidable). Besides, we have macros so if you
236
- want new syntax we've got you covered. In fact, writing syntax using
237
- macros makes sure that new syntactic forms support continuations
238
- correctly, and Heist itself eschews Ruby-based syntax where possible.
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
- characters that does not contain any spaces or parentheses and that
244
- is not a boolean literal, a number, a character literal or a string
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
- a quoted vector expression returns the same in-memory object every time
252
- it is evaluated. In contrast, an unquoted vector returns a new vector
253
- object every time it is evaluated. Unquoted vectors are not frozen
254
- as this makes macro transformations hard to implement, and because we
255
- cannot let the <tt>vector-set!</tt> procedure modify the parse tree
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
- pattern that follows the ellipsis matches input that the preceeding
270
- pattern would fail to match. This is, the ellipsis acts as a greedy
271
- star operator in regular expressions. In the above, <tt>(name value) ... body ...</tt>
272
- matches zero or more two-element lists followed by zero or more
273
- expressions of any type. The following expression evaluates to
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
- Heist. Macros are expanded as they are encountered at runtime, and
280
- their expansions are inlined into the AST to improve performance:
281
- the same macro use is never expanded more than once. Macros (and
282
- native syntactic forms) are first-class, so they can be easily
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
- inlining process will overwrite conditional code using the first
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
- without being concerned about the difference between normal and
299
- applicative order, which for example affects the expression for
300
- the Y combinator. It displays some interesting properties, such
301
- as the fact that this is a perfectly reasonable definition for
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
- a copy of this software and associated documentation files (the
327
- 'Software'), to deal in the Software without restriction, including
328
- without limitation the rights to use, copy, modify, merge, publish,
329
- distribute, sublicense, and/or sell copies of the Software, and to
330
- permit persons to whom the Software is furnished to do so, subject to
331
- the following conditions:
332
-
333
- The above copyright notice and this permission notice shall be
334
- included in all copies or substantial portions of the Software.
335
-
336
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
337
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
338
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
339
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
340
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
341
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
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
- require File.dirname(__FILE__) + '/../lib/heist'
3
- require File.dirname(__FILE__) + '/../lib/bin_spec'
2
+ dir = File.expand_path(File.dirname(__FILE__))
3
+ require dir + '/../lib/heist'
4
4
 
5
- begin
6
- options = Heist::BIN_SPEC.parse
7
- rescue Oyster::HelpRendered; exit
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
- if options[:interactive] or options[:unclaimed].empty?
11
- Heist::REPL.new(options).run
12
- else
13
- env = Heist::Runtime.new(options)
14
- env.run(File.expand_path(options[:unclaimed].first))
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