arpaka 1.0.0 → 2.0.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -2
  3. data/README.md +104 -7
  4. data/Rakefile +15 -1
  5. data/docs/architecture.dot +30 -0
  6. data/docs/architecture.md +96 -0
  7. data/docs/architecture.webp +0 -0
  8. data/docs/contributes.md +115 -0
  9. data/docs/usage.md +497 -0
  10. data/lib/arpaka/cli.rb +5 -53
  11. data/lib/arpaka/plugins/cli.rb +61 -0
  12. data/lib/arpaka/plugins/sample.rb +14 -0
  13. data/lib/arpaka/plugins/sample_runner.rb +21 -0
  14. data/lib/arpaka/{actions.rb → ruby/actions.rb} +230 -151
  15. data/lib/arpaka/ruby/class_name_parser.rb +97 -0
  16. data/lib/arpaka/ruby/cli.rb +64 -0
  17. data/lib/arpaka/ruby/frontend_emitter.rb +59 -0
  18. data/lib/arpaka/ruby/generator.rb +41 -0
  19. data/lib/arpaka/{ruby_grammar.rb → ruby/grammar.rb} +5 -56
  20. data/lib/arpaka/ruby/grammar_emitter.rb +71 -0
  21. data/lib/arpaka/ruby/profile.rb +129 -0
  22. data/lib/arpaka/{profile → ruby/profiles}/ruby_3_3.rb +21 -21
  23. data/lib/arpaka/{profile → ruby/profiles}/ruby_3_4.rb +21 -21
  24. data/lib/arpaka/{runtime → ruby/runtime/detailed}/ast.rb.erb +41 -5
  25. data/lib/arpaka/ruby/runtime/detailed/builder.rb.erb +1177 -0
  26. data/lib/arpaka/{runtime → ruby/runtime}/frontend.rb.erb +17 -4
  27. data/lib/arpaka/{runtime → ruby/runtime}/lexer.rb.erb +576 -99
  28. data/lib/arpaka/ruby/runtime/structured.rb.erb +111 -0
  29. data/lib/arpaka/ruby.rb +23 -0
  30. data/lib/arpaka.rb +6 -9
  31. data/lib/lrama/ruby/backend.rb +4 -9
  32. data/lib/lrama/ruby/parser.rb.erb +35 -9
  33. data/lib/lrama/ruby/parser_emitter.rb +41 -0
  34. data/lib/lrama/ruby/table_codec.rb +50 -0
  35. data/lib/lrama/ruby/version.rb +1 -1
  36. data/lib/lrama/ruby.rb +1 -0
  37. data/sig/arpaka.rbs +8 -3
  38. metadata +32 -16
  39. data/lib/arpaka/generator.rb +0 -51
  40. data/lib/arpaka/profile/ruby.rb +0 -49
  41. data/lib/arpaka/runtime/builder.rb.erb +0 -323
  42. /data/lib/arpaka/{BSDL → ruby/BSDL} +0 -0
  43. /data/lib/arpaka/{COPYING → ruby/COPYING} +0 -0
  44. /data/lib/arpaka/{source.json → ruby/source.json} +0 -0
  45. /data/lib/arpaka/{upstream_rules.json → ruby/upstream_rules.json} +0 -0
@@ -1,323 +0,0 @@
1
- class Builder
2
- RULES = <%= rules.inspect %>.to_h { |rule| [rule.fetch("id"), rule.freeze] }.freeze
3
- private_constant :RULES
4
-
5
- def initialize
6
- @locals = {}
7
- end
8
-
9
- def program(statements)
10
- AST::Program.new(statements.freeze)
11
- end
12
-
13
- def integer(value)
14
- raise ArgumentError, "tINTEGER requires an Integer value" unless value.is_a?(Integer)
15
- AST::Literal.new(value)
16
- end
17
-
18
- def float(value)
19
- raise ArgumentError, "tFLOAT requires a Float value" unless value.is_a?(Float)
20
- AST::Literal.new(value)
21
- end
22
-
23
- def literal(value)
24
- AST::Literal.new(value)
25
- end
26
-
27
- def reserved_word(value)
28
- value.to_sym
29
- end
30
-
31
- def binary(operator, left, right)
32
- AST::Binary.new(operator, left, right)
33
- end
34
-
35
- def operator(value)
36
- value.to_sym
37
- end
38
-
39
- def range(operator, begin_value, end_value)
40
- AST::RangeLiteral.new(operator, begin_value, end_value)
41
- end
42
-
43
- def ternary(condition, then_value, else_value)
44
- AST::Ternary.new(condition, then_value, else_value)
45
- end
46
-
47
- def call(name, arguments)
48
- AST::Call.new(name, arguments.freeze)
49
- end
50
-
51
- def receiver_call(receiver, operator, name, arguments)
52
- AST::ReceiverCall.new(receiver, operator, name, (arguments || []).freeze)
53
- end
54
-
55
- def block_call(call, body)
56
- AST::BlockCall.new(call, body_nodes(body))
57
- end
58
-
59
- def append_arguments(arguments, argument)
60
- list = arguments.is_a?(Array) ? arguments : [arguments]
61
- (list + [argument]).freeze
62
- end
63
-
64
- def string(value)
65
- if value.is_a?(Array)
66
- return AST::InterpolatedString.new(value.freeze) if value.any? { |part| !part.is_a?(String) }
67
- value = value.join
68
- end
69
- AST::StringLiteral.new(value.to_s)
70
- end
71
-
72
- def regexp(value)
73
- AST::RegexpLiteral.new(value.is_a?(Array) ? value.join : value.to_s)
74
- end
75
-
76
- def xstring(value)
77
- AST::XStringLiteral.new(value.is_a?(Array) ? value.join : value.to_s)
78
- end
79
-
80
- def for_node(variable, enumerable, body)
81
- AST::For.new(variable, enumerable, body)
82
- end
83
-
84
- def def_node(name, arguments, body)
85
- AST::Def.new(name.to_sym, (arguments || []).freeze, body || [].freeze)
86
- end
87
- <% if runtime.fetch("builder_methods", []).include?("singleton_method") -%>
88
- def singleton_method_node(receiver, name, arguments, body)
89
- AST::SingletonMethodDef.new(receiver, name.to_sym, (arguments || []).freeze,
90
- body_nodes(body))
91
- end
92
- <% end -%>
93
-
94
- def class_node(name, superclass, body)
95
- AST::ClassDef.new(name.to_sym, superclass, body_nodes(body))
96
- end
97
-
98
- def module_node(name, body)
99
- AST::ModuleDef.new(name.to_sym, body_nodes(body))
100
- end
101
- <% if runtime.fetch("builder_methods", []).include?("singleton_class") -%>
102
- def singleton_class_node(receiver, body)
103
- AST::SingletonClassDef.new(receiver, body_nodes(body))
104
- end
105
- <% end -%>
106
-
107
- def body_nodes(body)
108
- value = body
109
- while value.is_a?(Array) && value.length == 1 && value.first.is_a?(Array)
110
- value = value.first
111
- end
112
- value || [].freeze
113
- end
114
-
115
- def symbol(value)
116
- value = value.map { |part| part.is_a?(String) ? part : part.to_s }.join if value.is_a?(Array)
117
- value = value.name if value.is_a?(AST::Variable)
118
- AST::Literal.new(value.to_sym)
119
- end
120
-
121
- def join_strings(parts)
122
- parts
123
- end
124
-
125
- def interpolation(value)
126
- value.is_a?(Array) && value.length == 1 ? value.first : value
127
- end
128
-
129
- def concat_strings(left, right)
130
- left_parts = left.is_a?(AST::InterpolatedString) ? left.parts : [left.value]
131
- right_parts = right.is_a?(AST::InterpolatedString) ? right.parts : [right.value]
132
- parts = left_parts + right_parts
133
- parts.all? { |part| part.is_a?(String) } ? AST::StringLiteral.new(parts.join) : AST::InterpolatedString.new(parts.freeze)
134
- end
135
-
136
- def index(receiver, arguments)
137
- AST::Index.new(receiver, arguments.freeze)
138
- end
139
-
140
- def loop(kind, condition, body)
141
- AST::Loop.new(kind, condition, body)
142
- end
143
-
144
- def control(kind)
145
- AST::Control.new(kind)
146
- end
147
-
148
- def variable(kind, name)
149
- AST::Variable.new(kind, name.is_a?(String) ? name.to_sym : name)
150
- end
151
-
152
- def rescue_modifier(expression, fallback)
153
- AST::Rescue.new(expression, fallback)
154
- end
155
-
156
- def when_node(patterns, body)
157
- AST::When.new(patterns.freeze, body)
158
- end
159
-
160
- def case_node(expression, whens, else_body)
161
- AST::Case.new(expression, whens.freeze, else_body)
162
- end
163
-
164
- def case_clauses(value)
165
- value.is_a?(Array) ? value : [value]
166
- end
167
-
168
- def case_parts(value)
169
- values = case_clauses(value)
170
- if values.all? { |item| item.is_a?(AST::When) }
171
- [values, nil]
172
- else
173
- [values.grep(AST::When), values.reject { |item| item.is_a?(AST::When) }]
174
- end
175
- end
176
-
177
- def case_chain(when_node, rest)
178
- [when_node] + (rest.nil? ? [] : case_clauses(rest))
179
- end
180
-
181
- def lambda_node(arguments, body)
182
- AST::Lambda.new((arguments || []).freeze, body_nodes(body))
183
- end
184
- <% if runtime.fetch("builder_methods", []).include?("rescue") -%>
185
- def body_statement(body, clauses, else_body, ensure_body)
186
- clauses = clauses.nil? ? [] : Array(clauses)
187
- if clauses.empty? && else_body.nil? && ensure_body.nil?
188
- body_nodes(body)
189
- else
190
- full_rescue(body, clauses, else_body, ensure_body)
191
- end
192
- end
193
-
194
- def rescue_chain(clause, rest)
195
- [clause] + (rest.nil? ? [] : Array(rest))
196
- end
197
-
198
- def pattern(kind, values)
199
- AST::Pattern.new(kind.to_sym, Array(values).freeze)
200
- end
201
-
202
- def rescue_clause(exceptions, variable, body)
203
- AST::RescueClause.new(Array(exceptions).freeze, variable, body_nodes(body))
204
- end
205
-
206
- def full_rescue(body, clauses, else_body, ensure_body)
207
- AST::FullRescue.new(body_nodes(body), Array(clauses).freeze,
208
- else_body.nil? ? nil : body_nodes(else_body),
209
- ensure_body.nil? ? nil : body_nodes(ensure_body))
210
- end
211
-
212
- def begin_block(body)
213
- AST::BeginBlock.new(body_nodes(body))
214
- end
215
-
216
- def end_block(body)
217
- AST::EndBlock.new(body_nodes(body))
218
- end
219
- <% end -%>
220
-
221
- def unary(operator, operand)
222
- AST::Unary.new(operator, operand)
223
- end
224
-
225
- def if_node(condition, then_body, else_body)
226
- AST::If.new(condition, then_body, else_body)
227
- end
228
-
229
- def unless_node(condition, then_body, else_body)
230
- AST::If.new(AST::Unary.new(:!, condition), then_body, else_body)
231
- end
232
-
233
- def elsif_node(condition, then_body, else_body)
234
- AST::If.new(condition, then_body, else_body)
235
- end
236
-
237
- def parentheses(statements, rule_id)
238
- return statements.first if statements.length == 1
239
- AST::Sequence.new(statements.freeze)
240
- end
241
-
242
- def identifier(value)
243
- unless value.is_a?(Symbol) || value.is_a?(String)
244
- raise ArgumentError, "tIDENTIFIER requires a Symbol or String value"
245
- end
246
- value.to_sym
247
- end
248
-
249
- def declare_local(name)
250
- @locals[name] = true
251
- name
252
- end
253
-
254
- def read_local(name)
255
- return name if name.is_a?(AST::Variable)
256
- (@locals.key?(name) ? AST::LocalRead : AST::BareCall).new(name)
257
- end
258
-
259
- def assign(name, value)
260
- AST::LocalWrite.new(name, value)
261
- end
262
- <% if runtime.fetch("builder_methods", []).include?("assignment") -%>
263
- def assignment(name, value)
264
- if name.is_a?(AST::Field) || name.is_a?(AST::Index)
265
- AST::Assignment.new(name, value)
266
- else
267
- AST::LocalWrite.new(name, value)
268
- end
269
- end
270
-
271
- def opassign(target, operator, value)
272
- AST::OpAssign.new(target, operator.to_sym, value)
273
- end
274
-
275
- def multiple_assign(targets, value)
276
- AST::MultipleAssign.new(Array(targets).freeze, value)
277
- end
278
-
279
- def field(receiver, operator, name)
280
- AST::Field.new(receiver, operator.to_sym, name.to_sym)
281
- end
282
-
283
- def alias_node(new_name, old_name)
284
- AST::Alias.new(new_name, old_name)
285
- end
286
-
287
- def undef_node(names)
288
- AST::Undef.new(Array(names).freeze)
289
- end
290
- <% end -%>
291
-
292
- def array(elements)
293
- AST::ArrayLiteral.new(elements.freeze)
294
- end
295
-
296
- def word_array(elements, symbols: false)
297
- elements ||= []
298
- elements = elements.elements if elements.is_a?(AST::ArrayLiteral)
299
- values = elements.map do |value|
300
- value = value.value if value.is_a?(AST::StringLiteral)
301
- symbols ? value.to_sym : AST::StringLiteral.new(value.to_s)
302
- end
303
- AST::ArrayLiteral.new(values.freeze)
304
- end
305
-
306
- def hash(pairs)
307
- AST::HashLiteral.new(pairs.freeze)
308
- end
309
-
310
- def pair(key, value)
311
- AST::Pair.new(key, value)
312
- end
313
-
314
- def append(list, value)
315
- value.nil? ? list : (list + [value]).freeze
316
- end
317
-
318
- def unsupported(id)
319
- rule = RULES.fetch(id)
320
- raise UnsupportedSyntax.new(rule.fetch("rule"), rule.fetch("line"))
321
- end
322
- end
323
- private_constant :Builder
File without changes
File without changes
File without changes