myco 0.1.4 → 0.1.5
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/lib/myco/bootstrap/find_constant.rb +4 -11
- data/lib/myco/code_loader.rb +2 -1
- data/lib/myco/code_tools/AST/ConstantAccess.my +47 -3
- data/lib/myco/code_tools/AST/ConstantAccess.my.rb +13 -9
- data/lib/myco/code_tools/AST/ConstantAssignment.my +1 -5
- data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +3 -9
- data/lib/myco/code_tools/AST/ToRuby.my +5 -2
- data/lib/myco/code_tools/AST/ToRuby.my.rb +7 -3
- data/lib/myco/code_tools/AST.my +1 -0
- data/lib/myco/code_tools/AST.my.rb +9 -1
- data/lib/myco/code_tools/Parser.my +24 -0
- data/lib/myco/code_tools/Parser.my.rb +25 -0
- data/lib/myco/code_tools/parser/MycoBuilder.my +67 -0
- data/lib/myco/code_tools/parser/MycoBuilder.my.rb +99 -0
- data/lib/myco/code_tools/parser/MycoCharacterClasses.my +20 -0
- data/lib/myco/code_tools/parser/MycoCharacterClasses.my.rb +56 -0
- data/lib/myco/code_tools/parser/MycoGrammar.my +564 -0
- data/lib/myco/code_tools/parser/MycoGrammar.my.rb +1851 -0
- data/lib/myco/code_tools/parser/MycoTokens.my +78 -0
- data/lib/myco/code_tools/parser/MycoTokens.my.rb +170 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my +4 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Builder.my.rb +5 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +142 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +181 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +420 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +415 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +137 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my.rb +237 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my +183 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Constructions.my.rb +370 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +65 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +83 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my +139 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Instructions.my.rb +284 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my +37 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +24 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +42 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +52 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +123 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +164 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +236 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +339 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my +15 -0
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces.my.rb +14 -0
- data/lib/myco/code_tools.rb +1 -1
- data/lib/myco/version.rb +1 -1
- data/lib/myco.rb +2 -0
- metadata +44 -25
- data/lib/myco/code_tools/parser/peg_parser.rb +0 -7182
- data/lib/myco/code_tools/parser.rb +0 -39
@@ -0,0 +1,564 @@
|
|
1
|
+
|
2
|
+
import 'MycoCharacterClasses.my'
|
3
|
+
import 'MycoTokens.my'
|
4
|
+
|
5
|
+
MycoGrammar: Pegleromyces::Grammar {
|
6
|
+
C: MycoCharacterClasses
|
7
|
+
T: MycoTokens
|
8
|
+
|
9
|
+
[rules]
|
10
|
+
|
11
|
+
##
|
12
|
+
# Toplevel Terminal Categorizations
|
13
|
+
|
14
|
+
rule root:
|
15
|
+
(r(declobj_expr_body[:n0])
|
16
|
+
{ ast.declfile(n0, n0) })[:root]
|
17
|
+
|
18
|
+
# Declarations
|
19
|
+
rule decl:
|
20
|
+
declobj
|
21
|
+
/ declstr
|
22
|
+
/ copen
|
23
|
+
|
24
|
+
# Expressions allowable inside object declarations
|
25
|
+
rule declobj_expr:
|
26
|
+
category
|
27
|
+
/ declobj_expr_not_category
|
28
|
+
|
29
|
+
# Expressions allowable inside object declarations that is not a category
|
30
|
+
rule declobj_expr_not_category:
|
31
|
+
decl
|
32
|
+
/ cdefn
|
33
|
+
/ cmeme
|
34
|
+
/ constant
|
35
|
+
/ meme
|
36
|
+
|
37
|
+
# Expressions allowable inside memes
|
38
|
+
rule meme_expr:
|
39
|
+
arg_expr
|
40
|
+
|
41
|
+
# Expressions allowable as function arguments
|
42
|
+
rule arg_expr:
|
43
|
+
assignment
|
44
|
+
/ left_chained_atoms
|
45
|
+
/ dyn_string
|
46
|
+
/ dyn_symstr
|
47
|
+
/ expr_atom
|
48
|
+
|
49
|
+
# TODO: make expr_atom not redundant with below rules
|
50
|
+
# Expression atoms
|
51
|
+
rule expr_atom:
|
52
|
+
decl
|
53
|
+
/ left_chained_invocations
|
54
|
+
/ lit_string
|
55
|
+
/ lit_symstr
|
56
|
+
/ unary_operation
|
57
|
+
/ paren_expr
|
58
|
+
/ constant
|
59
|
+
/ lit_simple
|
60
|
+
/ lit_array
|
61
|
+
/ invoke
|
62
|
+
|
63
|
+
# Expression atoms that are not invocation chains
|
64
|
+
rule expr_atom_not_chained:
|
65
|
+
decl
|
66
|
+
/ lit_string
|
67
|
+
/ lit_symstr
|
68
|
+
/ unary_operation
|
69
|
+
/ paren_expr
|
70
|
+
/ constant
|
71
|
+
/ lit_simple
|
72
|
+
/ lit_array
|
73
|
+
/ invoke
|
74
|
+
|
75
|
+
# Expression atoms that are not strings
|
76
|
+
rule expr_atom_not_string:
|
77
|
+
decl
|
78
|
+
/ left_chained_invocations
|
79
|
+
/ unary_operation
|
80
|
+
/ paren_expr
|
81
|
+
/ constant
|
82
|
+
/ lit_simple
|
83
|
+
/ lit_array
|
84
|
+
/ invoke
|
85
|
+
|
86
|
+
##
|
87
|
+
# Simple literals
|
88
|
+
|
89
|
+
rule lit_simple:
|
90
|
+
r(T.null[:t0]) { ast.null(t0) }
|
91
|
+
/ r(T.void[:t0]) { ast.void(t0) }
|
92
|
+
/ r(T.true[:t0]) { ast.true(t0) }
|
93
|
+
/ r(T.false[:t0]) { ast.false(t0) }
|
94
|
+
/ r(T.self[:t0]) { ast.self(t0) }
|
95
|
+
/ r(T.float[:t0]) { ast.lit(t0, t0.float) }
|
96
|
+
/ r(T.integer[:t0]) { ast.lit(t0, t0.integer) }
|
97
|
+
/ r(T.symbol[:t0]) { ast.lit(t0, t0.text.slice(::Range.new(1,-1)).to_sym) } # TODO: more succinct here
|
98
|
+
|
99
|
+
##
|
100
|
+
# Enclosed literals
|
101
|
+
|
102
|
+
rule lit_string:
|
103
|
+
r((T.string_begin + T.string_body[:tb] + T.string_end) /
|
104
|
+
(T.sstring_begin + T.sstring_body[:tb] + T.sstring_end))
|
105
|
+
{ ast.lit(tb, encode_escapes(tb.text)) }
|
106
|
+
|
107
|
+
rule lit_string_as_symbol:
|
108
|
+
r((T.string_begin + T.string_body[:tb] + T.string_end) /
|
109
|
+
(T.sstring_begin + T.sstring_body[:tb] + T.sstring_end))
|
110
|
+
{ ast.lit(tb, encode_escapes(tb.text).to_sym) }
|
111
|
+
|
112
|
+
rule lit_symstr:
|
113
|
+
r(T.symstr_begin + T.string_body[:tb] + T.string_end)
|
114
|
+
{ ast.lit(tb, encode_escapes(tb.text).to_sym) }
|
115
|
+
|
116
|
+
rule category_name:
|
117
|
+
r(T.catgry_begin + T.catgry_body[:tb] + T.catgry_end)
|
118
|
+
{ ast.lit(tb, encode_escapes(tb.text).to_sym) }
|
119
|
+
|
120
|
+
##
|
121
|
+
# String interpolations / juxtapositions
|
122
|
+
|
123
|
+
rule dyn_string_part:
|
124
|
+
r(C.spc.* + expr_atom_not_string[:n0] + C.spc.* + lit_string[:n1])
|
125
|
+
{ [n0,n1] }
|
126
|
+
|
127
|
+
rule dyn_string_parts:
|
128
|
+
r(dyn_string_part.+[:nlist])
|
129
|
+
{ nlist.flatten }
|
130
|
+
|
131
|
+
rule dyn_string:
|
132
|
+
r(lit_string[:n0] + dyn_string_parts[:nrest])
|
133
|
+
{ ast.dstr(n0, [n0] + nrest) }
|
134
|
+
|
135
|
+
rule dyn_symstr:
|
136
|
+
r(lit_symstr[:n0] + dyn_string_parts[:nrest])
|
137
|
+
{ ast.dsym(n0, [n0] + nrest) }
|
138
|
+
|
139
|
+
##
|
140
|
+
# Constants
|
141
|
+
|
142
|
+
rule colon_const:
|
143
|
+
r(T.scope + T.constant[:tc])
|
144
|
+
{ tc }
|
145
|
+
|
146
|
+
rule constant:
|
147
|
+
r(T.scope.-[:ts] + T.constant[:tc] + colon_const.*[:trest])
|
148
|
+
{ ast.const((ts||tc), !!ts, [tc.sym, *trest.map(&:sym)]) }
|
149
|
+
|
150
|
+
rule const_sep: (C.spc_nl.* + T.const_sep + C.spc_nl.*).+
|
151
|
+
|
152
|
+
rule sepd_constant:
|
153
|
+
r(const_sep + constant[:n0])
|
154
|
+
{ n0 }
|
155
|
+
|
156
|
+
rule constant_list:
|
157
|
+
r(constant[:n0] + sepd_constant.*[:nrest])
|
158
|
+
{ ast.arrass(n0, [n0, *nrest]) }
|
159
|
+
|
160
|
+
##
|
161
|
+
# Bare identifiers
|
162
|
+
|
163
|
+
# Used in contexts where a bare identifier is a symbol
|
164
|
+
rule id_as_symbol:
|
165
|
+
r(T.identifier[:t0]) { ast.lit(t0, t0.sym) }
|
166
|
+
|
167
|
+
##
|
168
|
+
# Object declarations
|
169
|
+
|
170
|
+
rule declobj_sepd_expr:
|
171
|
+
r(arg_sep + declobj_expr[:n0]) { n0 }
|
172
|
+
|
173
|
+
rule declobj_sepd_exprs:
|
174
|
+
r(declobj_expr[:n0] + declobj_sepd_expr.*[:nrest] + arg_sep_opt)
|
175
|
+
{ [n0, *nrest] }
|
176
|
+
|
177
|
+
rule declobj_expr_body:
|
178
|
+
r(arg_sep_opt + declobj_sepd_exprs[:nlist] + T.declare_end[:te])
|
179
|
+
{ ast.block(nlist.first, nlist) }
|
180
|
+
/ r(arg_sep_opt + T.declare_end[:te])
|
181
|
+
{ ast.null(te) }
|
182
|
+
|
183
|
+
rule declobj:
|
184
|
+
r(constant_list[:n0] + C.spc_nl.* + T.declare_begin[:tb] + declobj_expr_body[:n1])
|
185
|
+
{ ast.declobj(tb, n0, n1) }
|
186
|
+
|
187
|
+
rule category_expr:
|
188
|
+
declobj_expr_not_category
|
189
|
+
|
190
|
+
rule category_sepd_expr:
|
191
|
+
r(arg_sep + category_expr[:n0]) { n0 }
|
192
|
+
|
193
|
+
rule category_sepd_exprs:
|
194
|
+
r(arg_sep + category_expr[:n0] + category_sepd_expr.*[:nrest])
|
195
|
+
{ [n0, *nrest] }
|
196
|
+
|
197
|
+
rule category:
|
198
|
+
r(category_name[:n0] + category_sepd_exprs.-[:nlist]
|
199
|
+
+ !!(arg_sep_opt + (T.catgry_begin / T.declare_end)))
|
200
|
+
{ ast.category(n0, n0.value,
|
201
|
+
(nlist &? ast.block(nlist.first, nlist) ?? ast.null(n0))) }
|
202
|
+
|
203
|
+
rule copen:
|
204
|
+
r(constant[:n0] + C.spc_nl.* + T.reopen[:tb] + C.spc_nl.* + T.declare_begin + declobj_expr_body[:n1])
|
205
|
+
{ ast.copen(tb, n0, n1) }
|
206
|
+
|
207
|
+
rule cdefn:
|
208
|
+
r(constant[:n0] + C.spc_nl.* + T.define[:tb] + C.spc_nl.* + declobj[:n1])
|
209
|
+
{ ast.cdefn(tb, n0, n1) }
|
210
|
+
|
211
|
+
##
|
212
|
+
# String object declarations
|
213
|
+
|
214
|
+
rule declstr_body:
|
215
|
+
r(T.declstr_begin[:tb] + C.spc.* + C.nl
|
216
|
+
+ T.declstr_body[:ts] + C.spc_nl.* + T.declstr_end)
|
217
|
+
{ ast.str(tb, ts.text) }
|
218
|
+
|
219
|
+
rule declstr:
|
220
|
+
r(constant_list[:nc] + C.spc.+ + declstr_body[:nb])
|
221
|
+
{ ast.declstr(nc, nc, nb) }
|
222
|
+
|
223
|
+
##
|
224
|
+
# Assignment
|
225
|
+
|
226
|
+
rule assignment:
|
227
|
+
local_assignment
|
228
|
+
/ invoke_assignment
|
229
|
+
|
230
|
+
rule assign_rhs:
|
231
|
+
arg_expr
|
232
|
+
|
233
|
+
rule local_assignment:
|
234
|
+
r(T.identifier[:ti] + C.spc_nl.* + T.assign[:to] + C.spc_nl.* + assign_rhs[:rhs])
|
235
|
+
{ ast.lasgn(to, ti.sym, rhs) }
|
236
|
+
|
237
|
+
rule invoke_assignment_lhs:
|
238
|
+
left_chained_invocations
|
239
|
+
/ invoke
|
240
|
+
|
241
|
+
rule invoke_assignment:
|
242
|
+
r(invoke_assignment_lhs[:lhs] + C.spc_nl.* + T.assign[:to] + C.spc_nl.* + assign_rhs[:rhs])
|
243
|
+
{
|
244
|
+
lhs.name = (""lhs.name"=").to_sym
|
245
|
+
orig_arguments = lhs.arguments &? lhs.arguments.body ?? []
|
246
|
+
arg_order = lhs.name==:"[]=" &? [*orig_arguments, rhs] ?? [rhs, *orig_arguments]
|
247
|
+
lhs.arguments = ast.argass(rhs, arg_order)
|
248
|
+
lhs
|
249
|
+
}
|
250
|
+
|
251
|
+
|
252
|
+
##
|
253
|
+
# Invoke - Results in a :lambig, :call, or :iter with a :call within
|
254
|
+
|
255
|
+
rule invoke_body:
|
256
|
+
r(C.spc_nl.* + param_list.-[:np] + C.spc_nl.* + meme_enclosed_expr_body[:nb])
|
257
|
+
{ [np, nb] }
|
258
|
+
|
259
|
+
opt_arg_list: (r(C.spc.* + arg_list[:n]) { n }).-
|
260
|
+
opt_invoke_body: (r(C.spc_nl.* + invoke_body[:nx]) { nx }).-
|
261
|
+
|
262
|
+
rule invoke:
|
263
|
+
r(T.identifier[:tn] + opt_arg_list[:na] + opt_invoke_body[:nlist])
|
264
|
+
{ ast.invoke(tn, null, tn.sym, na, *(nlist || [])) }
|
265
|
+
|
266
|
+
rule op_invoke: # Allow some binary operators to be invoked with a dot
|
267
|
+
r(op_invoke_id[:tn] + opt_arg_list[:na] + opt_invoke_body[:nlist])
|
268
|
+
{ ast.invoke(tn, null, tn.sym, na, *(nlist || [])) }
|
269
|
+
|
270
|
+
rule elem_invoke:
|
271
|
+
r(lit_array[:na] + opt_invoke_body[:nlist])
|
272
|
+
{ ast.invoke(na, null, :"[]", ast.argass(na, na.body), *(nlist || [])) }
|
273
|
+
|
274
|
+
rule op_invoke_id:
|
275
|
+
left_op_normal
|
276
|
+
|
277
|
+
##
|
278
|
+
# Argument lists
|
279
|
+
|
280
|
+
arg_sep: (C.spc.* + T.arg_sep + C.spc.*).+
|
281
|
+
arg_sep_opt: (C.spc / T.arg_sep).*
|
282
|
+
|
283
|
+
rule in_arg_normal:
|
284
|
+
in_arg_splat
|
285
|
+
/ r(arg_expr[:n0] + !in_arg_kwarg_mark) { n0 }
|
286
|
+
|
287
|
+
rule in_arg_sepd_normal:
|
288
|
+
r(arg_sep + in_arg_normal[:n0]) { n0 }
|
289
|
+
|
290
|
+
rule in_arg_normals:
|
291
|
+
r(in_arg_normal[:n0] + in_arg_sepd_normal.*[:nrest])
|
292
|
+
{ [n0,*nrest] }
|
293
|
+
|
294
|
+
rule in_arg_sepd_kwarg:
|
295
|
+
r(arg_sep + in_arg_kwarg[:n0]) { n0 }
|
296
|
+
|
297
|
+
rule in_arg_kwargs:
|
298
|
+
r(in_arg_kwarg[:n0] + in_arg_sepd_kwarg.*[:nrest])
|
299
|
+
{ ast.hash(n0.first, [n0,*nrest].flatten) }
|
300
|
+
|
301
|
+
rule in_arg_kwarg_mark: C.spc_nl.* + T.meme_mark
|
302
|
+
|
303
|
+
rule in_arg_kwarg:
|
304
|
+
r(id_as_symbol[:n0] + in_arg_kwarg_mark + C.spc_nl.* + arg_expr[:n1])
|
305
|
+
{ [n0, n1] }
|
306
|
+
|
307
|
+
rule in_arg_splat:
|
308
|
+
r(T.op_mult[:to] + expr_atom[:n0])
|
309
|
+
{ ast.splat(to, n0) }
|
310
|
+
|
311
|
+
rule in_arg_block:
|
312
|
+
r(T.op_toproc[:to] + expr_atom[:n0])
|
313
|
+
{ ast.blkarg(to, n0) }
|
314
|
+
|
315
|
+
rule in_arg_list:
|
316
|
+
r(in_arg_normals[:n0] + arg_sep + in_arg_kwargs[:n1] + arg_sep + in_arg_block[:n2]) { [*n0,n1,n2] }
|
317
|
+
/ r(in_arg_normals[:n0] + arg_sep + in_arg_kwargs[:n1]) { [*n0,n1] }
|
318
|
+
/ r(in_arg_normals[:n0] + arg_sep + in_arg_block[:n1]) { [*n0,n1] }
|
319
|
+
/ r(in_arg_kwargs[:n0] + arg_sep + in_arg_block[:n1]) { [n0,n1] }
|
320
|
+
/ r(in_arg_normals[:n0]) { [*n0] }
|
321
|
+
/ r(in_arg_kwargs[:n0]) { [n0] }
|
322
|
+
/ r(in_arg_block[:n0]) { [n0] }
|
323
|
+
|
324
|
+
rule arg_list:
|
325
|
+
r(T.args_begin[:tb] + arg_sep_opt + in_arg_list.-[:nlist] + arg_sep_opt + T.args_end)
|
326
|
+
{ ast.argass(tb, (nlist || [])) }
|
327
|
+
|
328
|
+
rule lit_array:
|
329
|
+
r(T.array_begin[:tb] + arg_sep_opt + in_arg_list.-[:nlist] + arg_sep_opt + T.array_end)
|
330
|
+
{ ast.arrass(tb, (nlist || [])) }
|
331
|
+
|
332
|
+
##
|
333
|
+
# Parameter lists
|
334
|
+
|
335
|
+
rule param:
|
336
|
+
r(T.identifier[:ti] + C.spc_nl.* + T.assign[:to] + C.spc_nl.* + arg_expr[:nv])
|
337
|
+
{ [:optional, ast.lasgn(ti, ti.sym, nv)] }
|
338
|
+
/ r(T.identifier[:ti] + C.spc_nl.* + T.meme_mark[:to] + C.spc_nl.* + arg_expr.-[:nv])
|
339
|
+
{ [:kwargs, ast.lasgn(ti, ti.sym, nv || ast.lit(to, :"*"))] }
|
340
|
+
/ r(T.op_exp + C.spc_nl.* + T.identifier[:ti])
|
341
|
+
{ [:kwrest, ti.sym] }
|
342
|
+
/ r(T.op_mult + C.spc_nl.* + T.identifier[:ti])
|
343
|
+
{ [:rest, ti.sym] }
|
344
|
+
/ r(T.op_toproc + C.spc_nl.* + T.identifier[:ti])
|
345
|
+
{ [:block, ti.sym] }
|
346
|
+
/ r(T.identifier[:ti])
|
347
|
+
{ [:required, ti.sym] }
|
348
|
+
|
349
|
+
rule param_sepd:
|
350
|
+
r(arg_sep + param[:n0]) { n0 }
|
351
|
+
|
352
|
+
rule param_sepds:
|
353
|
+
r(param[:n0] + param_sepd.*[:nrest] + arg_sep_opt) { [n0, *nrest] }
|
354
|
+
|
355
|
+
rule param_list:
|
356
|
+
r(T.params_begin[:tb] + T.params_end)
|
357
|
+
{ ast.args(tb, [], [], null, [], [], null, null) } # TODO: investigate removing
|
358
|
+
/ r(T.params_begin[:tb] + param_sepds[:plist] + T.params_end)
|
359
|
+
{
|
360
|
+
required = []
|
361
|
+
optional = []
|
362
|
+
rest = []
|
363
|
+
post = []
|
364
|
+
kwargs = []
|
365
|
+
kwrest = []
|
366
|
+
block = []
|
367
|
+
|
368
|
+
loop { plist[0] && plist[0][0] == :required || break; required.push(plist.shift[1]) }
|
369
|
+
loop { plist[0] && plist[0][0] == :optional || break; optional.push(plist.shift[1]) }
|
370
|
+
loop { plist[0] && plist[0][0] == :rest || break; rest .push(plist.shift[1]) }
|
371
|
+
loop { plist[0] && plist[0][0] == :required || break; post .push(plist.shift[1]) }
|
372
|
+
loop { plist[0] && plist[0][0] == :kwargs || break; kwargs .push(plist.shift[1]) }
|
373
|
+
loop { plist[0] && plist[0][0] == :kwrest || break; kwrest .push(plist.shift[1]) }
|
374
|
+
loop { plist[0] && plist[0][0] == :block || break; block .push(plist.shift[1]) }
|
375
|
+
|
376
|
+
required = required
|
377
|
+
optional = optional
|
378
|
+
rest = rest.first
|
379
|
+
post = post
|
380
|
+
kwargs = kwargs
|
381
|
+
kwrest = kwrest.first
|
382
|
+
block = block.first
|
383
|
+
|
384
|
+
# TODO: move these conversions to their respective reductions
|
385
|
+
block = block && ast.blkprm(tb, block)
|
386
|
+
|
387
|
+
ast.args(tb, required, optional, rest, post, kwargs, kwrest, block)
|
388
|
+
}
|
389
|
+
|
390
|
+
##
|
391
|
+
# Two-term operators
|
392
|
+
|
393
|
+
left_op_normal:
|
394
|
+
T.op_exp
|
395
|
+
/ T.op_mult / T.op_div / T.op_mod
|
396
|
+
/ T.op_plus / T.op_minus
|
397
|
+
/ T.op_compare
|
398
|
+
/ T.op_and / T.op_or
|
399
|
+
|
400
|
+
left_op_branch:
|
401
|
+
T.op_and / T.op_or
|
402
|
+
/ T.op_and_q / T.op_or_q / T.op_void_q
|
403
|
+
|
404
|
+
rule left_op: left_op_normal / left_op_branch
|
405
|
+
|
406
|
+
# Achieve left-associativity through iteration.
|
407
|
+
#
|
408
|
+
# PEG parsers get tripped up by left recursion
|
409
|
+
# (in contrast to LALR parsers, which prefer left recursion).
|
410
|
+
# This is a well-understood limitation, but refer to:
|
411
|
+
# http://www.dalnefre.com/wp/2011/05/parsing-expression-grammars-part-4/
|
412
|
+
# for an easy-to-understand explanation of this problem and this solution.
|
413
|
+
#
|
414
|
+
rule sepd_chained_atom:
|
415
|
+
r(C.spc_nl.* + left_op[:to] + C.spc_nl.* + expr_atom[:n1])
|
416
|
+
{ [to, n1] }
|
417
|
+
|
418
|
+
rule left_chained_atoms:
|
419
|
+
r(expr_atom[:n0] + sepd_chained_atom.+[:nlist])
|
420
|
+
{
|
421
|
+
nlist.unshift(n0)
|
422
|
+
nlist.flatten!
|
423
|
+
|
424
|
+
collapse(nlist, :t_op_exp)
|
425
|
+
collapse(nlist, :t_op_mult, :t_op_div, :t_op_mod)
|
426
|
+
collapse(nlist, :t_op_plus, :t_op_minus)
|
427
|
+
collapse(nlist, :t_op_compare)
|
428
|
+
collapse(nlist, :t_op_and, :t_op_or,
|
429
|
+
:t_op_and_q, :t_op_or_q, :t_op_void_q) |n0,op,n1| {
|
430
|
+
ast.branch_op(op, op.sym, n0, n1)
|
431
|
+
}
|
432
|
+
|
433
|
+
# There should only be one resulting node left
|
434
|
+
(nlist.count == 1)
|
435
|
+
|| raise("Failed to fully collapse left_chained_atoms: "nlist"")
|
436
|
+
|
437
|
+
nlist.first
|
438
|
+
}
|
439
|
+
|
440
|
+
##
|
441
|
+
# Invocations and Quests (soft-failing invocations)
|
442
|
+
|
443
|
+
rule left_invoke_op:
|
444
|
+
T.quest
|
445
|
+
/ T.dot
|
446
|
+
|
447
|
+
# Achieve left-associativity through iteration.
|
448
|
+
# (see left_chained_atoms).
|
449
|
+
#
|
450
|
+
rule sepd_chained_invocation:
|
451
|
+
r(C.spc_nl.* + left_invoke_op[:t0] + C.spc_nl.* + (invoke / op_invoke)[:n1])
|
452
|
+
{ [t0, n1] }
|
453
|
+
/ r(C.spc.*.token(:t_dot)[:t0] + elem_invoke[:n1])
|
454
|
+
{ [t0, n1] }
|
455
|
+
|
456
|
+
rule left_chained_invocations:
|
457
|
+
r(expr_atom_not_chained[:n0] + sepd_chained_invocation.+[:nlist])
|
458
|
+
{
|
459
|
+
nlist.unshift(n0)
|
460
|
+
nlist.send(:"flatten!")
|
461
|
+
|
462
|
+
collapse(nlist, :t_dot, :t_quest) |n0,op,n1| {
|
463
|
+
(op.type == :t_dot)
|
464
|
+
&? (n1.receiver=n0; n1)
|
465
|
+
?? ast.quest(op, n0, n1)
|
466
|
+
}
|
467
|
+
|
468
|
+
# There should only be one resulting node left
|
469
|
+
(nlist.count == 1)
|
470
|
+
|| raise("Failed to fully collapse left_chained_invocations: "nlist"")
|
471
|
+
|
472
|
+
nlist.first
|
473
|
+
}
|
474
|
+
|
475
|
+
##
|
476
|
+
# Unary operators
|
477
|
+
|
478
|
+
rule unary_operation:
|
479
|
+
r(T.op_not[:to] + expr_atom[:n0])
|
480
|
+
{ ast.invoke(to, n0, :"!", null) }
|
481
|
+
|
482
|
+
##
|
483
|
+
# Memes and etc..
|
484
|
+
|
485
|
+
# TODO: this should work without the call to 'inner'
|
486
|
+
# Currently, without this call, an unbalanced tidx_stack occurs
|
487
|
+
# in the Processor due to an extra :t_start capture symbol emitted
|
488
|
+
# by the BytecodeParser with no matching :t_end to clear it.
|
489
|
+
rule t_inln_sep: !T.arg_sep.inner + T.expr_sep
|
490
|
+
|
491
|
+
rule inln_sep: (C.spc.* + t_inln_sep + C.spc.*).+
|
492
|
+
rule inln_sep_opt: (C.spc / t_inln_sep).*
|
493
|
+
|
494
|
+
rule expr_sep: (C.spc.* + T.expr_sep + C.spc.*).+
|
495
|
+
rule expr_sep_opt: (C.spc / T.expr_sep).*
|
496
|
+
|
497
|
+
rule meme_inline_sepd_expr:
|
498
|
+
r(inln_sep + meme_expr[:n]) { n }
|
499
|
+
|
500
|
+
rule meme_inline_sepd_exprs:
|
501
|
+
r(meme_expr[:n0] + meme_inline_sepd_expr.*[:nrest] + inln_sep_opt)
|
502
|
+
{ [n0, *nrest] }
|
503
|
+
|
504
|
+
rule meme_sepd_expr:
|
505
|
+
r(expr_sep + meme_expr[:n]) { n }
|
506
|
+
|
507
|
+
rule meme_sepd_exprs:
|
508
|
+
r(meme_expr[:n0] + meme_sepd_expr.*[:nrest] + expr_sep_opt)
|
509
|
+
{ [n0, *nrest] }
|
510
|
+
|
511
|
+
rule meme_inline_expr_body:
|
512
|
+
r(inln_sep_opt + meme_inline_sepd_exprs[:nlist])
|
513
|
+
{ ast.block(nlist.first, nlist) }
|
514
|
+
|
515
|
+
rule meme_expr_body:
|
516
|
+
r(expr_sep_opt + meme_sepd_exprs[:nlist] + T.meme_end[:te])
|
517
|
+
{ ast.block(nlist.first, nlist) }
|
518
|
+
/ r(expr_sep_opt + T.meme_end[:te])
|
519
|
+
{ ast.null(te) }
|
520
|
+
|
521
|
+
rule paren_expr_body:
|
522
|
+
r(expr_sep_opt + meme_sepd_exprs[:nlist] + T.paren_end[:te])
|
523
|
+
{ nlist.count==1 &? nlist.first ?? ast.block(nlist.first, nlist) }
|
524
|
+
/ r(expr_sep_opt + T.paren_end[:te])
|
525
|
+
{ ast.null(te) }
|
526
|
+
|
527
|
+
rule paren_expr:
|
528
|
+
r(T.paren_begin + paren_expr_body[:n0]) { n0 }
|
529
|
+
|
530
|
+
rule meme_enclosed_expr_body:
|
531
|
+
r(T.meme_begin + meme_expr_body[:n0]) { n0 }
|
532
|
+
|
533
|
+
rule meme_either_body:
|
534
|
+
meme_enclosed_expr_body
|
535
|
+
/ meme_inline_expr_body
|
536
|
+
|
537
|
+
rule cmeme:
|
538
|
+
r(constant[:n0] + C.spc.* + T.meme_mark[:tm] + C.spc_nl.* + meme_inline_expr_body[:n1])
|
539
|
+
{ ast.cdecl(tm, n0, n1) }
|
540
|
+
|
541
|
+
rule meme_name:
|
542
|
+
id_as_symbol
|
543
|
+
/ lit_string_as_symbol
|
544
|
+
|
545
|
+
rule decorator:
|
546
|
+
r(meme_name[:ni] + arg_list.-[:na])
|
547
|
+
{ ast.deco(ni, ni, na) }
|
548
|
+
|
549
|
+
rule sepd_decorator:
|
550
|
+
r(C.spc.* + decorator[:n]) { n }
|
551
|
+
|
552
|
+
rule decorators_and_meme_name:
|
553
|
+
r(decorator[:n0] + sepd_decorator.*[:nrest])
|
554
|
+
{ ast.arrass(n0, [n0, *nrest].reverse) }
|
555
|
+
|
556
|
+
rule meme:
|
557
|
+
r(decorators_and_meme_name[:nd]
|
558
|
+
+ C.spc.* + T.meme_mark[:tm]
|
559
|
+
+ (r(C.spc_nl.* + param_list.-[:n]) { n })[:np]
|
560
|
+
+ C.spc_nl.* + meme_either_body[:nb])
|
561
|
+
{ ast.meme(tm, nd.body.shift.name, nd, np, nb) }
|
562
|
+
/ r(decorators_and_meme_name[:nd])
|
563
|
+
{ ast.meme(nd, nd.body.shift.name, nd, null, null) }
|
564
|
+
}
|