@@ -5,9 +5,68 @@ def compile(map, _:nil)
55 self
66 end
77
8- def call ( str , stage = :main )
8+ def call ( str , stage = :main , each : false , & block )
99 stage = @map . stages [ stage ]
10- Stage . new ( @map , str ) . execute_rule ( stage )
10+ s =
11+ if each
12+ e = Enumerator . new do |yielder |
13+ options = [ ]
14+ options_set = false
15+ choices = nil
16+
17+ i = 0
18+
19+ loop do
20+ result = nil
21+
22+ f = Fiber . new do
23+ $select_nth_string = true
24+ result = Stage . new ( @map , str ) . execute_rule ( stage )
25+ $select_nth_string = false
26+ Fiber . yield ( :end )
27+ end
28+
29+ iter = 0
30+
31+ loop do
32+ break if f . resume == :end
33+ # hash is unused for now... some problems may arise in certain
34+ # scenarios that are not a danger right now, but i'm genuinely
35+ # unsure how it can be handled.
36+ #
37+ # This scenario is described in a commented out test.
38+ type , value , hash = f . resume
39+ if options_set
40+ f . resume ( choices [ i ] [ iter ] )
41+ else
42+ options [ iter ] = value
43+ f . resume ( 0 )
44+ end
45+ iter += 1
46+ end
47+
48+ unless options_set
49+ options_set = true
50+
51+ opts = options . map { |i | ( 0 ...i ) . to_a }
52+ choices = opts [ 0 ] . product ( *opts [ 1 ..-1 ] )
53+ end
54+
55+ yielder . yield ( result )
56+
57+ i += 1
58+ break if i == choices . length
59+ end
60+ end
61+
62+ if block_given?
63+ e . each ( &block )
64+ else
65+ e
66+ end
67+ else
68+ Stage . new ( @map , str ) . execute_rule ( stage )
69+ end
1170 end
1271
1372 class Stage
@@ -106,7 +165,7 @@ def build_regexp(r)
106165 end
107166
108167 def build_item i , target = nil , doc = @map
109- i = i . first_string if %i[ str parstr ] . include? target
168+ i = i . nth_string if %i[ str parstr ] . include? target
110169 i = Interscript ::Node ::Item . try_convert ( i )
111170 target = :par if target == :parstr
112171
0 commit comments