language-ruby 0.5.6 → 0.6.1
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/.gitignore +0 -1
- data/.ruby-version +1 -0
- data/.tool-versions +1 -1
- data/Gemfile +5 -4
- data/Gemfile.lock +12 -23
- data/README.md +2 -102
- data/language-ruby.gemspec +7 -5
- data/lib/language/atom/absent.rb +29 -0
- data/lib/language/atom/aka.rb +32 -0
- data/lib/language/atom/and.rb +32 -0
- data/lib/language/atom/any.rb +15 -0
- data/lib/language/atom/ignore.rb +27 -0
- data/lib/language/atom/maybe.rb +32 -0
- data/lib/language/atom/or.rb +46 -0
- data/lib/language/atom/repeat.rb +57 -0
- data/lib/language/atom/str.rb +21 -0
- data/lib/language/atom/then.rb +21 -0
- data/lib/language/atom.rb +10 -291
- data/lib/language/output.rb +13 -11
- data/lib/language/parser/absent/present.rb +2 -0
- data/lib/language/parser/absent.rb +2 -0
- data/lib/language/parser/end_of_input.rb +2 -0
- data/lib/language/parser/interuption.rb +2 -0
- data/lib/language/parser/not_end_of_input.rb +2 -0
- data/lib/language/parser/str/not_found.rb +2 -0
- data/lib/language/parser/str.rb +2 -0
- data/lib/language/parser.rb +10 -10
- data/lib/language/version.rb +5 -0
- data/lib/language-ruby.rb +2 -5
- data/lib/language.rb +9 -7
- data/spec/language_spec.rb +21 -0
- data/spec/spec_helper.rb +2 -5
- metadata +18 -218
- data/.cherry.js +0 -21
- data/.editorconfig +0 -9
- data/.github/workflows/rspec.yml +0 -14
- data/.prettierrc +0 -3
- data/CHANGELOG.md +0 -55
- data/LICENSE +0 -7
- data/TODO +0 -17
- data/bin/code +0 -76
- data/bin/format +0 -3
- data/bin/publish +0 -19
- data/bin/template +0 -85
- data/bin/test +0 -17
- data/code-ruby.gemspec +0 -17
- data/docs/class.code +0 -9
- data/docs/euler/1.template +0 -10
- data/docs/euler/2.template +0 -16
- data/docs/euler/3.template +0 -16
- data/docs/euler/4.template +0 -10
- data/docs/euler/5.template +0 -13
- data/docs/fibonnaci.template +0 -14
- data/docs/meetup.code +0 -12
- data/docs/precedence.template +0 -36
- data/docs/rain.code +0 -22
- data/docs/slack.code +0 -17
- data/docs/stripe.code +0 -7
- data/docs/twitter.code +0 -9
- data/lib/code/error.rb +0 -18
- data/lib/code/node/base_10.rb +0 -29
- data/lib/code/node/base_16.rb +0 -13
- data/lib/code/node/base_2.rb +0 -13
- data/lib/code/node/base_8.rb +0 -13
- data/lib/code/node/boolean.rb +0 -22
- data/lib/code/node/call.rb +0 -47
- data/lib/code/node/call_argument.rb +0 -21
- data/lib/code/node/chained_call.rb +0 -23
- data/lib/code/node/code.rb +0 -20
- data/lib/code/node/decimal.rb +0 -26
- data/lib/code/node/dictionnary.rb +0 -33
- data/lib/code/node/equal.rb +0 -34
- data/lib/code/node/function.rb +0 -20
- data/lib/code/node/function_parameter.rb +0 -31
- data/lib/code/node/if.rb +0 -59
- data/lib/code/node/if_modifier.rb +0 -47
- data/lib/code/node/list.rb +0 -16
- data/lib/code/node/negation.rb +0 -15
- data/lib/code/node/not.rb +0 -15
- data/lib/code/node/nothing.rb +0 -12
- data/lib/code/node/number.rb +0 -25
- data/lib/code/node/operation.rb +0 -38
- data/lib/code/node/power.rb +0 -20
- data/lib/code/node/rescue.rb +0 -17
- data/lib/code/node/splat.rb +0 -15
- data/lib/code/node/statement.rb +0 -59
- data/lib/code/node/string.rb +0 -53
- data/lib/code/node/ternary.rb +0 -24
- data/lib/code/node/unary_minus.rb +0 -15
- data/lib/code/node/while.rb +0 -35
- data/lib/code/node.rb +0 -13
- data/lib/code/object/argument.rb +0 -32
- data/lib/code/object/boolean.rb +0 -27
- data/lib/code/object/decimal.rb +0 -162
- data/lib/code/object/dictionnary.rb +0 -96
- data/lib/code/object/function.rb +0 -64
- data/lib/code/object/global.rb +0 -42
- data/lib/code/object/integer.rb +0 -221
- data/lib/code/object/list.rb +0 -207
- data/lib/code/object/nothing.rb +0 -23
- data/lib/code/object/number.rb +0 -6
- data/lib/code/object/range.rb +0 -146
- data/lib/code/object/ruby_function.rb +0 -31
- data/lib/code/object/string.rb +0 -102
- data/lib/code/object.rb +0 -197
- data/lib/code/parser/addition.rb +0 -21
- data/lib/code/parser/and_operator.rb +0 -17
- data/lib/code/parser/bitwise_and.rb +0 -17
- data/lib/code/parser/bitwise_or.rb +0 -21
- data/lib/code/parser/boolean.rb +0 -17
- data/lib/code/parser/call.rb +0 -122
- data/lib/code/parser/chained_call.rb +0 -47
- data/lib/code/parser/class.rb +0 -45
- data/lib/code/parser/code.rb +0 -25
- data/lib/code/parser/dictionnary.rb +0 -67
- data/lib/code/parser/equal.rb +0 -94
- data/lib/code/parser/equality.rb +0 -35
- data/lib/code/parser/equality_lower.rb +0 -9
- data/lib/code/parser/function.rb +0 -85
- data/lib/code/parser/greater.rb +0 -25
- data/lib/code/parser/group.rb +0 -22
- data/lib/code/parser/if.rb +0 -63
- data/lib/code/parser/if_modifier.rb +0 -55
- data/lib/code/parser/list.rb +0 -42
- data/lib/code/parser/multiplication.rb +0 -25
- data/lib/code/parser/name.rb +0 -107
- data/lib/code/parser/negation.rb +0 -30
- data/lib/code/parser/not_keyword.rb +0 -23
- data/lib/code/parser/nothing.rb +0 -22
- data/lib/code/parser/number.rb +0 -154
- data/lib/code/parser/operation.rb +0 -35
- data/lib/code/parser/or_keyword.rb +0 -21
- data/lib/code/parser/or_operator.rb +0 -17
- data/lib/code/parser/power.rb +0 -43
- data/lib/code/parser/range.rb +0 -17
- data/lib/code/parser/rescue.rb +0 -39
- data/lib/code/parser/shift.rb +0 -21
- data/lib/code/parser/splat.rb +0 -31
- data/lib/code/parser/statement.rb +0 -9
- data/lib/code/parser/string.rb +0 -78
- data/lib/code/parser/ternary.rb +0 -46
- data/lib/code/parser/unary_minus.rb +0 -31
- data/lib/code/parser/while.rb +0 -36
- data/lib/code/parser/whitespace.rb +0 -49
- data/lib/code/parser.rb +0 -19
- data/lib/code/ruby.rb +0 -174
- data/lib/code-ruby.rb +0 -10
- data/lib/code.rb +0 -47
- data/lib/template/node/code_part.rb +0 -13
- data/lib/template/node/part.rb +0 -19
- data/lib/template/node/template.rb +0 -15
- data/lib/template/node/text_part.rb +0 -13
- data/lib/template/node.rb +0 -4
- data/lib/template/parser/template.rb +0 -39
- data/lib/template/parser.rb +0 -19
- data/lib/template/version.rb +0 -3
- data/lib/template-ruby.rb +0 -10
- data/lib/template.rb +0 -50
- data/spec/code/addition_spec.rb +0 -13
- data/spec/code/and_operator_spec.rb +0 -13
- data/spec/code/bitwise_and_spec.rb +0 -13
- data/spec/code/bitwise_or_spec.rb +0 -13
- data/spec/code/boolean_spec.rb +0 -13
- data/spec/code/call_spec.rb +0 -21
- data/spec/code/chained_call_spec.rb +0 -16
- data/spec/code/code_spec.rb +0 -29
- data/spec/code/dictionnary_spec.rb +0 -17
- data/spec/code/equal_spec.rb +0 -26
- data/spec/code/equality_spec.rb +0 -13
- data/spec/code/function_spec.rb +0 -18
- data/spec/code/greater_spec.rb +0 -18
- data/spec/code/group_spec.rb +0 -12
- data/spec/code/if_modifier_spec.rb +0 -20
- data/spec/code/if_spec.rb +0 -25
- data/spec/code/list_spec.rb +0 -19
- data/spec/code/multiplication_spec.rb +0 -18
- data/spec/code/negation_spec.rb +0 -20
- data/spec/code/not_keyword_spec.rb +0 -13
- data/spec/code/nothing_spec.rb +0 -17
- data/spec/code/number_spec.rb +0 -22
- data/spec/code/or_keyword_spec.rb +0 -17
- data/spec/code/or_operator_spec.rb +0 -16
- data/spec/code/parser/boolean_spec.rb +0 -16
- data/spec/code/parser/call_spec.rb +0 -26
- data/spec/code/parser/chained_call.rb +0 -17
- data/spec/code/parser/dictionnary_spec.rb +0 -18
- data/spec/code/parser/function_spec.rb +0 -16
- data/spec/code/parser/group_spec.rb +0 -18
- data/spec/code/parser/list_spec.rb +0 -18
- data/spec/code/parser/number_spec.rb +0 -12
- data/spec/code/parser/string_spec.rb +0 -21
- data/spec/code/parser_spec.rb +0 -23
- data/spec/code/power_spec.rb +0 -13
- data/spec/code/range_spec.rb +0 -16
- data/spec/code/rescue_spec.rb +0 -13
- data/spec/code/shift_spec.rb +0 -13
- data/spec/code/splat_spec.rb +0 -13
- data/spec/code/string_spec.rb +0 -27
- data/spec/code/ternary_spec.rb +0 -18
- data/spec/code/unary_minus_spec.rb +0 -13
- data/spec/code/while_spec.rb +0 -18
- data/template-ruby.gemspec +0 -19
data/lib/language/atom.rb
CHANGED
@@ -1,290 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Language
|
2
4
|
class Atom
|
3
|
-
class Rule < Atom
|
4
|
-
def initialize(name:)
|
5
|
-
@name = name
|
6
|
-
end
|
7
|
-
|
8
|
-
def parse(parser)
|
9
|
-
parser.find_rule!(@name).parse(parser)
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
"rule(#{@name.inspect})"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class Any < Atom
|
18
|
-
def parse(parser)
|
19
|
-
parser.consume(1)
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
"any"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class Then < Atom
|
28
|
-
def initialize(parent:, block:)
|
29
|
-
@parent = parent
|
30
|
-
@block = block
|
31
|
-
end
|
32
|
-
|
33
|
-
def parse(parser)
|
34
|
-
@parent.parse(parser)
|
35
|
-
parser.output = Output.from_raw(@block.call(parser.output.to_raw))
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_s
|
39
|
-
"(#{@parent}).then {}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class Repeat < Atom
|
44
|
-
def initialize(parent: nil, min: 0, max: nil)
|
45
|
-
@parent = parent
|
46
|
-
@min = min
|
47
|
-
@max = max
|
48
|
-
end
|
49
|
-
|
50
|
-
def parse(parser)
|
51
|
-
return unless @parent
|
52
|
-
|
53
|
-
if @max.nil?
|
54
|
-
@min.times { match(parser) }
|
55
|
-
|
56
|
-
begin
|
57
|
-
loop { match(parser) }
|
58
|
-
rescue Parser::Interuption
|
59
|
-
end
|
60
|
-
else
|
61
|
-
@min.times { match(parser) }
|
62
|
-
|
63
|
-
begin
|
64
|
-
(@max - @min).times { match(parser) }
|
65
|
-
rescue Parser::Interuption
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def to_s
|
71
|
-
min = @min.zero? ? "" : @min.to_s
|
72
|
-
max = @max.nil? ? "" : ", #{@max}"
|
73
|
-
parenthesis = min.empty? && max.empty? ? "" : "(#{min}#{max})"
|
74
|
-
|
75
|
-
@parent ? "(#{@parent}).repeat#{parenthesis}" : "repeat#{parenthesis}"
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def match(parser)
|
81
|
-
clone =
|
82
|
-
Parser.new(
|
83
|
-
root: self,
|
84
|
-
input: parser.input,
|
85
|
-
cursor: parser.cursor,
|
86
|
-
buffer: parser.buffer
|
87
|
-
)
|
88
|
-
|
89
|
-
@parent.parse(clone)
|
90
|
-
|
91
|
-
parser.cursor = clone.cursor
|
92
|
-
parser.buffer = clone.buffer
|
93
|
-
parser.output << clone.output
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
class Str < Atom
|
98
|
-
def initialize(string:)
|
99
|
-
@string = string
|
100
|
-
end
|
101
|
-
|
102
|
-
def parse(parser)
|
103
|
-
if parser.next?(@string)
|
104
|
-
parser.consume(@string.size)
|
105
|
-
else
|
106
|
-
raise Parser::Str::NotFound.new(parser, @string)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def to_s
|
111
|
-
"str(#{@string.inspect})"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class Absent < Atom
|
116
|
-
def initialize(parent: nil)
|
117
|
-
@parent = parent
|
118
|
-
end
|
119
|
-
|
120
|
-
def parse(parser)
|
121
|
-
clone =
|
122
|
-
Parser.new(
|
123
|
-
root: self,
|
124
|
-
input: parser.input,
|
125
|
-
cursor: parser.cursor,
|
126
|
-
buffer: parser.buffer
|
127
|
-
)
|
128
|
-
@parent.parse(clone) if @parent
|
129
|
-
rescue Parser::Interuption
|
130
|
-
else
|
131
|
-
raise Parser::Interuption.new(parser, self)
|
132
|
-
end
|
133
|
-
|
134
|
-
def to_s
|
135
|
-
@parent ? "(#{@parent}).absent" : "absent"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class Ignore < Atom
|
140
|
-
def initialize(parent: nil)
|
141
|
-
@parent = parent
|
142
|
-
end
|
143
|
-
|
144
|
-
def parse(parser)
|
145
|
-
clone =
|
146
|
-
Parser.new(
|
147
|
-
root: self,
|
148
|
-
input: parser.input,
|
149
|
-
cursor: parser.cursor,
|
150
|
-
buffer: parser.buffer
|
151
|
-
)
|
152
|
-
@parent.parse(clone) if @parent
|
153
|
-
parser.cursor = clone.cursor
|
154
|
-
end
|
155
|
-
|
156
|
-
def to_s
|
157
|
-
@parent ? "#{@parent}.ignore" : "ignore"
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
class Maybe < Atom
|
162
|
-
def initialize(parent:)
|
163
|
-
@parent = parent
|
164
|
-
end
|
165
|
-
|
166
|
-
def parse(parser)
|
167
|
-
clone =
|
168
|
-
Parser.new(
|
169
|
-
root: self,
|
170
|
-
input: parser.input,
|
171
|
-
cursor: parser.cursor,
|
172
|
-
buffer: parser.buffer
|
173
|
-
)
|
174
|
-
|
175
|
-
@parent.parse(clone)
|
176
|
-
rescue Parser::Interuption
|
177
|
-
else
|
178
|
-
parser.cursor = clone.cursor
|
179
|
-
parser.output = clone.output
|
180
|
-
end
|
181
|
-
|
182
|
-
def to_s
|
183
|
-
@parent ? "#{@parent}.maybe" : "maybe"
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
class Aka < Atom
|
188
|
-
def initialize(name:, parent:)
|
189
|
-
@name = name
|
190
|
-
@parent = parent
|
191
|
-
end
|
192
|
-
|
193
|
-
def parse(parser)
|
194
|
-
clone =
|
195
|
-
Parser.new(root: self, input: parser.input, cursor: parser.cursor)
|
196
|
-
|
197
|
-
@parent.parse(clone)
|
198
|
-
|
199
|
-
if clone.output?
|
200
|
-
parser.output = Output.new(@name => clone.output)
|
201
|
-
else
|
202
|
-
parser.output[@name] = Output.new(clone.buffer)
|
203
|
-
parser.buffer = ""
|
204
|
-
end
|
205
|
-
|
206
|
-
parser.cursor = clone.cursor
|
207
|
-
end
|
208
|
-
|
209
|
-
def to_s
|
210
|
-
@parent ? "#{@parent}.aka(#{@name.inspect})" : "aka(#{@name.inspect})"
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
class Or < Atom
|
215
|
-
def initialize(left:, right:)
|
216
|
-
@left = left
|
217
|
-
@right = right
|
218
|
-
end
|
219
|
-
|
220
|
-
def parse(parser)
|
221
|
-
left_clone =
|
222
|
-
Parser.new(
|
223
|
-
root: self,
|
224
|
-
input: parser.input,
|
225
|
-
cursor: parser.cursor,
|
226
|
-
buffer: parser.buffer
|
227
|
-
)
|
228
|
-
|
229
|
-
right_clone =
|
230
|
-
Parser.new(
|
231
|
-
root: self,
|
232
|
-
input: parser.input,
|
233
|
-
cursor: parser.cursor,
|
234
|
-
buffer: parser.buffer
|
235
|
-
)
|
236
|
-
|
237
|
-
begin
|
238
|
-
@left.parse(left_clone)
|
239
|
-
parser.cursor = left_clone.cursor
|
240
|
-
parser.buffer = left_clone.buffer
|
241
|
-
parser.output.merge(left_clone.output)
|
242
|
-
rescue Parser::Interuption
|
243
|
-
@right.parse(right_clone)
|
244
|
-
parser.cursor = right_clone.cursor
|
245
|
-
parser.buffer = right_clone.buffer
|
246
|
-
parser.output.merge(right_clone.output)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def to_s
|
251
|
-
"((#{@left}) | (#{@right}))"
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
class And < Atom
|
256
|
-
def initialize(left:, right:)
|
257
|
-
@left = left
|
258
|
-
@right = right
|
259
|
-
end
|
260
|
-
|
261
|
-
def parse(parser)
|
262
|
-
@left.parse(parser)
|
263
|
-
right_clone =
|
264
|
-
Parser.new(
|
265
|
-
root: self,
|
266
|
-
input: parser.input,
|
267
|
-
cursor: parser.cursor,
|
268
|
-
buffer: parser.buffer
|
269
|
-
)
|
270
|
-
@right.parse(right_clone)
|
271
|
-
parser.cursor = right_clone.cursor
|
272
|
-
parser.buffer = right_clone.buffer
|
273
|
-
|
274
|
-
parser.output.merge(right_clone.output)
|
275
|
-
end
|
276
|
-
|
277
|
-
def to_s
|
278
|
-
"#{@left} >> #{@right}".to_s
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
5
|
def any
|
283
6
|
Any.new
|
284
7
|
end
|
285
8
|
|
286
9
|
def str(string)
|
287
|
-
Str.new(string:
|
10
|
+
Str.new(string:)
|
288
11
|
end
|
289
12
|
|
290
13
|
def absent
|
@@ -299,12 +22,12 @@ class Language
|
|
299
22
|
Maybe.new(parent: self)
|
300
23
|
end
|
301
24
|
|
302
|
-
def repeat(
|
303
|
-
Repeat.new(parent: self,
|
25
|
+
def repeat(minimum = 0, maximum = nil)
|
26
|
+
Repeat.new(parent: self, minimum:, maximum:)
|
304
27
|
end
|
305
28
|
|
306
29
|
def aka(name)
|
307
|
-
Aka.new(parent: self, name:
|
30
|
+
Aka.new(parent: self, name:)
|
308
31
|
end
|
309
32
|
|
310
33
|
def |(other)
|
@@ -320,19 +43,15 @@ class Language
|
|
320
43
|
end
|
321
44
|
|
322
45
|
def then(&block)
|
323
|
-
Then.new(parent: self, block:
|
324
|
-
end
|
325
|
-
|
326
|
-
def rule(name)
|
327
|
-
Rule.new(name: name)
|
46
|
+
Then.new(parent: self, block:)
|
328
47
|
end
|
329
48
|
|
330
|
-
def parse(
|
331
|
-
raise NotImplementedError
|
49
|
+
def parse(_parser)
|
50
|
+
raise NotImplementedError, "#{self.class}#parse"
|
332
51
|
end
|
333
52
|
|
334
53
|
def to_s
|
335
|
-
""
|
54
|
+
raise NotImplementedError, "#{self.class}#parse"
|
336
55
|
end
|
337
56
|
|
338
57
|
def inspect
|
data/lib/language/output.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Language
|
2
4
|
class Output
|
3
5
|
attr_reader :raw
|
@@ -10,7 +12,7 @@ class Language
|
|
10
12
|
if raw.is_a?(Array)
|
11
13
|
new(raw.map { |element| from_raw(element) })
|
12
14
|
elsif raw.is_a?(Hash)
|
13
|
-
new(raw.
|
15
|
+
new(raw.transform_values { |value| from_raw(value) })
|
14
16
|
else
|
15
17
|
new(raw)
|
16
18
|
end
|
@@ -20,7 +22,7 @@ class Language
|
|
20
22
|
if raw.is_a?(Array)
|
21
23
|
raw.map(&:to_raw)
|
22
24
|
elsif raw.is_a?(Hash)
|
23
|
-
raw.
|
25
|
+
raw.transform_values(&:to_raw)
|
24
26
|
else
|
25
27
|
raw
|
26
28
|
end
|
@@ -35,7 +37,7 @@ class Language
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def ==(other)
|
38
|
-
other.is_a?(Output) ?
|
40
|
+
raw == (other.is_a?(Output) ? other.raw : other)
|
39
41
|
end
|
40
42
|
|
41
43
|
def to_s
|
@@ -66,7 +68,7 @@ class Language
|
|
66
68
|
when String
|
67
69
|
case other.raw
|
68
70
|
when String
|
69
|
-
@raw
|
71
|
+
@raw += other.raw
|
70
72
|
when Array
|
71
73
|
@raw = other.raw
|
72
74
|
when Hash
|
@@ -75,18 +77,18 @@ class Language
|
|
75
77
|
when Array
|
76
78
|
case other.raw
|
77
79
|
when String
|
78
|
-
|
80
|
+
nil
|
79
81
|
when Array
|
80
|
-
@raw
|
82
|
+
@raw += other.raw
|
81
83
|
when Hash
|
82
84
|
@raw << other
|
83
85
|
end
|
84
86
|
when Hash
|
85
87
|
case other.raw
|
86
88
|
when String
|
87
|
-
|
89
|
+
nil
|
88
90
|
when Array
|
89
|
-
|
91
|
+
nil
|
90
92
|
when Hash
|
91
93
|
@raw.merge!(other.raw)
|
92
94
|
end
|
@@ -107,7 +109,7 @@ class Language
|
|
107
109
|
when String
|
108
110
|
case other.raw
|
109
111
|
when String
|
110
|
-
@raw
|
112
|
+
@raw += other.raw
|
111
113
|
when Array
|
112
114
|
@raw = [other]
|
113
115
|
when Hash
|
@@ -118,9 +120,9 @@ class Language
|
|
118
120
|
when Hash
|
119
121
|
case other.raw
|
120
122
|
when String
|
121
|
-
|
123
|
+
nil
|
122
124
|
when Array
|
123
|
-
|
125
|
+
nil
|
124
126
|
when Hash
|
125
127
|
@raw.merge!(other.raw)
|
126
128
|
end
|
data/lib/language/parser/str.rb
CHANGED
data/lib/language/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Language
|
2
4
|
class Parser
|
3
5
|
attr_accessor :input, :buffer, :output, :root, :cursor
|
@@ -13,20 +15,18 @@ class Language
|
|
13
15
|
def parse(check_end_of_input: true)
|
14
16
|
@root.parse(self)
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
else
|
19
|
-
raise NotEndOfInput.new(self)
|
18
|
+
unless @cursor == @input.size || !check_end_of_input
|
19
|
+
raise NotEndOfInput, self
|
20
20
|
end
|
21
|
+
|
22
|
+
@output.present? ? @output : Output.new(@buffer)
|
21
23
|
end
|
22
24
|
|
23
25
|
def consume(n)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
raise EndOfInput.new(self)
|
29
|
-
end
|
26
|
+
raise EndOfInput, self unless @cursor + n <= @input.size
|
27
|
+
|
28
|
+
@buffer += @input[@cursor, n]
|
29
|
+
@cursor += n
|
30
30
|
end
|
31
31
|
|
32
32
|
def aka(name)
|
data/lib/language-ruby.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require "timeout"
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
4
3
|
require "zeitwerk"
|
5
4
|
|
6
5
|
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
7
|
-
loader.ignore("#{__dir__}/template-ruby.rb")
|
8
|
-
loader.ignore("#{__dir__}/code-ruby.rb")
|
9
6
|
loader.ignore("#{__dir__}/language-ruby.rb")
|
10
7
|
loader.setup
|
data/lib/language.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Language
|
2
4
|
def self.parse(input)
|
3
5
|
new.parse(input)
|
@@ -15,12 +17,12 @@ class Language
|
|
15
17
|
Atom::Maybe.new(parent: new)
|
16
18
|
end
|
17
19
|
|
18
|
-
def self.repeat(
|
19
|
-
Atom::Repeat.new(parent: new,
|
20
|
+
def self.repeat(minimum = 0, maximum = nil)
|
21
|
+
Atom::Repeat.new(parent: new, minimum:, maximum:)
|
20
22
|
end
|
21
23
|
|
22
24
|
def self.aka(name)
|
23
|
-
Atom::Aka.new(parent: new, name:
|
25
|
+
Atom::Aka.new(parent: new, name:)
|
24
26
|
end
|
25
27
|
|
26
28
|
def self.|(other)
|
@@ -36,7 +38,7 @@ class Language
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def self.then(&block)
|
39
|
-
Atom::Then.new(parent: new, block:
|
41
|
+
Atom::Then.new(parent: new, block:)
|
40
42
|
end
|
41
43
|
|
42
44
|
def parse(input_or_parser)
|
@@ -44,7 +46,7 @@ class Language
|
|
44
46
|
parser = input_or_parser
|
45
47
|
clone =
|
46
48
|
Parser.new(
|
47
|
-
root
|
49
|
+
root:,
|
48
50
|
input: parser.input,
|
49
51
|
cursor: parser.cursor,
|
50
52
|
buffer: parser.buffer,
|
@@ -58,12 +60,12 @@ class Language
|
|
58
60
|
parser.output = clone.output
|
59
61
|
else
|
60
62
|
input = input_or_parser
|
61
|
-
Parser.new(root
|
63
|
+
Parser.new(root:, input:).parse
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
67
|
def str(string)
|
66
|
-
Atom::Str.new(string:
|
68
|
+
Atom::Str.new(string:)
|
67
69
|
end
|
68
70
|
|
69
71
|
def any
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Parser
|
5
|
+
class Nothing < Language
|
6
|
+
def nothing_keyword
|
7
|
+
str("nothing")
|
8
|
+
end
|
9
|
+
|
10
|
+
def root
|
11
|
+
nothing_keyword.aka(:nothing)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.describe Language do
|
18
|
+
it "works" do
|
19
|
+
expect(Code::Parser::Nothing.parse("nothing")).to eq({ nothing: "nothing" })
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
CHANGED