arpaka 0.1.1 → 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 +118 -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 -50
  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} +53 -59
  20. data/lib/arpaka/ruby/grammar_emitter.rb +71 -0
  21. data/lib/arpaka/ruby/profile.rb +129 -0
  22. data/lib/arpaka/ruby/profiles/ruby_3_3.rb +800 -0
  23. data/lib/arpaka/ruby/profiles/ruby_3_4.rb +802 -0
  24. data/lib/arpaka/ruby/runtime/detailed/ast.rb.erb +92 -0
  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 +583 -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 +46 -13
  39. data/lib/arpaka/generator.rb +0 -43
  40. data/lib/arpaka/runtime/ast.rb.erb +0 -35
  41. data/lib/arpaka/runtime/builder.rb.erb +0 -247
  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,247 +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
-
88
- def class_node(name, superclass, body)
89
- AST::ClassDef.new(name.to_sym, superclass, body_nodes(body))
90
- end
91
-
92
- def module_node(name, body)
93
- AST::ModuleDef.new(name.to_sym, body_nodes(body))
94
- end
95
-
96
- def body_nodes(body)
97
- value = body
98
- while value.is_a?(Array) && value.length == 1 && value.first.is_a?(Array)
99
- value = value.first
100
- end
101
- value || [].freeze
102
- end
103
-
104
- def symbol(value)
105
- value = value.map { |part| part.is_a?(String) ? part : part.to_s }.join if value.is_a?(Array)
106
- value = value.name if value.is_a?(AST::Variable)
107
- AST::Literal.new(value.to_sym)
108
- end
109
-
110
- def join_strings(parts)
111
- parts
112
- end
113
-
114
- def interpolation(value)
115
- value.is_a?(Array) && value.length == 1 ? value.first : value
116
- end
117
-
118
- def concat_strings(left, right)
119
- left_parts = left.is_a?(AST::InterpolatedString) ? left.parts : [left.value]
120
- right_parts = right.is_a?(AST::InterpolatedString) ? right.parts : [right.value]
121
- parts = left_parts + right_parts
122
- parts.all? { |part| part.is_a?(String) } ? AST::StringLiteral.new(parts.join) : AST::InterpolatedString.new(parts.freeze)
123
- end
124
-
125
- def index(receiver, arguments)
126
- AST::Index.new(receiver, arguments.freeze)
127
- end
128
-
129
- def loop(kind, condition, body)
130
- AST::Loop.new(kind, condition, body)
131
- end
132
-
133
- def control(kind)
134
- AST::Control.new(kind)
135
- end
136
-
137
- def variable(kind, name)
138
- AST::Variable.new(kind, name.is_a?(String) ? name.to_sym : name)
139
- end
140
-
141
- def rescue_modifier(expression, fallback)
142
- AST::Rescue.new(expression, fallback)
143
- end
144
-
145
- def when_node(patterns, body)
146
- AST::When.new(patterns.freeze, body)
147
- end
148
-
149
- def case_node(expression, whens, else_body)
150
- AST::Case.new(expression, whens.freeze, else_body)
151
- end
152
-
153
- def case_clauses(value)
154
- value.is_a?(Array) ? value : [value]
155
- end
156
-
157
- def case_parts(value)
158
- values = case_clauses(value)
159
- if values.all? { |item| item.is_a?(AST::When) }
160
- [values, nil]
161
- else
162
- [values.grep(AST::When), values.reject { |item| item.is_a?(AST::When) }]
163
- end
164
- end
165
-
166
- def case_chain(when_node, rest)
167
- [when_node] + (rest.nil? ? [] : case_clauses(rest))
168
- end
169
-
170
- def lambda_node(arguments, body)
171
- AST::Lambda.new((arguments || []).freeze, body_nodes(body))
172
- end
173
-
174
- def unary(operator, operand)
175
- AST::Unary.new(operator, operand)
176
- end
177
-
178
- def if_node(condition, then_body, else_body)
179
- AST::If.new(condition, then_body, else_body)
180
- end
181
-
182
- def unless_node(condition, then_body, else_body)
183
- AST::If.new(AST::Unary.new(:!, condition), then_body, else_body)
184
- end
185
-
186
- def elsif_node(condition, then_body, else_body)
187
- AST::If.new(condition, then_body, else_body)
188
- end
189
-
190
- def parentheses(statements, rule_id)
191
- return statements.first if statements.length == 1
192
- AST::Sequence.new(statements.freeze)
193
- end
194
-
195
- def identifier(value)
196
- unless value.is_a?(Symbol) || value.is_a?(String)
197
- raise ArgumentError, "tIDENTIFIER requires a Symbol or String value"
198
- end
199
- value.to_sym
200
- end
201
-
202
- def declare_local(name)
203
- @locals[name] = true
204
- name
205
- end
206
-
207
- def read_local(name)
208
- return name if name.is_a?(AST::Variable)
209
- (@locals.key?(name) ? AST::LocalRead : AST::BareCall).new(name)
210
- end
211
-
212
- def assign(name, value)
213
- AST::LocalWrite.new(name, value)
214
- end
215
-
216
- def array(elements)
217
- AST::ArrayLiteral.new(elements.freeze)
218
- end
219
-
220
- def word_array(elements, symbols: false)
221
- elements ||= []
222
- elements = elements.elements if elements.is_a?(AST::ArrayLiteral)
223
- values = elements.map do |value|
224
- value = value.value if value.is_a?(AST::StringLiteral)
225
- symbols ? value.to_sym : AST::StringLiteral.new(value.to_s)
226
- end
227
- AST::ArrayLiteral.new(values.freeze)
228
- end
229
-
230
- def hash(pairs)
231
- AST::HashLiteral.new(pairs.freeze)
232
- end
233
-
234
- def pair(key, value)
235
- AST::Pair.new(key, value)
236
- end
237
-
238
- def append(list, value)
239
- value.nil? ? list : (list + [value]).freeze
240
- end
241
-
242
- def unsupported(id)
243
- rule = RULES.fetch(id)
244
- raise UnsupportedSyntax.new(rule.fetch("rule"), rule.fetch("line"))
245
- end
246
- end
247
- private_constant :Builder
File without changes
File without changes
File without changes