myco 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/myco/bootstrap/instance.rb +13 -3
  3. data/lib/myco/code_tools/AST.my +0 -2
  4. data/lib/myco/code_tools/AST.my.rb +0 -1
  5. data/lib/myco/code_tools/AST/Block.my +15 -4
  6. data/lib/myco/code_tools/AST/Block.my.rb +16 -3
  7. data/lib/myco/code_tools/AST/DeclareMeme.my +44 -64
  8. data/lib/myco/code_tools/AST/DeclareMeme.my.rb +66 -74
  9. data/lib/myco/code_tools/AST/ToRuby.my +17 -20
  10. data/lib/myco/code_tools/AST/ToRuby.my.rb +24 -22
  11. data/lib/myco/code_tools/Parser.my +2 -1
  12. data/lib/myco/code_tools/Parser.my.rb +2 -1
  13. data/lib/myco/code_tools/parser/MycoBuilder.my +2 -2
  14. data/lib/myco/code_tools/parser/MycoBuilder.my.rb +2 -2
  15. data/lib/myco/code_tools/parser/MycoGrammar.my +28 -21
  16. data/lib/myco/code_tools/parser/MycoGrammar.my.rb +94 -56
  17. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my +10 -11
  18. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my.rb +10 -9
  19. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +25 -3
  20. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +38 -0
  21. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Capture.my +152 -0
  22. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Capture.my.rb +189 -0
  23. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Common.my +84 -0
  24. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Common.my.rb +114 -0
  25. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Common/Parser.my +139 -0
  26. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/{BytecodeParser.my.rb → Common/Parser.my.rb} +17 -36
  27. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Composite.my +229 -0
  28. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Composite.my.rb +296 -0
  29. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +8 -25
  30. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +9 -37
  31. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +139 -37
  32. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +206 -36
  33. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +21 -12
  34. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +45 -24
  35. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Stream.my +99 -0
  36. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Stream.my.rb +152 -0
  37. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Stream/Parser.my +37 -0
  38. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Stream/Parser.my.rb +57 -0
  39. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/String.my +136 -0
  40. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/String.my.rb +147 -0
  41. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/String/Parser.my +45 -0
  42. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/String/Parser.my.rb +85 -0
  43. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my +31 -25
  44. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my.rb +44 -25
  45. data/lib/myco/code_tools/parser/pegleromyces/spec/Stream/Parser.test.my +49 -0
  46. data/lib/myco/code_tools/parser/pegleromyces/spec/Stream/Parser.test.my.rb +119 -0
  47. data/lib/myco/code_tools/parser/pegleromyces/spec/Stream/Patterns.test.my +131 -0
  48. data/lib/myco/code_tools/parser/pegleromyces/spec/Stream/Patterns.test.my.rb +595 -0
  49. data/lib/myco/code_tools/parser/pegleromyces/spec/{BytecodeParser.test.my → String/Parser.test.my} +41 -2
  50. data/lib/myco/code_tools/parser/pegleromyces/spec/{BytecodeParser.test.my.rb → String/Parser.test.my.rb} +144 -3
  51. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my +4 -10
  52. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my.rb +4 -8
  53. data/lib/myco/core.my +1 -0
  54. data/lib/myco/core.my.rb +1 -0
  55. data/lib/myco/core/BasicObject.my +4 -2
  56. data/lib/myco/core/BasicObject.my.rb +2 -5
  57. data/lib/myco/core/Loop.my +5 -0
  58. data/lib/myco/core/Loop.my.rb +13 -0
  59. data/lib/myco/dev.rb +1 -0
  60. data/lib/myco/dev/profile.rb +12 -0
  61. data/lib/myco/version.rb +3 -3
  62. metadata +54 -59
  63. data/lib/myco/code_tools/AST/DeclareDecorator.my +0 -19
  64. data/lib/myco/code_tools/AST/DeclareDecorator.my.rb +0 -24
  65. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my +0 -4
  66. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my.rb +0 -5
  67. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +0 -420
  68. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +0 -415
  69. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +0 -147
  70. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my +0 -183
  71. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my.rb +0 -370
  72. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my +0 -139
  73. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my.rb +0 -284
  74. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my +0 -37
  75. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +0 -24
  76. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +0 -123
  77. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +0 -164
  78. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my +0 -10
  79. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my.rb +0 -9
  80. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my +0 -10
  81. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my.rb +0 -9
  82. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my +0 -229
  83. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my.rb +0 -663
  84. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my +0 -10
  85. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my.rb +0 -9
  86. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my +0 -13
  87. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my.rb +0 -20
  88. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my +0 -54
  89. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my.rb +0 -215
@@ -1,19 +0,0 @@
1
-
2
- CodeTools::AST << {
3
-
4
- DeclareDecorator < Node {
5
- node_type deco
6
- field name, field arguments
7
-
8
- setter arguments: |x|
9
- x || ArrayAssembly.new(line:self.line, body:[])
10
-
11
- implementation: ArrayAssembly.new(
12
- line:self.line
13
- body:[self.name, self.arguments]
14
- )
15
-
16
- bytecode: |g| pos(g); implementation.bytecode(g)
17
- }
18
-
19
- }
@@ -1,24 +0,0 @@
1
-
2
- ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
- .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.find_constant(:CodeTools)::AST.component_eval {(::Myco.cscope.for_method_definition::DeclareDecorator = ::Myco::Component.new([::Myco.find_constant(:Node)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
- .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
- declare_meme(:deco, [[:node_type, []]], nil, ::Myco.cscope.dup) { |*| nil}
6
- declare_meme(:name, [[:field, []]], nil, ::Myco.cscope.dup) { |*| nil}
7
- declare_meme(:arguments, [[:field, []]], nil, ::Myco.cscope.dup) { |*| nil}
8
- declare_meme(:arguments, [[:setter, []]], nil, ::Myco.cscope.dup) { |x| (::Myco.branch_op(:"||", x) {::Myco.find_constant(:ArrayAssembly).new({
9
- :line => self.line,
10
- :body => []
11
- })})}
12
- declare_meme(:implementation, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:ArrayAssembly).new({
13
- :line => self.line,
14
- :body => [
15
- self.name,
16
- self.arguments
17
- ]
18
- }))}
19
- declare_meme(:bytecode, [], nil, ::Myco.cscope.dup) { |g| (
20
- self.pos(g)
21
- self.implementation.bytecode(g)
22
- )}
23
- )}}
24
- .tap { |__c__| __c__.__name__ = :DeclareDecorator })})}}.instance
@@ -1,4 +0,0 @@
1
-
2
- Builder < BasicObject {
3
-
4
- }
@@ -1,5 +0,0 @@
1
-
2
- ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
- .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.cscope.for_method_definition::Builder = ::Myco::Component.new([::Myco.find_constant(:BasicObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
- .tap { |__c__| __c__.__last__ = __c__.component_eval {nil}}
5
- .tap { |__c__| __c__.__name__ = :Builder })}}.instance
@@ -1,420 +0,0 @@
1
- ##
2
- # The following code is based on code from Pegarus by Brian Shirai.
3
- # A link to the code in question and the relevant license is reproduced below.
4
- #
5
- # https://github.com/brixen/pegarus/blob/master/lib/pegarus/rubinius/compiler.rb
6
- #
7
- # Copyright (c) 2014, Brian Shirai
8
- # All rights reserved.
9
- #
10
- # Redistribution and use in source and binary forms, with or without
11
- # modification, are permitted provided that the following conditions are met:
12
- #
13
- # 1. Redistributions of source code must retain the above copyright notice, this
14
- # list of conditions and the following disclaimer.
15
- # 2. Redistributions in binary form must reproduce the above copyright notice,
16
- # this list of conditions and the following disclaimer in the documentation
17
- # and/or other materials provided with the distribution.
18
- # 3. Neither the name of the library nor the names of its contributors may be
19
- # used to endorse or promote products derived from this software without
20
- # specific prior written permission.
21
- #
22
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
- # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
26
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29
- # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31
- # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
-
33
- import "BytecodeHelpers.my"
34
-
35
-
36
- # This set of instructions is not directly related to those in Instructions, as
37
- # those are not necessarily suitable for direct translation to the Rubinius VM.
38
- #
39
- BytecodeInstructions < BasicObject {
40
-
41
- Constructions << {
42
- AnyCharacter << { bytecode: |m| m.any(1) }
43
- Character << { bytecode: |m| m.char(code.chr) }
44
- CharacterString << { bytecode: |m| m.char(codes.map(&:chr).join) }
45
- CharacterSet << { bytecode: |m| m.set(codes.map(&:chr).join) }
46
- CharacterRange << { bytecode: |m|
47
- codes = Range.new(start,stop); m.set(codes.map(&:chr).join)
48
- }
49
-
50
- NegativePredicate << { bytecode: |m|
51
- m.neg_predicate(
52
- &{ inner.bytecode(m) }
53
- inner.bytecode_can_capture
54
- )
55
- }
56
- PositivePredicate << { bytecode: |m|
57
- m.pos_predicate(
58
- &{ inner.bytecode(m) }
59
- inner.bytecode_can_capture
60
- )
61
- }
62
- OneOrMore << { bytecode: |m|
63
- m.many(
64
- &{ inner.bytecode(m); inlaid.?call }
65
- inner.bytecode_can_capture
66
- )
67
- }
68
- ZeroOrOne << {
69
- bytecode: |m| {
70
- m.choice(
71
- &{ inner.bytecode(m) }
72
- &{ }
73
- inner.bytecode_can_capture
74
- )
75
- }
76
- }
77
- ZeroOrMore << { bytecode: |m|
78
- m.kleene(
79
- &{ inner.bytecode(m); inlaid.?call }
80
- inner.bytecode_can_capture
81
- )
82
- }
83
- OrderedChoice << {
84
- bytecode: |m| {
85
- m.choice(
86
- &{ first.bytecode(m) }
87
- &{ second.bytecode(m) }
88
- first.bytecode_can_capture
89
- )
90
- }
91
- }
92
- Concatenation << { bytecode: |m|
93
- first.bytecode(m); second.bytecode(m)
94
- }
95
-
96
- NamedCapture << {
97
- bytecode: |m| {
98
- (inner.is_a?(OneOrMore) || inner.is_a?(ZeroOrMore)) &? (
99
- inner.inlaid = &{ m.capture(:m_split, captargs) }
100
- m.capture(:m_start)
101
- inner.bytecode(m)
102
- m.capture(:m_end, captargs)
103
- ) ?? (
104
- m.capture(:c_start)
105
- inner.bytecode(m)
106
- m.capture(:c_end, captargs)
107
- )
108
- }
109
- }
110
-
111
- NamedTextCapture << {
112
- bytecode: |m| {
113
- m.capture(:s_start)
114
- inner.bytecode(m)
115
- m.capture(:s_end, captargs)
116
- }
117
- }
118
-
119
- NamedTokenCapture << {
120
- bytecode: |m| {
121
- m.capture(:t_start)
122
- inner.bytecode(m)
123
- m.capture(:t_end, captargs)
124
- }
125
- }
126
-
127
- Reduction << {
128
- bytecode: |m| {
129
- m.capture(:r_start)
130
- inner.bytecode(m)
131
- m.capture(:r_end, captargs)
132
- }
133
- }
134
-
135
- # Hints for optimization (skip saving of temp captures for primitives)
136
- AnyCharacter << { bytecode_can_capture: false }
137
- Character << { bytecode_can_capture: false }
138
- CharacterString << { bytecode_can_capture: false }
139
- CharacterSet << { bytecode_can_capture: false }
140
- CharacterRange << { bytecode_can_capture: false }
141
- NegativePredicate << { bytecode_can_capture: inner.bytecode_can_capture }
142
- PositivePredicate << { bytecode_can_capture: inner.bytecode_can_capture }
143
- OneOrMore << { bytecode_can_capture: inner.bytecode_can_capture }
144
- ZeroOrOne << { bytecode_can_capture: inner.bytecode_can_capture }
145
- ZeroOrMore << { bytecode_can_capture: inner.bytecode_can_capture }
146
- OrderedChoice << { bytecode_can_capture: first.bytecode_can_capture
147
- || second.bytecode_can_capture }
148
- Concatenation << { bytecode_can_capture: first.bytecode_can_capture
149
- || second.bytecode_can_capture }
150
- NamedCapture << { bytecode_can_capture: true }
151
- NamedTextCapture << { bytecode_can_capture: true }
152
- NamedTokenCapture << { bytecode_can_capture: true }
153
- Reduction << { bytecode_can_capture: true }
154
- }
155
-
156
-
157
- var g # The generator to use
158
-
159
- # Match any character, |count| number of times.
160
- any: |count| {
161
- g.push_idx
162
- g.push_int(count)
163
- g.send(:"+", 1)
164
-
165
- g.push_subject
166
- g.send(:size, 0)
167
- g.send(:"<=", 1)
168
- g.goto_if_false(g.overall_fail)
169
-
170
- g.push_int(count)
171
- g.increment_idx
172
- }
173
-
174
- # Match the given |string| of characters, one time.
175
- char: |string| {
176
- g.setup_unwind(g.overall_fail, 0) # "rescue" to overall fail
177
-
178
- g.push_literal(string)
179
- g.push_subject
180
- g.push_idx
181
- g.push_int(string.size)
182
- g.send(:compare_substring, 3)
183
- g.meta_push_0
184
-
185
- g.pop_unwind # end rescued block
186
-
187
- g.goto_if_not_equal(g.overall_fail)
188
-
189
- g.push_int(string.size)
190
- g.increment_idx
191
- }
192
-
193
- # Match if the character is included in the given |string|, one time.
194
- set: |string| {
195
- local_done = g.new_label
196
- local_early_fail = g.new_label
197
-
198
- g.push_literal(string)
199
- g.push_subject_at_idx
200
- g.dup_top
201
- g.goto_if_false(local_early_fail)
202
- g.meta_push_0
203
- g.send(:find_string, 2)
204
- g.goto_if_false(g.overall_fail)
205
- g.goto(local_done)
206
-
207
- local_early_fail.set!
208
- g.pop # pop literal string
209
- g.pop # pop subject_at_idx
210
- g.goto(g.overall_fail)
211
-
212
- local_done.set!
213
- g.meta_push_1
214
- g.increment_idx
215
- }
216
-
217
- # An ordered choice between |first| and |second|.
218
- # Each argument should be a Proc that generates bytecode when called.
219
- choice: |first, second, first_can_capture| {
220
- local_done = g.new_label
221
- local_fail = g.new_label
222
- old_fail = g.overall_fail
223
- g.overall_fail = local_fail
224
-
225
- # Store index and captures for backtracking in case of failure
226
- if(first_can_capture) { g.push_temp_captures }
227
- g.push_idx
228
-
229
- first.call
230
-
231
- # Success, throw away backtrack entry
232
- g.pop # keep idx
233
- if(first_can_capture) { g.pop_to_accept_captures }
234
- g.overall_fail = old_fail # reset fail
235
- g.goto(local_done)
236
-
237
- # Failure, backtrack index and captures
238
- local_fail.set!
239
- g.pop_to_set_idx
240
- if(first_can_capture) { g.pop_to_reject_captures }
241
- g.overall_fail = old_fail
242
-
243
- second.call
244
-
245
- local_done.set!
246
- }
247
-
248
- # Keep consuming |inner| until it doesn't match; it must match at least one.
249
- # The argument should be a Proc that generates bytecode when called.
250
- many: |inner, inner_can_capture| {
251
- local_retry = g.new_label
252
- local_fail = g.new_label
253
- old_fail = g.overall_fail
254
- g.overall_fail = local_fail
255
- # push a false to indicate that no matches have occurred yet
256
- g.push_false
257
-
258
- local_retry.set!
259
-
260
- # Store captures for restoration
261
- if(inner_can_capture) { g.push_temp_captures }
262
-
263
- inner.call
264
-
265
- # Success, accept captures and try again, popping the last boolean
266
- # to push a true to indicate at least one match was made.
267
- if(inner_can_capture) { g.pop_to_accept_captures }
268
- g.pop; g.push_true
269
- g.goto(local_retry)
270
-
271
- # Failure, reject captures and continue
272
- local_fail.set!
273
- if(inner_can_capture) { g.pop_to_reject_captures }
274
- g.overall_fail = old_fail # reset fail
275
-
276
- # If at least one match was not found, it is an overall failure
277
- g.goto_if_false(g.overall_fail)
278
- }
279
-
280
- # Keep consuming |inner| until it doesn't match; it will not cause backtrack.
281
- # The argument should be a Proc that generates bytecode when called.
282
- kleene: |inner, inner_can_capture| {
283
- local_retry = g.new_label
284
- local_fail = g.new_label
285
- old_fail = g.overall_fail
286
- g.overall_fail = local_fail
287
-
288
- local_retry.set!
289
-
290
- # Store captures for restoration
291
- if(inner_can_capture) { g.push_temp_captures }
292
-
293
- inner.call
294
-
295
- # Success, accept captures and try again
296
- if(inner_can_capture) { g.pop_to_accept_captures }
297
- g.goto(local_retry)
298
-
299
- # Failure, reject captures and continue
300
- local_fail.set!
301
- if(inner_can_capture) { g.pop_to_reject_captures }
302
- g.overall_fail = old_fail # reset fail
303
- }
304
-
305
- # Positive matching predicate that consumes no input.
306
- # The argument should be a Proc that generates bytecode when called.
307
- pos_predicate: |inner, inner_can_capture| {
308
- local_done = g.new_label
309
- local_fail = g.new_label
310
- old_fail = g.overall_fail
311
- g.overall_fail = local_fail
312
-
313
- # Store index and captures for backtracking
314
- if(inner_can_capture) { g.push_temp_captures }
315
- g.push_idx
316
-
317
- inner.call
318
-
319
- # Success, but do not consume input, so backtrack index but keep captures
320
- g.pop_to_set_idx
321
- if(inner_can_capture) { g.pop_to_accept_captures }
322
- g.overall_fail = old_fail # reset fail
323
- g.goto(local_done)
324
-
325
- # Failure, backtrack index and captures
326
- local_fail.set!
327
- g.pop_to_set_idx
328
- if(inner_can_capture) { g.pop_to_reject_captures }
329
- g.overall_fail = old_fail
330
- g.goto(g.overall_fail)
331
-
332
- local_done.set!
333
- }
334
-
335
- # Negative matching predicate that consumes no input.
336
- # The argument should be a Proc that generates bytecode when called.
337
- neg_predicate: |inner, inner_can_capture| {
338
- local_fail = g.new_label
339
- old_fail = g.overall_fail
340
- g.overall_fail = local_fail
341
-
342
- # Store index and captures for backtracking
343
- if(inner_can_capture) { g.push_temp_captures }
344
- g.push_idx
345
-
346
- inner.call
347
-
348
- # Success => Failure, backtrack index and captures
349
- g.pop_to_set_idx
350
- if(inner_can_capture) { g.pop_to_reject_captures }
351
- g.overall_fail = old_fail # reset fail
352
- g.goto(g.overall_fail)
353
-
354
- # Failure => Success, backtrack index and cannot keep captures either (incomplete)
355
- local_fail.set!
356
- g.pop_to_set_idx
357
- if(inner_can_capture) { g.pop_to_reject_captures }
358
- g.overall_fail = old_fail
359
- }
360
-
361
- # Call the compiled rule by |name| and continue or fail based on the result.
362
- call: |name, memoize=true| {
363
- result_check = g.new_label
364
- memo_result_check = g.new_label
365
- local_success = g.new_label
366
- local_fail = g.new_label
367
-
368
- # Push @captures onto stack and set @captures to a new empty array
369
- g.push_temp_captures
370
-
371
- if(memoize) {
372
- # Check if a memoized result exists;
373
- # If one does, go straight to memo_result_check label
374
- g.memo_or_eq_new_hash(name)
375
- g.goto_if_memo_for_idx(name, memo_result_check)
376
- }
377
-
378
- # Call the method; sets @captures and returns the result_idx (or nil)
379
- g.push_self
380
- g.push_subject
381
- g.push_idx
382
- g.send(name, 2)
383
-
384
- # Check result and memoize the result
385
- result_check.set!
386
- g.copy_result_to_memo(name)
387
- g.dup_top
388
- g.goto_if_true(local_success)
389
- g.goto(local_fail)
390
-
391
- if(memoize) {
392
- # Check result, but skip memo copy
393
- memo_result_check.set!
394
- g.dup_top
395
- g.goto_if_true(local_success)
396
- g.goto(local_fail)
397
- }
398
-
399
- # Failure, reject index and captures
400
- local_fail.set!
401
- g.pop # reject idx (which is actually null here)
402
- g.pop_to_reject_captures
403
- g.goto(g.overall_fail)
404
-
405
- # Success, accept new index and captures
406
- local_success.set!
407
- g.pop_to_set_idx # set to the new index given by the call's return value
408
- g.pop_to_accept_captures
409
- }
410
-
411
- capture: |*metadata| {
412
- g.push_captures
413
- g.push_idx
414
- g.push_literal_or_array(metadata)
415
- g.make_array(2)
416
- g.make_array(1)
417
- g.send(:concat, 1)
418
- g.pop
419
- }
420
- }