heist 0.1.0 → 0.2.0
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 +17 -0
- data/Manifest.txt +23 -19
- data/README.txt +84 -52
- data/lib/builtin/library.scm +208 -10
- data/lib/builtin/primitives.rb +154 -92
- data/lib/builtin/syntax.scm +22 -5
- data/lib/heist.rb +49 -17
- data/lib/parser/nodes.rb +47 -24
- data/lib/parser/ruby.rb +29 -0
- data/lib/parser/scheme.rb +455 -143
- data/lib/parser/scheme.tt +23 -5
- data/lib/repl.rb +19 -16
- data/lib/runtime/binding.rb +24 -2
- data/lib/runtime/callable/continuation.rb +23 -2
- data/lib/runtime/callable/function.rb +122 -21
- data/lib/runtime/callable/macro.rb +169 -123
- data/lib/runtime/callable/macro/expansion.rb +137 -2
- data/lib/runtime/callable/macro/matches.rb +125 -41
- data/lib/runtime/callable/macro/tree.rb +141 -0
- data/lib/runtime/callable/syntax.rb +44 -0
- data/lib/runtime/data/cons.rb +234 -0
- data/lib/runtime/data/expression.rb +15 -6
- data/lib/runtime/data/identifier.rb +19 -2
- data/lib/runtime/frame.rb +102 -35
- data/lib/runtime/runtime.rb +44 -19
- data/lib/runtime/scope.rb +145 -30
- data/lib/runtime/stack.rb +103 -1
- data/lib/runtime/stackless.rb +48 -6
- data/test/arithmetic.scm +11 -2
- data/test/continuations.scm +16 -2
- data/test/equivalence.scm +34 -0
- data/test/functional.scm +4 -0
- data/test/lists.scm +78 -0
- data/test/macro-helpers.scm +1 -0
- data/test/macros.scm +111 -24
- data/test/numbers.scm +30 -8
- data/test/test_heist.rb +67 -12
- metadata +25 -21
- data/lib/builtin/syntax.rb +0 -166
- data/lib/runtime/callable/macro/splice.rb +0 -56
- data/lib/runtime/data/list.rb +0 -36
data/lib/parser/nodes.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
module Heist
|
2
|
+
# The +Scheme+ module hosts various classes used by the +SchemeParser+ class,
|
3
|
+
# which is generated from a parsing expression grammar using +Treetop+. (See
|
4
|
+
# <tt>lib/parser/scheme.tt</tt>.) The classes map syntax structures generated
|
5
|
+
# by +Treetop+ to Heist runtime objects for execution. All the classes except
|
6
|
+
# +Program+ are evaluated without a runtime environment; evaluating them
|
7
|
+
# simply casts to non-Treetop objects in the Heist library, or to raw Ruby
|
8
|
+
# objects. Evaluating a +Program+ requires a +Runtime+ in which to do so.
|
2
9
|
module Scheme
|
3
10
|
|
11
|
+
# Any list-generating shorthands present in the grammar should be listed here.
|
12
|
+
# In Scheme, this list includes the various quoting symbols that can be used
|
13
|
+
# as shorthands for calling quoting functions.
|
4
14
|
SHORTHANDS = {
|
5
15
|
"'" => :quote,
|
6
16
|
"`" => :quasiquote,
|
@@ -8,50 +18,63 @@ module Heist
|
|
8
18
|
",@" => :'unquote-splicing'
|
9
19
|
}
|
10
20
|
|
21
|
+
# +Program+ is the root of the parse tree; parsing any string of Scheme code
|
22
|
+
# produces one of these.
|
11
23
|
class Program < Treetop::Runtime::SyntaxNode
|
24
|
+
# Evaluates all the expressions in the +Program+ in order, returning the
|
25
|
+
# result of the last expression.
|
12
26
|
def eval(scope)
|
13
27
|
convert!
|
14
28
|
@data.map { |part| Heist.evaluate(part, scope) }.last
|
15
29
|
end
|
16
30
|
|
31
|
+
# Converts all the +Treetop+ objects in the +Program+ to Heist objects
|
32
|
+
# and raw Ruby data ready for interpretation using a +Runtime+.
|
17
33
|
def convert!
|
18
34
|
return if @data
|
19
|
-
@data =
|
20
|
-
elements.each_with_index { |cell, i| self[i] = cell.eval }
|
21
|
-
end
|
22
|
-
|
23
|
-
def [](index)
|
24
|
-
@data[index]
|
25
|
-
end
|
26
|
-
|
27
|
-
def []=(index, value)
|
28
|
-
value.exists_at!(self, index) if Runtime::Expression === value
|
29
|
-
@data[index] = value
|
35
|
+
@data = Runtime::Cons.construct(elements, true) { |c| c.eval }
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
39
|
+
# A +List+ has an array of +cells+, and optionally a +tail+ if it's an
|
40
|
+
# improper list or a dotted pair.
|
33
41
|
module List
|
42
|
+
# Evaluating a +List+ produces a Heist +Cons+ object.
|
34
43
|
def eval
|
35
|
-
list = Runtime::
|
36
|
-
|
44
|
+
list = Runtime::Cons.construct(cells, true) { |c| c.eval }
|
45
|
+
list.tail.cdr = tail.cell.eval if tail.respond_to?(:dot)
|
37
46
|
list
|
38
47
|
end
|
39
48
|
|
40
49
|
def cells
|
41
|
-
@cells ||= elements[1].elements
|
50
|
+
@cells ||= elements[1].elements[0].elements
|
51
|
+
end
|
52
|
+
|
53
|
+
def tail
|
54
|
+
@tail ||= elements[1].elements[1]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# <tt>QuotedCell</tt> are generated using the quoting shorthands.
|
59
|
+
class QuotedCell < Treetop::Runtime::SyntaxNode
|
60
|
+
# Evaluating a +QuotedCell+ produces a +Cons+ that expresses a function
|
61
|
+
# call to the appropriate quoting function, with the cell as the argument.
|
62
|
+
def eval
|
63
|
+
quote = elements[1].text_value
|
64
|
+
cell = elements[2].eval
|
65
|
+
Runtime::Cons.construct([Runtime::Identifier.new(SHORTHANDS[quote]), cell])
|
42
66
|
end
|
43
67
|
end
|
44
68
|
|
69
|
+
# <tt>Cells</tt> are any piece of Scheme data: numbers, booleans, strings,
|
70
|
+
# lists. Any building block of Scheme code goes in a +Cell+.
|
45
71
|
class Cell < Treetop::Runtime::SyntaxNode
|
46
72
|
def eval
|
47
|
-
|
48
|
-
string = elements[1].text_value
|
49
|
-
SHORTHANDS.has_key?(string) ?
|
50
|
-
Runtime::List.new([Runtime::Identifier.new(SHORTHANDS[string]), result]) :
|
51
|
-
result
|
73
|
+
elements[1].eval
|
52
74
|
end
|
53
75
|
end
|
54
76
|
|
77
|
+
# A +Datum+ is any piece of atomic literal data.
|
55
78
|
class Datum < Treetop::Runtime::SyntaxNode
|
56
79
|
def eval
|
57
80
|
elements[0].eval
|
@@ -66,25 +89,25 @@ module Heist
|
|
66
89
|
|
67
90
|
class Complex < Treetop::Runtime::SyntaxNode
|
68
91
|
def eval
|
69
|
-
|
92
|
+
@value ||= Heist.complex(real.eval, imaginary.eval)
|
70
93
|
end
|
71
94
|
end
|
72
95
|
|
73
96
|
class Real < Treetop::Runtime::SyntaxNode
|
74
97
|
def eval
|
75
|
-
@value ||=
|
98
|
+
@value ||= text_value.to_f
|
76
99
|
end
|
77
100
|
end
|
78
101
|
|
79
102
|
class Rational < Treetop::Runtime::SyntaxNode
|
80
103
|
def eval
|
81
|
-
@value ||= numerator.eval
|
104
|
+
@value ||= Heist.rational(numerator.eval, denominator.eval)
|
82
105
|
end
|
83
106
|
end
|
84
107
|
|
85
108
|
class Integer < Treetop::Runtime::SyntaxNode
|
86
109
|
def eval
|
87
|
-
@value ||=
|
110
|
+
@value ||= text_value.to_i
|
88
111
|
end
|
89
112
|
end
|
90
113
|
|
@@ -94,7 +117,7 @@ module Heist
|
|
94
117
|
end
|
95
118
|
end
|
96
119
|
|
97
|
-
|
120
|
+
module Identifier
|
98
121
|
def eval
|
99
122
|
Runtime::Identifier.new(text_value)
|
100
123
|
end
|
data/lib/parser/ruby.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Heist
|
2
|
+
# +RubyParser+ parses non-string code given as Ruby data such as arrays. It
|
3
|
+
# allows Lisp-style code to be expressed inline with Ruby, for example:
|
4
|
+
#
|
5
|
+
# scheme = Heist::Runtime.new
|
6
|
+
# scheme.exec [:define, [:square, :x], [:*, :x, :x]]
|
7
|
+
# scheme.exec [:square, 9]
|
8
|
+
# #=> 81
|
9
|
+
#
|
10
|
+
# The above API uses +RubyParser+ behind the scenes to turn Ruby data into
|
11
|
+
# Heist runtime objects such as +Cons+ based lists before execution.
|
12
|
+
#
|
13
|
+
class RubyParser
|
14
|
+
|
15
|
+
# Parses a single piece of Ruby data in
|
16
|
+
def parse(source)
|
17
|
+
case source
|
18
|
+
when Array then
|
19
|
+
Runtime::Cons.construct(source) { |cell| parse(cell) }
|
20
|
+
when Symbol then
|
21
|
+
Runtime::Identifier.new(source)
|
22
|
+
else
|
23
|
+
source
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/parser/scheme.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Heist
|
2
|
-
module Scheme
|
2
|
+
module Scheme #:nodoc:
|
3
3
|
include Treetop::Runtime
|
4
4
|
|
5
5
|
def root
|
@@ -30,17 +30,27 @@ module Heist
|
|
30
30
|
return r0
|
31
31
|
end
|
32
32
|
|
33
|
-
module Cell0
|
33
|
+
module Cell0 #:nodoc:
|
34
34
|
def ignore
|
35
35
|
elements[0]
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
38
|
+
def quote
|
39
|
+
elements[1]
|
40
|
+
end
|
41
|
+
|
42
|
+
def cell
|
39
43
|
elements[2]
|
40
44
|
end
|
45
|
+
end
|
41
46
|
|
47
|
+
module Cell1 #:nodoc:
|
42
48
|
def ignore
|
43
|
-
elements[
|
49
|
+
elements[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def ignore
|
53
|
+
elements[2]
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
@@ -52,48 +62,64 @@ module Heist
|
|
52
62
|
return cached
|
53
63
|
end
|
54
64
|
|
55
|
-
i0
|
56
|
-
|
57
|
-
|
58
|
-
|
65
|
+
i0 = index
|
66
|
+
i1, s1 = index, []
|
67
|
+
r2 = _nt_ignore
|
68
|
+
s1 << r2
|
69
|
+
if r2
|
59
70
|
r3 = _nt_quote
|
71
|
+
s1 << r3
|
60
72
|
if r3
|
61
|
-
|
62
|
-
|
63
|
-
r2 = SyntaxNode.new(input, index...index)
|
73
|
+
r4 = _nt_cell
|
74
|
+
s1 << r4
|
64
75
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
end
|
77
|
+
if s1.last
|
78
|
+
r1 = (QuotedCell).new(input, i1...index, s1)
|
79
|
+
r1.extend(Cell0)
|
80
|
+
else
|
81
|
+
self.index = i1
|
82
|
+
r1 = nil
|
83
|
+
end
|
84
|
+
if r1
|
85
|
+
r0 = r1
|
86
|
+
else
|
87
|
+
i5, s5 = index, []
|
88
|
+
r6 = _nt_ignore
|
89
|
+
s5 << r6
|
90
|
+
if r6
|
91
|
+
i7 = index
|
92
|
+
r8 = _nt_list
|
93
|
+
if r8
|
94
|
+
r7 = r8
|
95
|
+
else
|
96
|
+
r9 = _nt_atom
|
97
|
+
if r9
|
98
|
+
r7 = r9
|
74
99
|
else
|
75
|
-
|
76
|
-
|
77
|
-
r5 = r7
|
78
|
-
else
|
79
|
-
self.index = i5
|
80
|
-
r5 = nil
|
81
|
-
end
|
82
|
-
end
|
83
|
-
s0 << r5
|
84
|
-
if r5
|
85
|
-
r8 = _nt_ignore
|
86
|
-
s0 << r8
|
100
|
+
self.index = i7
|
101
|
+
r7 = nil
|
87
102
|
end
|
88
103
|
end
|
104
|
+
s5 << r7
|
105
|
+
if r7
|
106
|
+
r10 = _nt_ignore
|
107
|
+
s5 << r10
|
108
|
+
end
|
109
|
+
end
|
110
|
+
if s5.last
|
111
|
+
r5 = (Cell).new(input, i5...index, s5)
|
112
|
+
r5.extend(Cell1)
|
113
|
+
else
|
114
|
+
self.index = i5
|
115
|
+
r5 = nil
|
116
|
+
end
|
117
|
+
if r5
|
118
|
+
r0 = r5
|
119
|
+
else
|
120
|
+
self.index = i0
|
121
|
+
r0 = nil
|
89
122
|
end
|
90
|
-
end
|
91
|
-
if s0.last
|
92
|
-
r0 = (Cell).new(input, i0...index, s0)
|
93
|
-
r0.extend(Cell0)
|
94
|
-
else
|
95
|
-
self.index = i0
|
96
|
-
r0 = nil
|
97
123
|
end
|
98
124
|
|
99
125
|
node_cache[:cell][start_index] = r0
|
@@ -162,10 +188,39 @@ module Heist
|
|
162
188
|
return r0
|
163
189
|
end
|
164
190
|
|
165
|
-
|
191
|
+
def _nt_dot
|
192
|
+
start_index = index
|
193
|
+
if node_cache[:dot].has_key?(index)
|
194
|
+
cached = node_cache[:dot][index]
|
195
|
+
@index = cached.interval.end if cached
|
196
|
+
return cached
|
197
|
+
end
|
198
|
+
|
199
|
+
if input.index(".", index) == index
|
200
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
201
|
+
@index += 1
|
202
|
+
else
|
203
|
+
terminal_parse_failure(".")
|
204
|
+
r0 = nil
|
205
|
+
end
|
206
|
+
|
207
|
+
node_cache[:dot][start_index] = r0
|
208
|
+
|
209
|
+
return r0
|
166
210
|
end
|
167
211
|
|
168
|
-
module
|
212
|
+
module List0 #:nodoc:
|
213
|
+
def cells
|
214
|
+
elements[1]
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
module List1 #:nodoc:
|
220
|
+
def cells
|
221
|
+
elements[1]
|
222
|
+
end
|
223
|
+
|
169
224
|
end
|
170
225
|
|
171
226
|
def _nt_list
|
@@ -187,26 +242,17 @@ module Heist
|
|
187
242
|
end
|
188
243
|
s1 << r2
|
189
244
|
if r2
|
190
|
-
|
191
|
-
loop do
|
192
|
-
r4 = _nt_cell
|
193
|
-
if r4
|
194
|
-
s3 << r4
|
195
|
-
else
|
196
|
-
break
|
197
|
-
end
|
198
|
-
end
|
199
|
-
r3 = SyntaxNode.new(input, i3...index, s3)
|
245
|
+
r3 = _nt_cells
|
200
246
|
s1 << r3
|
201
247
|
if r3
|
202
248
|
if input.index(")", index) == index
|
203
|
-
|
249
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
204
250
|
@index += 1
|
205
251
|
else
|
206
252
|
terminal_parse_failure(")")
|
207
|
-
|
253
|
+
r4 = nil
|
208
254
|
end
|
209
|
-
s1 <<
|
255
|
+
s1 << r4
|
210
256
|
end
|
211
257
|
end
|
212
258
|
if s1.last
|
@@ -220,47 +266,38 @@ module Heist
|
|
220
266
|
r0 = r1
|
221
267
|
r0.extend(List)
|
222
268
|
else
|
223
|
-
|
269
|
+
i5, s5 = index, []
|
224
270
|
if input.index("[", index) == index
|
225
|
-
|
271
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
226
272
|
@index += 1
|
227
273
|
else
|
228
274
|
terminal_parse_failure("[")
|
229
|
-
|
275
|
+
r6 = nil
|
230
276
|
end
|
231
|
-
|
232
|
-
if
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
if r9
|
237
|
-
s8 << r9
|
238
|
-
else
|
239
|
-
break
|
240
|
-
end
|
241
|
-
end
|
242
|
-
r8 = SyntaxNode.new(input, i8...index, s8)
|
243
|
-
s6 << r8
|
244
|
-
if r8
|
277
|
+
s5 << r6
|
278
|
+
if r6
|
279
|
+
r7 = _nt_cells
|
280
|
+
s5 << r7
|
281
|
+
if r7
|
245
282
|
if input.index("]", index) == index
|
246
|
-
|
283
|
+
r8 = (SyntaxNode).new(input, index...(index + 1))
|
247
284
|
@index += 1
|
248
285
|
else
|
249
286
|
terminal_parse_failure("]")
|
250
|
-
|
287
|
+
r8 = nil
|
251
288
|
end
|
252
|
-
|
289
|
+
s5 << r8
|
253
290
|
end
|
254
291
|
end
|
255
|
-
if
|
256
|
-
|
257
|
-
|
292
|
+
if s5.last
|
293
|
+
r5 = (SyntaxNode).new(input, i5...index, s5)
|
294
|
+
r5.extend(List1)
|
258
295
|
else
|
259
|
-
self.index =
|
260
|
-
|
296
|
+
self.index = i5
|
297
|
+
r5 = nil
|
261
298
|
end
|
262
|
-
if
|
263
|
-
r0 =
|
299
|
+
if r5
|
300
|
+
r0 = r5
|
264
301
|
r0.extend(List)
|
265
302
|
else
|
266
303
|
self.index = i0
|
@@ -273,6 +310,122 @@ module Heist
|
|
273
310
|
return r0
|
274
311
|
end
|
275
312
|
|
313
|
+
module Cells0 #:nodoc:
|
314
|
+
def dot
|
315
|
+
elements[0]
|
316
|
+
end
|
317
|
+
|
318
|
+
def space
|
319
|
+
elements[1]
|
320
|
+
end
|
321
|
+
|
322
|
+
def cell
|
323
|
+
elements[2]
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
module Cells1 #:nodoc:
|
328
|
+
end
|
329
|
+
|
330
|
+
module Cells2 #:nodoc:
|
331
|
+
def ignore
|
332
|
+
elements[1]
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def _nt_cells
|
337
|
+
start_index = index
|
338
|
+
if node_cache[:cells].has_key?(index)
|
339
|
+
cached = node_cache[:cells][index]
|
340
|
+
@index = cached.interval.end if cached
|
341
|
+
return cached
|
342
|
+
end
|
343
|
+
|
344
|
+
i0 = index
|
345
|
+
i1, s1 = index, []
|
346
|
+
s2, i2 = [], index
|
347
|
+
loop do
|
348
|
+
r3 = _nt_cell
|
349
|
+
if r3
|
350
|
+
s2 << r3
|
351
|
+
else
|
352
|
+
break
|
353
|
+
end
|
354
|
+
end
|
355
|
+
if s2.empty?
|
356
|
+
self.index = i2
|
357
|
+
r2 = nil
|
358
|
+
else
|
359
|
+
r2 = SyntaxNode.new(input, i2...index, s2)
|
360
|
+
end
|
361
|
+
s1 << r2
|
362
|
+
if r2
|
363
|
+
i4, s4 = index, []
|
364
|
+
r5 = _nt_dot
|
365
|
+
s4 << r5
|
366
|
+
if r5
|
367
|
+
r6 = _nt_space
|
368
|
+
s4 << r6
|
369
|
+
if r6
|
370
|
+
r7 = _nt_cell
|
371
|
+
s4 << r7
|
372
|
+
end
|
373
|
+
end
|
374
|
+
if s4.last
|
375
|
+
r4 = (SyntaxNode).new(input, i4...index, s4)
|
376
|
+
r4.extend(Cells0)
|
377
|
+
else
|
378
|
+
self.index = i4
|
379
|
+
r4 = nil
|
380
|
+
end
|
381
|
+
s1 << r4
|
382
|
+
end
|
383
|
+
if s1.last
|
384
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
385
|
+
r1.extend(Cells1)
|
386
|
+
else
|
387
|
+
self.index = i1
|
388
|
+
r1 = nil
|
389
|
+
end
|
390
|
+
if r1
|
391
|
+
r0 = r1
|
392
|
+
else
|
393
|
+
i8, s8 = index, []
|
394
|
+
s9, i9 = [], index
|
395
|
+
loop do
|
396
|
+
r10 = _nt_cell
|
397
|
+
if r10
|
398
|
+
s9 << r10
|
399
|
+
else
|
400
|
+
break
|
401
|
+
end
|
402
|
+
end
|
403
|
+
r9 = SyntaxNode.new(input, i9...index, s9)
|
404
|
+
s8 << r9
|
405
|
+
if r9
|
406
|
+
r11 = _nt_ignore
|
407
|
+
s8 << r11
|
408
|
+
end
|
409
|
+
if s8.last
|
410
|
+
r8 = (SyntaxNode).new(input, i8...index, s8)
|
411
|
+
r8.extend(Cells2)
|
412
|
+
else
|
413
|
+
self.index = i8
|
414
|
+
r8 = nil
|
415
|
+
end
|
416
|
+
if r8
|
417
|
+
r0 = r8
|
418
|
+
else
|
419
|
+
self.index = i0
|
420
|
+
r0 = nil
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
node_cache[:cells][start_index] = r0
|
425
|
+
|
426
|
+
return r0
|
427
|
+
end
|
428
|
+
|
276
429
|
def _nt_atom
|
277
430
|
start_index = index
|
278
431
|
if node_cache[:atom].has_key?(index)
|
@@ -300,10 +453,10 @@ module Heist
|
|
300
453
|
return r0
|
301
454
|
end
|
302
455
|
|
303
|
-
module Datum0
|
456
|
+
module Datum0 #:nodoc:
|
304
457
|
end
|
305
458
|
|
306
|
-
module Datum1
|
459
|
+
module Datum1 #:nodoc:
|
307
460
|
end
|
308
461
|
|
309
462
|
def _nt_datum
|
@@ -462,12 +615,12 @@ module Heist
|
|
462
615
|
return r0
|
463
616
|
end
|
464
617
|
|
465
|
-
module Complex0
|
618
|
+
module Complex0 #:nodoc:
|
466
619
|
def real
|
467
620
|
elements[0]
|
468
621
|
end
|
469
622
|
|
470
|
-
def
|
623
|
+
def imaginary
|
471
624
|
elements[2]
|
472
625
|
end
|
473
626
|
|
@@ -482,29 +635,53 @@ module Heist
|
|
482
635
|
end
|
483
636
|
|
484
637
|
i0, s0 = index, []
|
485
|
-
|
638
|
+
i1 = index
|
639
|
+
r2 = _nt_real
|
640
|
+
if r2
|
641
|
+
r1 = r2
|
642
|
+
else
|
643
|
+
r3 = _nt_integer
|
644
|
+
if r3
|
645
|
+
r1 = r3
|
646
|
+
else
|
647
|
+
self.index = i1
|
648
|
+
r1 = nil
|
649
|
+
end
|
650
|
+
end
|
486
651
|
s0 << r1
|
487
652
|
if r1
|
488
653
|
if input.index("+", index) == index
|
489
|
-
|
654
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
490
655
|
@index += 1
|
491
656
|
else
|
492
657
|
terminal_parse_failure("+")
|
493
|
-
|
658
|
+
r4 = nil
|
494
659
|
end
|
495
|
-
s0 <<
|
496
|
-
if
|
497
|
-
|
498
|
-
|
499
|
-
if
|
660
|
+
s0 << r4
|
661
|
+
if r4
|
662
|
+
i5 = index
|
663
|
+
r6 = _nt_real
|
664
|
+
if r6
|
665
|
+
r5 = r6
|
666
|
+
else
|
667
|
+
r7 = _nt_integer
|
668
|
+
if r7
|
669
|
+
r5 = r7
|
670
|
+
else
|
671
|
+
self.index = i5
|
672
|
+
r5 = nil
|
673
|
+
end
|
674
|
+
end
|
675
|
+
s0 << r5
|
676
|
+
if r5
|
500
677
|
if input.index("i", index) == index
|
501
|
-
|
678
|
+
r8 = (SyntaxNode).new(input, index...(index + 1))
|
502
679
|
@index += 1
|
503
680
|
else
|
504
681
|
terminal_parse_failure("i")
|
505
|
-
|
682
|
+
r8 = nil
|
506
683
|
end
|
507
|
-
s0 <<
|
684
|
+
s0 << r8
|
508
685
|
end
|
509
686
|
end
|
510
687
|
end
|
@@ -521,10 +698,10 @@ module Heist
|
|
521
698
|
return r0
|
522
699
|
end
|
523
700
|
|
524
|
-
module Real0
|
701
|
+
module Real0 #:nodoc:
|
525
702
|
end
|
526
703
|
|
527
|
-
module Real1
|
704
|
+
module Real1 #:nodoc:
|
528
705
|
def integer
|
529
706
|
elements[0]
|
530
707
|
end
|
@@ -592,7 +769,7 @@ module Heist
|
|
592
769
|
return r0
|
593
770
|
end
|
594
771
|
|
595
|
-
module Rational0
|
772
|
+
module Rational0 #:nodoc:
|
596
773
|
def numerator
|
597
774
|
elements[0]
|
598
775
|
end
|
@@ -640,10 +817,10 @@ module Heist
|
|
640
817
|
return r0
|
641
818
|
end
|
642
819
|
|
643
|
-
module Integer0
|
820
|
+
module Integer0 #:nodoc:
|
644
821
|
end
|
645
822
|
|
646
|
-
module Integer1
|
823
|
+
module Integer1 #:nodoc:
|
647
824
|
end
|
648
825
|
|
649
826
|
def _nt_integer
|
@@ -730,7 +907,7 @@ module Heist
|
|
730
907
|
return r0
|
731
908
|
end
|
732
909
|
|
733
|
-
module String0
|
910
|
+
module String0 #:nodoc:
|
734
911
|
end
|
735
912
|
|
736
913
|
def _nt_string
|
@@ -809,7 +986,16 @@ module Heist
|
|
809
986
|
return r0
|
810
987
|
end
|
811
988
|
|
812
|
-
module Identifier0
|
989
|
+
module Identifier0 #:nodoc:
|
990
|
+
end
|
991
|
+
|
992
|
+
module Identifier1 #:nodoc:
|
993
|
+
end
|
994
|
+
|
995
|
+
module Identifier2 #:nodoc:
|
996
|
+
end
|
997
|
+
|
998
|
+
module Identifier3 #:nodoc:
|
813
999
|
end
|
814
1000
|
|
815
1001
|
def _nt_identifier
|
@@ -820,47 +1006,126 @@ module Heist
|
|
820
1006
|
return cached
|
821
1007
|
end
|
822
1008
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
1009
|
+
i0 = index
|
1010
|
+
i1, s1 = index, []
|
1011
|
+
i2, s2 = index, []
|
1012
|
+
i3 = index
|
1013
|
+
r4 = _nt_delimiter
|
1014
|
+
if r4
|
1015
|
+
r3 = nil
|
1016
|
+
else
|
1017
|
+
self.index = i3
|
1018
|
+
r3 = SyntaxNode.new(input, index...index)
|
1019
|
+
end
|
1020
|
+
s2 << r3
|
1021
|
+
if r3
|
1022
|
+
if index < input_length
|
1023
|
+
r5 = (SyntaxNode).new(input, index...(index + 1))
|
1024
|
+
@index += 1
|
830
1025
|
else
|
831
|
-
|
832
|
-
|
1026
|
+
terminal_parse_failure("any character")
|
1027
|
+
r5 = nil
|
833
1028
|
end
|
834
|
-
|
835
|
-
|
1029
|
+
s2 << r5
|
1030
|
+
end
|
1031
|
+
if s2.last
|
1032
|
+
r2 = (SyntaxNode).new(input, i2...index, s2)
|
1033
|
+
r2.extend(Identifier0)
|
1034
|
+
else
|
1035
|
+
self.index = i2
|
1036
|
+
r2 = nil
|
1037
|
+
end
|
1038
|
+
s1 << r2
|
1039
|
+
if r2
|
1040
|
+
s6, i6 = [], index
|
1041
|
+
loop do
|
1042
|
+
i7, s7 = index, []
|
1043
|
+
i8 = index
|
1044
|
+
r9 = _nt_delimiter
|
1045
|
+
if r9
|
1046
|
+
r8 = nil
|
1047
|
+
else
|
1048
|
+
self.index = i8
|
1049
|
+
r8 = SyntaxNode.new(input, index...index)
|
1050
|
+
end
|
1051
|
+
s7 << r8
|
1052
|
+
if r8
|
1053
|
+
if index < input_length
|
1054
|
+
r10 = (SyntaxNode).new(input, index...(index + 1))
|
1055
|
+
@index += 1
|
1056
|
+
else
|
1057
|
+
terminal_parse_failure("any character")
|
1058
|
+
r10 = nil
|
1059
|
+
end
|
1060
|
+
s7 << r10
|
1061
|
+
end
|
1062
|
+
if s7.last
|
1063
|
+
r7 = (SyntaxNode).new(input, i7...index, s7)
|
1064
|
+
r7.extend(Identifier1)
|
1065
|
+
else
|
1066
|
+
self.index = i7
|
1067
|
+
r7 = nil
|
1068
|
+
end
|
1069
|
+
if r7
|
1070
|
+
s6 << r7
|
1071
|
+
else
|
1072
|
+
break
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
if s6.empty?
|
1076
|
+
self.index = i6
|
1077
|
+
r6 = nil
|
1078
|
+
else
|
1079
|
+
r6 = SyntaxNode.new(input, i6...index, s6)
|
1080
|
+
end
|
1081
|
+
s1 << r6
|
1082
|
+
end
|
1083
|
+
if s1.last
|
1084
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
1085
|
+
r1.extend(Identifier2)
|
1086
|
+
else
|
1087
|
+
self.index = i1
|
1088
|
+
r1 = nil
|
1089
|
+
end
|
1090
|
+
if r1
|
1091
|
+
r0 = r1
|
1092
|
+
r0.extend(Identifier)
|
1093
|
+
else
|
1094
|
+
i11, s11 = index, []
|
1095
|
+
i12 = index
|
1096
|
+
r13 = _nt_reserved
|
1097
|
+
if r13
|
1098
|
+
r12 = nil
|
1099
|
+
else
|
1100
|
+
self.index = i12
|
1101
|
+
r12 = SyntaxNode.new(input, index...index)
|
1102
|
+
end
|
1103
|
+
s11 << r12
|
1104
|
+
if r12
|
836
1105
|
if index < input_length
|
837
|
-
|
1106
|
+
r14 = (SyntaxNode).new(input, index...(index + 1))
|
838
1107
|
@index += 1
|
839
1108
|
else
|
840
1109
|
terminal_parse_failure("any character")
|
841
|
-
|
1110
|
+
r14 = nil
|
842
1111
|
end
|
843
|
-
|
1112
|
+
s11 << r14
|
844
1113
|
end
|
845
|
-
if
|
846
|
-
|
847
|
-
|
1114
|
+
if s11.last
|
1115
|
+
r11 = (SyntaxNode).new(input, i11...index, s11)
|
1116
|
+
r11.extend(Identifier3)
|
848
1117
|
else
|
849
|
-
self.index =
|
850
|
-
|
1118
|
+
self.index = i11
|
1119
|
+
r11 = nil
|
851
1120
|
end
|
852
|
-
if
|
853
|
-
|
1121
|
+
if r11
|
1122
|
+
r0 = r11
|
1123
|
+
r0.extend(Identifier)
|
854
1124
|
else
|
855
|
-
|
1125
|
+
self.index = i0
|
1126
|
+
r0 = nil
|
856
1127
|
end
|
857
1128
|
end
|
858
|
-
if s0.empty?
|
859
|
-
self.index = i0
|
860
|
-
r0 = nil
|
861
|
-
else
|
862
|
-
r0 = Identifier.new(input, i0...index, s0)
|
863
|
-
end
|
864
1129
|
|
865
1130
|
node_cache[:identifier][start_index] = r0
|
866
1131
|
|
@@ -887,6 +1152,33 @@ module Heist
|
|
887
1152
|
return r0
|
888
1153
|
end
|
889
1154
|
|
1155
|
+
def _nt_reserved
|
1156
|
+
start_index = index
|
1157
|
+
if node_cache[:reserved].has_key?(index)
|
1158
|
+
cached = node_cache[:reserved][index]
|
1159
|
+
@index = cached.interval.end if cached
|
1160
|
+
return cached
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
i0 = index
|
1164
|
+
r1 = _nt_dot
|
1165
|
+
if r1
|
1166
|
+
r0 = r1
|
1167
|
+
else
|
1168
|
+
r2 = _nt_delimiter
|
1169
|
+
if r2
|
1170
|
+
r0 = r2
|
1171
|
+
else
|
1172
|
+
self.index = i0
|
1173
|
+
r0 = nil
|
1174
|
+
end
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
node_cache[:reserved][start_index] = r0
|
1178
|
+
|
1179
|
+
return r0
|
1180
|
+
end
|
1181
|
+
|
890
1182
|
def _nt_delimiter
|
891
1183
|
start_index = index
|
892
1184
|
if node_cache[:delimiter].has_key?(index)
|
@@ -896,21 +1188,21 @@ module Heist
|
|
896
1188
|
end
|
897
1189
|
|
898
1190
|
i0 = index
|
899
|
-
|
900
|
-
r1 = (SyntaxNode).new(input, index...(index + 1))
|
901
|
-
@index += 1
|
902
|
-
else
|
903
|
-
r1 = nil
|
904
|
-
end
|
1191
|
+
r1 = _nt_quote
|
905
1192
|
if r1
|
906
1193
|
r0 = r1
|
907
1194
|
else
|
908
|
-
r2 =
|
1195
|
+
r2 = _nt_paren
|
909
1196
|
if r2
|
910
1197
|
r0 = r2
|
911
1198
|
else
|
912
|
-
|
913
|
-
|
1199
|
+
r3 = _nt_space
|
1200
|
+
if r3
|
1201
|
+
r0 = r3
|
1202
|
+
else
|
1203
|
+
self.index = i0
|
1204
|
+
r0 = nil
|
1205
|
+
end
|
914
1206
|
end
|
915
1207
|
end
|
916
1208
|
|
@@ -919,6 +1211,26 @@ module Heist
|
|
919
1211
|
return r0
|
920
1212
|
end
|
921
1213
|
|
1214
|
+
def _nt_paren
|
1215
|
+
start_index = index
|
1216
|
+
if node_cache[:paren].has_key?(index)
|
1217
|
+
cached = node_cache[:paren][index]
|
1218
|
+
@index = cached.interval.end if cached
|
1219
|
+
return cached
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
if input.index(Regexp.new('[\\(\\)\\[\\]]'), index) == index
|
1223
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
1224
|
+
@index += 1
|
1225
|
+
else
|
1226
|
+
r0 = nil
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
node_cache[:paren][start_index] = r0
|
1230
|
+
|
1231
|
+
return r0
|
1232
|
+
end
|
1233
|
+
|
922
1234
|
def _nt_space
|
923
1235
|
start_index = index
|
924
1236
|
if node_cache[:space].has_key?(index)
|
@@ -939,7 +1251,7 @@ module Heist
|
|
939
1251
|
return r0
|
940
1252
|
end
|
941
1253
|
|
942
|
-
module Ignore0
|
1254
|
+
module Ignore0 #:nodoc:
|
943
1255
|
end
|
944
1256
|
|
945
1257
|
def _nt_ignore
|
@@ -984,10 +1296,10 @@ module Heist
|
|
984
1296
|
return r0
|
985
1297
|
end
|
986
1298
|
|
987
|
-
module Comment0
|
1299
|
+
module Comment0 #:nodoc:
|
988
1300
|
end
|
989
1301
|
|
990
|
-
module Comment1
|
1302
|
+
module Comment1 #:nodoc:
|
991
1303
|
def ignore
|
992
1304
|
elements[2]
|
993
1305
|
end
|