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.
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