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,51 +1,221 @@
1
1
 
2
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::Parser = ::Myco::Component.new([::Myco.find_constant(:BasicObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.find_constant(:Common).component_eval {(::Myco.cscope.for_method_definition::Parser = ::Myco::Component.new([::Myco.find_constant(:BasicObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
4
  .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ ::Myco.cscope.for_method_definition::State = ::Myco::Component.new([::Myco.find_constant(:BasicObject)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
6
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
7
+ declare_meme(:string, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
8
+ declare_meme(:start_idx, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
9
+ declare_meme(:end_idx, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
10
+ declare_meme(:rule, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
11
+ declare_meme(:result, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
12
+ declare_meme(:error_idx, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
13
+ declare_meme(:error_row, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
14
+ declare_meme(:error_col, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
15
+ declare_meme(:raise_error, [], nil, ::Myco.cscope.dup) { |*| (::Myco.branch_op(:"&&", self.error_idx) {self.raise(
16
+ ::Myco.find_constant(:SyntaxError),
17
+ "Unexpected character with parser: #{self.rule} near line: #{self.error_row}, column: #{self.error_col}.\n#{self.string.each_line.to_a.__send__(
18
+ :[],
19
+ self.error_row.__send__(
20
+ :-,
21
+ 1
22
+ )
23
+ )}#{" ".__send__(
24
+ :*,
25
+ [
26
+ self.error_col.__send__(
27
+ :-,
28
+ 1
29
+ ),
30
+ 0
31
+ ].max
32
+ )}^"
33
+ )})}
34
+ )}}
35
+ .tap { |__c__| __c__.__name__ = :State }
36
+ declare_meme(:debug_mode, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (false)}
5
37
  declare_meme(:grammar, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Grammar).new)}
6
- declare_meme(:string, [[:var, []]], nil, ::Myco.cscope.dup) { |*| ("")}
7
- declare_meme(:result, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (nil)}
8
- declare_meme(:make_sequence_table, [[:memoize, []]], nil, ::Myco.cscope.dup) { |grammar| (
9
- grammar.construct_all_rules
10
- grammar.rule_table.map { |k, v| ([
11
- k,
12
- v.construct_rule.sequence.__send__(
13
- :+,
14
- [[:return]]
15
- )
16
- ])}.to_h
17
- )}
18
- declare_meme(:new_machine, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Machine).new({
19
- :sequence_table => self.make_sequence_table(self.grammar),
20
- :subject => self.string.each_char.map(&:ord)
21
- }))}
22
- declare_meme(:new_processor, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Processor).new({
23
- :builder => self.new_builder,
24
- :string => self.string
25
- }))}
26
- declare_meme(:new_builder, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Builder).new)}
27
- declare_meme(:parse, [], nil, ::Myco.cscope.dup) { |string=nil| (
28
- ::Myco.branch_op(:"&&", string) {self.__send__(
29
- :string=,
30
- string
38
+ declare_meme(:builder, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (nil)}
39
+ declare_meme(:new_worker, [], nil, ::Myco.cscope.dup) { |*| (self.set_up_worker(self.prototype.new))}
40
+ declare_meme(:new_processor, [], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Processor).new({:builder => self.builder}))}
41
+ declare_meme(:prototype, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (self.compile_prototype)}
42
+ declare_meme(:refresh, [], nil, ::Myco.cscope.dup) { |*| (self.__send__(
43
+ :prototype=,
44
+ self.compile_prototype
45
+ ))}
46
+ declare_meme(:compile_prototype, [], nil, ::Myco.cscope.dup) { |*| (
47
+ proto = ::Myco.find_constant(:Component).new
48
+ self.grammar.construct_all_rules
49
+ self.grammar.rule_table.each { |name, rule| (self.compile_rule_into(
50
+ proto,
51
+ name,
52
+ rule
53
+ ))}
54
+ proto
55
+ )}
56
+ declare_meme(:compile_rule_into, [], nil, ::Myco.cscope.dup) { |proto, name, rule| (
57
+ construct = rule.inner.construct
58
+ ::Myco.find_constant(:Myco).add_dynamic_method(
59
+ proto,
60
+ name,
61
+ "(compiled parser)"
62
+ ) { |g| (
63
+ g.extend(::Myco.find_constant(:BytecodeHelpers))
64
+ g.__send__(
65
+ :debug_mode=,
66
+ self.debug_mode
67
+ )
68
+ g.rule_start
69
+ construct.bytecode(g)
70
+ g.rule_finish
31
71
  )}
32
- machine = self.new_machine
33
- machine.execute
72
+ )}
73
+ declare_meme(:compile_generator, [], nil, ::Myco.cscope.dup) { |name, file, line=1, &block| (
74
+ g = ::Myco.find_constant(:Myco)::ToolSet::Generator.new
75
+ g.__send__(
76
+ :name=,
77
+ name
78
+ )
79
+ g.__send__(
80
+ :file=,
81
+ file
82
+ )
83
+ g.set_line(line)
84
+ block.call(g)
85
+ g.ret
86
+ g.close
87
+ g.use_detected
88
+ g
89
+ )}
90
+ declare_meme(:compile_code, [], nil, ::Myco.cscope.dup) { |name, file, line=1, &block| (
91
+ g = self.compile_generator(
92
+ name,
93
+ file,
94
+ line,
95
+ &block
96
+ )
97
+ g.encode
98
+ g.package(::Myco.find_constant(:Rubinius)::CompiledCode)
99
+ )}
100
+ declare_meme(:save_prototype, [], nil, ::Myco.cscope.dup) { |filename| (
101
+ code = self.compile_code(
102
+ :__script__,
103
+ :"(snippet)"
104
+ ) { |g| (
105
+ g.push_cpath_top
106
+ g.find_const(:Class)
107
+ g.create_block(self.compile_generator(
108
+ :__block__,
109
+ :"(snippet)"
110
+ ) { |g| (self.prototype.instance_methods.each { |name| (
111
+ code = self.prototype.instance_method(name).executable
112
+ self.__send__(
113
+ :if,
114
+ code.__send__(
115
+ :is_a?,
116
+ ::Myco.find_constant(:Rubinius)::CompiledCode
117
+ )
118
+ ) { || (
119
+ g.push_rubinius
120
+ g.push_literal(name)
121
+ g.push_literal(code)
122
+ g.push_scope
123
+ g.push_variables
124
+ g.send(
125
+ :method_visibility,
126
+ 0
127
+ )
128
+ g.send(
129
+ :add_defn_method,
130
+ 4
131
+ )
132
+ )}
133
+ )})})
134
+ g.send_with_block(
135
+ :new,
136
+ 0
137
+ )
138
+ )}
139
+ ::Myco.find_constant(:Myco)::ToolSet::CompiledFile.dump(
140
+ code,
141
+ filename,
142
+ ::Myco.find_constant(:Rubinius)::Signature,
143
+ ::Myco.find_constant(:Rubinius)::RUBY_LIB_VERSION
144
+ )
145
+ )}
146
+ declare_meme(:load_prototype, [], nil, ::Myco.cscope.dup) { |filename| (
147
+ loader = ::Myco.find_constant(:Myco)::CodeLoader::BytecodeLoader.new(filename)
148
+ loader.bind_to({:call_depth => 1})
34
149
  self.__send__(
35
- :unless,
36
- machine.had_failure
37
- ) { || (
38
- processor = self.new_processor
150
+ :prototype=,
151
+ loader.load
152
+ )
153
+ )}
154
+ declare_meme(:set_up_worker, [], nil, ::Myco.cscope.dup) { |worker| (
155
+ worker.__set_ivar__(
156
+ :@captures,
157
+ []
158
+ )
159
+ worker.__set_ivar__(
160
+ :@highest_idx,
161
+ 0
162
+ )
163
+ worker
164
+ )}
165
+ declare_meme(:captures_of_worker, [], nil, ::Myco.cscope.dup) { |worker| (worker.__get_ivar__(:@captures))}
166
+ declare_meme(:highest_idx_of_worker, [], nil, ::Myco.cscope.dup) { |worker| (worker.__get_ivar__(:@highest_idx))}
167
+ declare_meme(:parse, [], nil, ::Myco.cscope.dup) { |string, rule:"root", start_idx:0| (
168
+ worker = self.new_worker
169
+ processor = self.new_processor
170
+ state = ::Myco.find_constant(:State).new({
171
+ :string => string.to_s,
172
+ :rule => rule.to_sym,
173
+ :start_idx => start_idx.to_i
174
+ })
175
+ state.__send__(
176
+ :end_idx=,
177
+ worker.__send__(
178
+ state.rule,
179
+ state.string,
180
+ state.start_idx
181
+ )
182
+ )
183
+ ::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", state.end_idx) {(
184
+ processor.__send__(
185
+ :string=,
186
+ state.string
187
+ )
39
188
  processor.__send__(
40
189
  :capture_items=,
41
- machine.captures
190
+ self.captures_of_worker(worker)
42
191
  )
43
- self.__send__(
192
+ ::Myco.branch_op(:"&&", (Rubinius::Type.object_respond_to?(self.grammar, :tokenizer).false? ? ::Myco::Void : self.grammar.tokenizer)) {processor.__send__(
193
+ :tokenizer=,
194
+ self.grammar.tokenizer
195
+ )}
196
+ state.__send__(
44
197
  :result=,
45
198
  processor.process
46
199
  )
200
+ )}) {(
201
+ state.__send__(
202
+ :error_idx=,
203
+ self.highest_idx_of_worker(worker)
204
+ )
205
+ pos = processor.position_of(
206
+ state.error_idx,
207
+ state.string
208
+ )
209
+ state.__send__(
210
+ :error_row=,
211
+ pos.first
212
+ )
213
+ state.__send__(
214
+ :error_col=,
215
+ pos.last
216
+ )
47
217
  )}
48
- self
218
+ state
49
219
  )}
50
220
  )}}
51
- .tap { |__c__| __c__.__name__ = :Parser })}}.instance
221
+ .tap { |__c__| __c__.__name__ = :Parser })})}}.instance
@@ -24,12 +24,22 @@ Processor < BasicObject {
24
24
  integer: |base=0| text.to_inum(base, true)
25
25
  }
26
26
 
27
+ var tokenizer: &|type, source, start, stop| {
28
+ pos = position_of(start, source)
29
+ value = Token.new(
30
+ type: type
31
+ text: source.slice(start, stop - start)
32
+ row: pos.first
33
+ col: pos.last
34
+ )
35
+ }
36
+
27
37
  # The environment for performing reduction actions to build an AST in the PEG.
28
38
  # It gives implicit access to both local captures and AST builder methods.
29
39
  var reduction_env:
30
- Patterns::Reduction::Environment.new
40
+ Capture::Patterns::Reduction::Environment.new
31
41
  var reduction_env_cscope:
32
- ::Rubinius::ConstantScope.new(Patterns::Reduction::Environment) # TODO: fix
42
+ ::Rubinius::ConstantScope.new(Capture::Patterns::Reduction::Environment) # TODO: fix
33
43
 
34
44
  var cidx_stack: [] # A FILO stack of start indices for captures
35
45
  var sidx_stack: [] # A FILO stack of start indices for string captures
@@ -116,7 +126,8 @@ Processor < BasicObject {
116
126
  # If the reduction is not found and the string length is not zero
117
127
  # slice the string with the given indices to get a text value.
118
128
  !use_reduction && !(start_idx==idx) && (
119
- value = string.slice(start_idx, idx-start_idx)
129
+ size = idx-start_idx
130
+ value = (size == 1 &? string[start_idx] ?? string.slice(start_idx, size))
120
131
  )
121
132
 
122
133
  store_value = [[start_idx, idx], value]
@@ -151,14 +162,8 @@ Processor < BasicObject {
151
162
  t_end: |idx, name| {
152
163
  captures = capt_stack.last
153
164
  start_idx = tidx_stack.pop
154
- pos = position_of(start_idx, string)
155
165
 
156
- value = Token.new(
157
- type: name
158
- text: string.slice(start_idx, idx - start_idx)
159
- row: pos.first
160
- col: pos.last
161
- )
166
+ value = tokenizer.call(name, string, start_idx, idx)
162
167
  store_value = [[start_idx, idx], value]
163
168
  captures.store(idx, store_value)
164
169
  captures.store(name, store_value)
@@ -216,16 +221,20 @@ Processor < BasicObject {
216
221
  captures = pop_layer
217
222
  start_idx = ridx_stack.pop
218
223
 
224
+ captures_map = captures.map |k,v| {
225
+ k.is_a?(Symbol) &? [k,v.last] ?? null
226
+ }.compact.to_h
227
+
219
228
  # Set up the reduction environment
220
229
  code.scope = reduction_env_cscope
221
230
  reduction_env.builder = builder
222
- reduction_env.captures = captures.map |k,v| { [k,v.last] }.to_h
231
+ reduction_env.captures = captures_map
223
232
 
224
233
  # Invoke the reduction action to get a value
225
234
  # Store with the string index as the key so the value can be recaptured
226
235
  value = code.invoke(
227
236
  code.name,
228
- Patterns::Reduction::Environment,
237
+ Capture::Patterns::Reduction::Environment,
229
238
  reduction_env,
230
239
  [],
231
240
  null,
@@ -38,8 +38,26 @@
38
38
  ))}
39
39
  )}}
40
40
  .tap { |__c__| __c__.__name__ = :Token }
41
- declare_meme(:reduction_env, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Patterns)::Reduction::Environment.new)}
42
- declare_meme(:reduction_env_cscope, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Rubinius::ConstantScope.new(::Myco.find_constant(:Patterns)::Reduction::Environment))}
41
+ declare_meme(:tokenizer, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Object::Proc.new { |type, source, start, stop| (
42
+ pos = self.position_of(
43
+ start,
44
+ source
45
+ )
46
+ value = ::Myco.find_constant(:Token).new({
47
+ :type => type,
48
+ :text => source.slice(
49
+ start,
50
+ stop.__send__(
51
+ :-,
52
+ start
53
+ )
54
+ ),
55
+ :row => pos.first,
56
+ :col => pos.last
57
+ })
58
+ )})}
59
+ declare_meme(:reduction_env, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Myco.find_constant(:Capture)::Patterns::Reduction::Environment.new)}
60
+ declare_meme(:reduction_env_cscope, [[:var, []]], nil, ::Myco.cscope.dup) { |*| (::Rubinius::ConstantScope.new(::Myco.find_constant(:Capture)::Patterns::Reduction::Environment))}
43
61
  declare_meme(:cidx_stack, [[:var, []]], nil, ::Myco.cscope.dup) { |*| ([])}
44
62
  declare_meme(:sidx_stack, [[:var, []]], nil, ::Myco.cscope.dup) { |*| ([])}
45
63
  declare_meme(:tidx_stack, [[:var, []]], nil, ::Myco.cscope.dup) { |*| ([])}
@@ -149,12 +167,21 @@
149
167
  ::Myco.branch_op(:"&&", ::Myco.branch_op(:"&&", use_reduction.__send__(:!)) {start_idx.__send__(
150
168
  :==,
151
169
  idx
152
- ).__send__(:!)}) {value = self.string.slice(
153
- start_idx,
154
- idx.__send__(
170
+ ).__send__(:!)}) {(
171
+ size = idx.__send__(
155
172
  :-,
156
173
  start_idx
157
174
  )
175
+ value = ::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", size.__send__(
176
+ :==,
177
+ 1
178
+ )) {self.string.__send__(
179
+ :[],
180
+ start_idx
181
+ )}) {self.string.slice(
182
+ start_idx,
183
+ size
184
+ )}
158
185
  )}
159
186
  store_value = [
160
187
  [
@@ -203,22 +230,12 @@
203
230
  declare_meme(:t_end, [], nil, ::Myco.cscope.dup) { |idx, name| (
204
231
  captures = self.capt_stack.last
205
232
  start_idx = self.tidx_stack.pop
206
- pos = self.position_of(
233
+ value = self.tokenizer.call(
234
+ name,
235
+ self.string,
207
236
  start_idx,
208
- self.string
237
+ idx
209
238
  )
210
- value = ::Myco.find_constant(:Token).new({
211
- :type => name,
212
- :text => self.string.slice(
213
- start_idx,
214
- idx.__send__(
215
- :-,
216
- start_idx
217
- )
218
- ),
219
- :row => pos.first,
220
- :col => pos.last
221
- })
222
239
  store_value = [
223
240
  [
224
241
  start_idx,
@@ -300,6 +317,13 @@
300
317
  declare_meme(:r_end, [], nil, ::Myco.cscope.dup) { |idx, code, *args| (
301
318
  captures = self.pop_layer
302
319
  start_idx = self.ridx_stack.pop
320
+ captures_map = captures.map { |k, v| (::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", k.__send__(
321
+ :is_a?,
322
+ ::Myco.find_constant(:Symbol)
323
+ )) {[
324
+ k,
325
+ v.last
326
+ ]}) {nil})}.compact.to_h
303
327
  code.__send__(
304
328
  :scope=,
305
329
  self.reduction_env_cscope
@@ -310,14 +334,11 @@
310
334
  )
311
335
  self.reduction_env.__send__(
312
336
  :captures=,
313
- captures.map { |k, v| ([
314
- k,
315
- v.last
316
- ])}.to_h
337
+ captures_map
317
338
  )
318
339
  value = code.invoke(
319
340
  code.name,
320
- ::Myco.find_constant(:Patterns)::Reduction::Environment,
341
+ ::Myco.find_constant(:Capture)::Patterns::Reduction::Environment,
321
342
  self.reduction_env,
322
343
  [],
323
344
  nil
@@ -0,0 +1,99 @@
1
+
2
+ Stream < EmptyObject {
3
+ Patterns < EmptyObject {
4
+ Base < Common::Patterns::Base { }
5
+
6
+ End < Base {
7
+ construct: Constructions::End.new
8
+ }
9
+ Item < Base { var checks
10
+ construct: Constructions::Item.new(checks: checks)
11
+ }
12
+ }
13
+
14
+ Constructions < EmptyObject {
15
+ Base < Common::Constructions::Base { }
16
+
17
+ End < Base { }
18
+ Item < Base { var checks }
19
+ }
20
+
21
+ Constructions << {
22
+ End << { bytecode: |g| {
23
+ # Just verify the index is NOT within range
24
+ g.push_subject; g.send(:size, 0)
25
+ g.push_idx
26
+ g.send(:">", 1)
27
+ g.goto_if_true(g.overall_fail)
28
+ }}
29
+
30
+ Item << { bytecode: |g| {
31
+ many_checks = checks.size > 1
32
+ local_fail = g.overall_fail
33
+ if(many_checks) { local_fail = g.new_label }
34
+
35
+ # First, verify the index is within range
36
+ g.push_subject; g.send(:size, 0)
37
+ g.push_idx
38
+ g.send(:">", 1)
39
+ g.goto_if_false(g.overall_fail)
40
+
41
+ checks.empty? || (
42
+ # Retrieve the item
43
+ g.push_subject_at_idx
44
+
45
+ # Try each check on the item until one fails
46
+ checks.each |method, args, result| {
47
+ if(many_checks) { g.dup_top }
48
+
49
+ # Run the given method (or other check) with the given args (if applicable)
50
+ :self.equal?(method) &? (
51
+ # Do nothing; let the self pass through to result checking.
52
+ ) ?? (method.is_a?(Symbol) &? (
53
+ args.each |arg| { g.push_literal_or_array(arg) }
54
+ g.send(method, args.size)
55
+ ) ?? (method.is_a?(Proc) &? (
56
+ code = method.block.compiled_code
57
+ g.push_literal(code) # TODO: add a move_up instruction and avoid all of these swap_stacks
58
+ g.swap_stack; g.push_literal(code.name) # name
59
+ g.swap_stack; g.push_cpath_top; g.find_const(:Myco) # module
60
+ g.swap_stack # receiver (the item)
61
+ g.push_literal_array(args) # args
62
+ g.push_nil # block
63
+ g.send(:invoke, 5)
64
+ ) ?? (
65
+ raise("Unknown type of check method: "method"")
66
+ )))
67
+
68
+ # Compare the result of the check with the given expected result
69
+ null.equal?(result) &? (
70
+ g.goto_if_not_nil(local_fail)
71
+ ) ?? ((false.equal?(result) || true.equal?(result) ||
72
+ result.is_a?(Symbol) || result.is_a?(Fixnum)) &? (
73
+ g.push_literal(result)
74
+ g.goto_if_not_equal(local_fail)
75
+ ) ?? (
76
+ g.push_literal_or_array(result)
77
+ g.send(:"==", 1)
78
+ g.goto_if_false(local_fail)
79
+ ))
80
+ }
81
+
82
+ if(many_checks) {
83
+ local_done = g.new_label
84
+ g.pop # The dup'd subject_at_idx
85
+ g.goto(local_done)
86
+
87
+ local_fail.set!
88
+ g.pop # The dup'd subject_at_idx
89
+ g.goto(g.overall_fail)
90
+
91
+ local_done.set!
92
+ }
93
+ )
94
+
95
+ g.meta_push_1
96
+ g.increment_idx
97
+ }}
98
+ }
99
+ }