thefox-ext 2.0.0 → 3.0.0.pre.rc.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +0 -1
- data/CHANGELOG-v2.md +1 -1
- data/CHANGELOG-v3.md +6 -0
- data/README.md +6 -0
- data/bin/dev +1 -4
- data/bin/test.rb +13 -0
- data/lib/thefox-ext.rb +8 -5
- data/lib/thefox-ext/range/lexer/base.rb +59 -4
- data/lib/thefox-ext/range/lexer/block.rb +10 -1
- data/lib/thefox-ext/range/lexer/block_down.rb +8 -4
- data/lib/thefox-ext/range/lexer/block_level.rb +37 -0
- data/lib/thefox-ext/range/lexer/block_up.rb +6 -4
- data/lib/thefox-ext/range/lexer/collection.rb +73 -0
- data/lib/thefox-ext/range/lexer/interval.rb +35 -26
- data/lib/thefox-ext/range/lexer/lexer.rb +39 -229
- data/lib/thefox-ext/range/lexer/number.rb +74 -27
- data/lib/thefox-ext/range/lexer/range.rb +37 -13
- data/lib/thefox-ext/range/lexer/scope.rb +257 -0
- data/lib/thefox-ext/range/lexer/separator.rb +1 -1
- data/lib/thefox-ext/range/resolver.rb +3 -9
- data/lib/thefox-ext/version.rb +2 -2
- data/thefox-ext.gemspec +3 -1
- metadata +37 -6
- data/lib/thefox-ext/range/lexer/block_stack.rb +0 -44
@@ -1,37 +1,33 @@
|
|
1
1
|
|
2
|
-
require 'pp'
|
3
|
-
|
4
2
|
module TheFox
|
5
3
|
module Range
|
6
4
|
module Lexer
|
7
5
|
class Lexer
|
8
6
|
def initialize(chars)
|
9
|
-
# puts '->
|
7
|
+
# puts '-> Lexer2.initialize'
|
10
8
|
@chars = chars
|
11
|
-
# pp @chars
|
12
9
|
end
|
13
10
|
|
14
11
|
def resolve()
|
15
12
|
# puts
|
16
|
-
# puts '->
|
13
|
+
# puts '-> Lexer2.resolve L1 [Create Object for each character]'
|
17
14
|
|
15
|
+
block_level = BlockLevel.new
|
16
|
+
item_collection1 = Collection.new
|
18
17
|
position = 0
|
19
|
-
prev_item = nil
|
20
|
-
block_level = 0
|
21
|
-
items1 = []
|
22
18
|
@chars.each do |char|
|
23
19
|
position += 1
|
24
|
-
|
25
20
|
curr_item = case char
|
26
|
-
when '
|
21
|
+
when ' '
|
22
|
+
# Skip space
|
23
|
+
when "\r"
|
24
|
+
# Skip
|
25
|
+
when ',', "\n"
|
27
26
|
Separator.new()
|
28
27
|
when '{'
|
29
|
-
block_level += 1
|
30
28
|
BlockDown.new(block_level)
|
31
29
|
when '}'
|
32
|
-
|
33
|
-
block_level -= 1
|
34
|
-
BlockUp.new(org_level)
|
30
|
+
BlockUp.new(block_level)
|
35
31
|
when '+'
|
36
32
|
Operator.new()
|
37
33
|
when '-', '.'
|
@@ -41,242 +37,56 @@ module Lexer
|
|
41
37
|
when '0'..'9'
|
42
38
|
Number.new(char)
|
43
39
|
else
|
44
|
-
raise 'Unknown character at position %d: %s' % [
|
40
|
+
raise 'Unknown character at position %d: "%s" (ord=%d)' % [
|
41
|
+
position, char, char.ord
|
42
|
+
]
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
prev_item.chain(curr_item)
|
49
|
-
end
|
50
|
-
items1.push(curr_item)
|
51
|
-
prev_item = curr_item
|
45
|
+
item_collection1.push(curr_item)
|
52
46
|
end
|
53
47
|
|
54
|
-
#
|
48
|
+
# puts '-> Lexer2.resolve L1 Items'
|
49
|
+
# pp item_collection1.items.map{ |item| item.inspect }
|
55
50
|
|
56
51
|
# puts
|
57
|
-
# puts '->
|
58
|
-
|
59
|
-
|
60
|
-
items2 = []
|
61
|
-
items1.each do |item|
|
52
|
+
# puts '-> Lexer2.resolve L2 [Append Number]'
|
53
|
+
item_collection2 = Collection.new
|
54
|
+
item_collection1.items.each do |item|
|
62
55
|
# puts '--> L2 item: %s' % [item.inspect]
|
63
56
|
|
64
|
-
append_dup = false
|
65
|
-
|
66
57
|
case item
|
67
58
|
when Number
|
68
|
-
if
|
69
|
-
|
70
|
-
curr_item = item.dup
|
71
|
-
if !prev_item.nil?
|
72
|
-
prev_item.chain(curr_item)
|
73
|
-
end
|
74
|
-
items2.push(curr_item)
|
75
|
-
prev_item = curr_item
|
59
|
+
if item_collection2.curr.is_a?(Number)
|
60
|
+
item_collection2.curr.append(item)
|
76
61
|
else
|
77
|
-
|
78
|
-
if curr_item.is_a?(Number)
|
79
|
-
curr_item.append(item.char)
|
80
|
-
else
|
81
|
-
raise 'Do not know what to do'
|
82
|
-
end
|
62
|
+
item_collection2.push(item)
|
83
63
|
end
|
84
64
|
when Range
|
85
|
-
|
86
|
-
|
65
|
+
# puts '--> L2 Its Range: %s %s %s %s %s' % [
|
66
|
+
# item.inspect,
|
67
|
+
# item_collection2.curr.inspect,
|
68
|
+
# item_collection2.curr.is_a?(Range) ? 'Y' : 'n',
|
69
|
+
# item_collection2.curr.symbole == '.' ? 'Y' : 'n',
|
70
|
+
# item.symbole == '.' ? 'Y' : 'n',
|
71
|
+
# ]
|
72
|
+
if item_collection2.curr.is_a?(Range) && item_collection2.curr.symbole == '.' && item.symbole == '.'
|
73
|
+
# puts '--> L2 Skip'
|
87
74
|
else
|
88
|
-
|
75
|
+
item_collection2.push(item)
|
89
76
|
end
|
90
77
|
else
|
91
78
|
# puts '--> L2 ELSE'
|
79
|
+
item_collection2.push(item)
|
80
|
+
end # case item
|
92
81
|
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
if append_dup
|
97
|
-
curr_item = item.dup
|
98
|
-
if !prev_item.nil?
|
99
|
-
prev_item.chain(curr_item)
|
100
|
-
end
|
101
|
-
items2.push(curr_item)
|
102
|
-
prev_item = curr_item
|
103
|
-
|
104
|
-
curr_item = nil
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
# pp items2.map{ |item| item.inspect }
|
109
|
-
|
110
|
-
# puts
|
111
|
-
# puts '-> Lexer.resolve L3'
|
112
|
-
append_dub_f = nil
|
113
|
-
append_prev_f = nil
|
114
|
-
prev_item = nil
|
115
|
-
block_stack = BlockStack.new
|
116
|
-
items3 = []
|
117
|
-
items2.each do |item|
|
118
|
-
# puts '--> L3 %20s bs=%d' % [item.inspect, block_stack.length]
|
119
|
-
|
120
|
-
append_dup = false
|
121
|
-
append_prev = false
|
122
|
-
|
123
|
-
case item
|
124
|
-
when Number
|
125
|
-
if item.next_item.is_a?(Range) || item.prev_item.is_a?(Range) || item.prev_item.is_a?(Interval)
|
126
|
-
# skip
|
127
|
-
else
|
128
|
-
append_dup = true
|
129
|
-
end
|
130
|
-
when Range
|
131
|
-
if item.prev_item.is_a?(Number) && item.next_item.is_a?(Number)
|
132
|
-
# puts '--> Range normal'
|
133
|
-
append_dub_f = -> (curr_item){
|
134
|
-
curr_item.left_item = item.prev_item.dup
|
135
|
-
curr_item.right_item = item.next_item.dup
|
136
|
-
|
137
|
-
curr_item.left_item.parent_item = block_stack.curr
|
138
|
-
curr_item.right_item.parent_item = block_stack.curr
|
139
|
-
|
140
|
-
block_stack.add_child(curr_item.left_item)
|
141
|
-
block_stack.add_child(curr_item.right_item)
|
142
|
-
}
|
143
|
-
append_dup = true
|
144
|
-
else
|
145
|
-
raise 'Invalid Range: %s %s' % [
|
146
|
-
item.prev_item.inspect,
|
147
|
-
item.next_item.inspect,
|
148
|
-
]
|
149
|
-
end
|
150
|
-
when Interval
|
151
|
-
if !item.next_item.is_a?(Number)
|
152
|
-
raise 'Invalid Interval: %s' % [item.next_item.inspect]
|
153
|
-
end
|
154
|
-
|
155
|
-
append_dub_f = ->(curr_item){ curr_item.number = item.next_item.dup }
|
156
|
-
append_dup = true
|
157
|
-
when Operator
|
158
|
-
if prev_item.is_a?(Number)
|
159
|
-
append_prev_f = -> (curr_item){ curr_item.inc }
|
160
|
-
append_prev = true
|
161
|
-
end
|
162
|
-
when BlockDown
|
163
|
-
#block_stack.push(item.dup)
|
164
|
-
append_dub_f = ->(curr_item){ block_stack.push(curr_item) }
|
165
|
-
append_dup = true
|
166
|
-
when BlockUp
|
167
|
-
block_stack.pop
|
168
|
-
append_dup = true
|
169
|
-
else
|
170
|
-
# puts '--> L3 ELSE'
|
171
|
-
append_dup = true
|
172
|
-
end
|
173
|
-
|
174
|
-
# Append Dup
|
175
|
-
if append_dup
|
176
|
-
# Dup
|
177
|
-
curr_item = item.dup
|
178
|
-
# Function
|
179
|
-
if !append_dub_f.nil?
|
180
|
-
append_dub_f.call(curr_item)
|
181
|
-
append_dub_f = nil
|
182
|
-
end
|
183
|
-
# Chain
|
184
|
-
if !prev_item.nil?
|
185
|
-
prev_item.chain(curr_item)
|
186
|
-
end
|
187
|
-
# Block
|
188
|
-
if !item.is_a?(Block)
|
189
|
-
# puts '---> set Parent: %s' % [block_stack.curr.inspect]
|
190
|
-
curr_item.parent_item = block_stack.curr
|
191
|
-
block_stack.add_child(curr_item)
|
192
|
-
end
|
193
|
-
# Append
|
194
|
-
items3.push(curr_item)
|
195
|
-
# Prev Item
|
196
|
-
prev_item = curr_item
|
197
|
-
end
|
198
|
-
|
199
|
-
# Append Prev
|
200
|
-
if append_prev && !prev_item.nil?
|
201
|
-
# Dup
|
202
|
-
curr_item = prev_item.dup
|
203
|
-
# Function
|
204
|
-
if !append_prev_f.nil?
|
205
|
-
append_prev_f.call(curr_item)
|
206
|
-
append_prev_f = nil
|
207
|
-
end
|
208
|
-
# Chain
|
209
|
-
prev_item.chain(curr_item)
|
210
|
-
# Block
|
211
|
-
if !item.is_a?(Block)
|
212
|
-
curr_item.parent_item = block_stack.curr
|
213
|
-
block_stack.add_child(curr_item)
|
214
|
-
end
|
215
|
-
# Append
|
216
|
-
items3.push(curr_item)
|
217
|
-
# Prev Item
|
218
|
-
prev_item = curr_item
|
219
|
-
end
|
220
|
-
|
221
|
-
# Block
|
222
|
-
if item.is_a?(Block)
|
223
|
-
# puts '--> L3 set parent block for block'
|
224
|
-
item.parent_item = block_stack.curr
|
225
|
-
block_stack.add_child(item)
|
226
|
-
end
|
227
|
-
end
|
82
|
+
end # item_collection1.items
|
228
83
|
|
229
|
-
#
|
84
|
+
# puts '-> Lexer2.resolve L2 Items'
|
85
|
+
# pp item_collection2.items.map{ |item| item.inspect }
|
230
86
|
|
231
87
|
# puts
|
232
|
-
|
233
|
-
|
234
|
-
items3.each do |item|
|
235
|
-
# puts '--> L4 %20s %20s c: %d' % [item.inspect, item.parent_item.inspect, item.children.length]
|
236
|
-
|
237
|
-
case item
|
238
|
-
when Number
|
239
|
-
if item.next_item.is_a?(BlockDown)
|
240
|
-
# skip
|
241
|
-
# puts '---> skip'
|
242
|
-
else
|
243
|
-
items4.push(item.char.to_i)
|
244
|
-
end
|
245
|
-
when Range
|
246
|
-
r_begin = item.left_item.char.to_i
|
247
|
-
r_end = item.right_item.char.to_i
|
248
|
-
r = ::Range.new(r_begin, r_end)
|
249
|
-
|
250
|
-
if item.next_item.is_a?(Interval)
|
251
|
-
# Interval Range
|
252
|
-
n = item.next_item.number.char.to_i
|
253
|
-
c = 0
|
254
|
-
r.each do |i|
|
255
|
-
if c == 0
|
256
|
-
items4.push(i)
|
257
|
-
end
|
258
|
-
c += 1
|
259
|
-
if c == n
|
260
|
-
c = 0
|
261
|
-
end
|
262
|
-
end
|
263
|
-
else
|
264
|
-
# Normal Range
|
265
|
-
items4.push(*r.to_a)
|
266
|
-
end
|
267
|
-
when Interval
|
268
|
-
# puts '---> skip Interval'
|
269
|
-
when Separator
|
270
|
-
# puts '---> skip Separator'
|
271
|
-
when Block
|
272
|
-
# puts '---> skip Block'
|
273
|
-
else
|
274
|
-
raise 'Implementation missing for: %s' % [item.inspect]
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
# pp items4
|
279
|
-
items4
|
88
|
+
scope = Scope.new(item_collection2.items)
|
89
|
+
scope.resolve
|
280
90
|
end
|
281
91
|
end # Lexer
|
282
92
|
end # Lexer
|
@@ -1,6 +1,4 @@
|
|
1
1
|
|
2
|
-
require 'pp'
|
3
|
-
|
4
2
|
module TheFox
|
5
3
|
module Range
|
6
4
|
module Lexer
|
@@ -9,47 +7,96 @@ module Lexer
|
|
9
7
|
def initialize(char)
|
10
8
|
super()
|
11
9
|
# puts '-> Number.initialize(%s)' % [char]
|
10
|
+
#@nonce = rand(10 ** 3).to_s.rjust(3, '0')
|
12
11
|
@char = char
|
12
|
+
@is_ref_item = false
|
13
13
|
end
|
14
14
|
|
15
15
|
# :nocov:
|
16
16
|
def inspect()
|
17
|
-
|
17
|
+
a = [
|
18
|
+
# '#' + @nonce.to_s,
|
19
|
+
# 'c' + @char,
|
20
|
+
@char,
|
21
|
+
]
|
22
|
+
if !@parent_item.nil?
|
23
|
+
a.push('^%s' % @parent_item.inspect)
|
24
|
+
end
|
25
|
+
a.push('IRI=%d' % [@is_ref_item])
|
26
|
+
# if @children.length > 0
|
27
|
+
# a.push('v%d' % @children.length)
|
28
|
+
# end
|
29
|
+
'Number(%s)' % [a.join(' ')]
|
30
|
+
end
|
31
|
+
def dup()
|
32
|
+
# puts '-> Number.dup(%s) -> %s %s' % [@char, inspect, self.is_ref_item ? 'Y' : 'n']
|
33
|
+
# puts '-> %s.dup' % [inspect]
|
34
|
+
o = super()
|
35
|
+
o.is_ref_item = self.is_ref_item
|
36
|
+
# puts '-> Number.dup(%s) -> %s' % [@char, o.inspect]
|
37
|
+
o
|
18
38
|
end
|
19
39
|
# :nocov:
|
20
40
|
|
21
|
-
def char
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
raise 'Parent Prev item for %s is not a Block: %s' % [
|
32
|
-
self.inspect,
|
33
|
-
self.parent_item.prev_item.inspect,
|
34
|
-
]
|
35
|
-
end
|
36
|
-
else
|
37
|
-
raise 'Parent item for %s is not a Block: %s' % [self.inspect, self.parent_item.inspect]
|
38
|
-
end
|
39
|
-
else
|
40
|
-
# puts '-> %s.char char' % [self.inspect]
|
41
|
-
@char
|
42
|
-
end
|
41
|
+
def char
|
42
|
+
@char
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_ref_item
|
46
|
+
@is_ref_item
|
47
|
+
end
|
48
|
+
def is_ref_item=(is_ref_item)
|
49
|
+
@is_ref_item = is_ref_item
|
43
50
|
end
|
44
51
|
|
45
|
-
def append(
|
46
|
-
|
52
|
+
def append(obj)
|
53
|
+
if obj.is_a?(Number)
|
54
|
+
self.append(obj.char)
|
55
|
+
else
|
56
|
+
@char += obj
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
49
60
|
def inc()
|
50
61
|
f = '%%0%dd' % [@char.length]
|
51
62
|
@char = f % [@char.to_i + 1]
|
52
63
|
end
|
64
|
+
|
65
|
+
def resolve(level = 0)
|
66
|
+
# puts '-> %s.resolve(%d)' % [self.inspect, @char, level]
|
67
|
+
if self.has_parent_item
|
68
|
+
if @parent_item.is_a?(Number)
|
69
|
+
('%s%s' % [@parent_item.resolve(level + 1), @char]).to_i
|
70
|
+
elsif @parent_item.is_a?(Scope)
|
71
|
+
curr_item = @parent_item
|
72
|
+
stack = [@char]
|
73
|
+
while !curr_item.parent_scope.nil? do
|
74
|
+
# puts '-----> CI=%s RI=%s' % [curr_item.inspect, curr_item.ref_item.inspect]
|
75
|
+
|
76
|
+
if !curr_item.ref_item.nil?
|
77
|
+
stack.push(curr_item.ref_item.char)
|
78
|
+
end
|
79
|
+
curr_item = curr_item.parent_scope
|
80
|
+
end
|
81
|
+
|
82
|
+
# pp stack.reverse
|
83
|
+
|
84
|
+
stack.reverse.join.to_i
|
85
|
+
|
86
|
+
# if @char == '5'
|
87
|
+
# 2102
|
88
|
+
# else
|
89
|
+
# 9999
|
90
|
+
# end
|
91
|
+
elsif @parent_item.is_a?(Interval)
|
92
|
+
@char.to_i
|
93
|
+
else
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
else
|
97
|
+
@char.to_i
|
98
|
+
end
|
99
|
+
end
|
53
100
|
end # Number
|
54
101
|
end # Lexer
|
55
102
|
end # Range
|
@@ -2,7 +2,7 @@
|
|
2
2
|
module TheFox
|
3
3
|
module Range
|
4
4
|
module Lexer
|
5
|
-
# -
|
5
|
+
# - ..
|
6
6
|
class Range < Base
|
7
7
|
def initialize(symbole)
|
8
8
|
super(symbole)
|
@@ -10,31 +10,55 @@ module Lexer
|
|
10
10
|
|
11
11
|
@left_item = nil
|
12
12
|
@right_item = nil
|
13
|
+
@interval = nil
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
# :nocov:
|
17
|
+
def inspect()
|
18
|
+
if !@left_item.nil? && !@right_item.nil?
|
19
|
+
'Range(#%s s=%s l=%s r=%s i=%s)' % [
|
20
|
+
@nonce,
|
21
|
+
@symbole,
|
22
|
+
@left_item.inspect,
|
23
|
+
@right_item.inspect,
|
24
|
+
@interval.inspect
|
25
|
+
]
|
26
|
+
else
|
27
|
+
'Range(#%s %s)' % [@nonce, @symbole]
|
28
|
+
end
|
17
29
|
end
|
30
|
+
# :nocov:
|
31
|
+
|
18
32
|
def left_item=(left_item)
|
19
|
-
@left_item = left_item
|
33
|
+
@left_item = left_item.dup
|
20
34
|
end
|
21
35
|
|
36
|
+
def right_item=(right_item)
|
37
|
+
@right_item = right_item.dup
|
38
|
+
end
|
22
39
|
def right_item()
|
23
40
|
@right_item
|
24
41
|
end
|
25
|
-
|
26
|
-
|
42
|
+
|
43
|
+
def interval()
|
44
|
+
@interval
|
45
|
+
end
|
46
|
+
def interval=(interval)
|
47
|
+
@interval = interval.dup
|
27
48
|
end
|
28
49
|
|
29
|
-
|
30
|
-
|
31
|
-
if
|
32
|
-
|
33
|
-
|
34
|
-
|
50
|
+
def resolve()
|
51
|
+
# puts '-> %s.resolve()'.colorize(:red) % [inspect]
|
52
|
+
if @left_item.is_a?(Number) && @right_item.is_a?(Number)
|
53
|
+
r = ::Range.new(@left_item.resolve, @right_item.resolve)
|
54
|
+
if @interval.is_a?(Interval)
|
55
|
+
# puts '--> I=%s'.colorize(:red) % [@interval.inspect]
|
56
|
+
r = r.step(@interval.resolve)
|
57
|
+
end
|
58
|
+
# puts '--> %s'.colorize(:red) % [r.inspect]
|
59
|
+
r.to_a
|
35
60
|
end
|
36
61
|
end
|
37
|
-
# :nocov:
|
38
62
|
end # Range
|
39
63
|
end # Lexer
|
40
64
|
end # Range
|