myco 0.1.0.dev
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 +7 -0
- data/LICENSE +2 -0
- data/bin/myco +7 -0
- data/lib/myco/backtrace.rb +56 -0
- data/lib/myco/bootstrap/component.rb +142 -0
- data/lib/myco/bootstrap/empty_object.rb +4 -0
- data/lib/myco/bootstrap/file_toplevel.rb +5 -0
- data/lib/myco/bootstrap/find_constant.rb +86 -0
- data/lib/myco/bootstrap/instance.rb +52 -0
- data/lib/myco/bootstrap/meme.rb +160 -0
- data/lib/myco/bootstrap/void.rb +40 -0
- data/lib/myco/bootstrap.my +15 -0
- data/lib/myco/bootstrap.rb +10 -0
- data/lib/myco/command.my +33 -0
- data/lib/myco/core/BasicObject.my +46 -0
- data/lib/myco/core/Category.my +5 -0
- data/lib/myco/core/Decorator.my +18 -0
- data/lib/myco/core/FileToplevel.my +23 -0
- data/lib/myco/core/Object.my +24 -0
- data/lib/myco/core/Switch.my +31 -0
- data/lib/myco/eval.rb +63 -0
- data/lib/myco/parser/ast/constant_access.rb +29 -0
- data/lib/myco/parser/ast/constant_define.rb +40 -0
- data/lib/myco/parser/ast/constant_reopen.rb +47 -0
- data/lib/myco/parser/ast/declare_category.rb +51 -0
- data/lib/myco/parser/ast/declare_decorator.rb +35 -0
- data/lib/myco/parser/ast/declare_file.rb +54 -0
- data/lib/myco/parser/ast/declare_meme.rb +44 -0
- data/lib/myco/parser/ast/declare_object.rb +75 -0
- data/lib/myco/parser/ast/declare_string.rb +37 -0
- data/lib/myco/parser/ast/invoke.rb +66 -0
- data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +38 -0
- data/lib/myco/parser/ast/misc.rb +61 -0
- data/lib/myco/parser/ast/myco_module_scope.rb +58 -0
- data/lib/myco/parser/ast/quest.rb +82 -0
- data/lib/myco/parser/ast.rb +15 -0
- data/lib/myco/parser/builder.output +3995 -0
- data/lib/myco/parser/builder.racc +585 -0
- data/lib/myco/parser/builder.rb +1592 -0
- data/lib/myco/parser/lexer.rb +2306 -0
- data/lib/myco/parser/lexer.rl +393 -0
- data/lib/myco/parser/lexer_char_classes.rl +56 -0
- data/lib/myco/parser/lexer_common.rb +95 -0
- data/lib/myco/parser/lexer_skeleton.rl +154 -0
- data/lib/myco/parser/peg_parser.kpeg +759 -0
- data/lib/myco/parser/peg_parser.rb +7094 -0
- data/lib/myco/parser.rb +40 -0
- data/lib/myco/tools/OptionParser.my +38 -0
- data/lib/myco/tools/mycompile.my +51 -0
- data/lib/myco/toolset.rb +16 -0
- data/lib/myco/version.rb +22 -0
- data/lib/myco.rb +15 -0
- metadata +247 -0
@@ -0,0 +1,585 @@
|
|
1
|
+
class CodeTools::Builder
|
2
|
+
token T_CONSTANT T_IDENTIFIER T_SYMBOL
|
3
|
+
T_NULL T_VOID T_TRUE T_FALSE
|
4
|
+
T_INTEGER T_FLOAT
|
5
|
+
T_SELF
|
6
|
+
T_OP_PLUS T_OP_MINUS T_OP_MULT T_OP_DIV T_OP_MOD T_OP_EXP
|
7
|
+
T_OP_COMPARE T_OP_AND T_OP_OR
|
8
|
+
T_OP_TOPROC
|
9
|
+
T_DOT T_QUEST
|
10
|
+
T_DEFINE T_CONST_SEP T_EXPR_SEP T_ARG_SEP T_SCOPE T_ASSIGN
|
11
|
+
T_DECLARE_BEGIN T_DECLARE_END
|
12
|
+
T_DECLSTR_BEGIN T_DECLSTR_END T_DECLSTR_BODY
|
13
|
+
T_STRING_BEGIN T_STRING_END T_STRING_BODY
|
14
|
+
T_SYMSTR_BEGIN T_SYMSTR_END T_SYMSTR_BODY
|
15
|
+
T_DECLID_TAG T_DECLID_VALUE
|
16
|
+
T_CATEGORY_BEGIN T_CATEGORY_END T_CATEGORY_BODY
|
17
|
+
T_MEME_BEGIN T_MEME_END
|
18
|
+
T_PARAMS_BEGIN T_PARAMS_END
|
19
|
+
T_ARGS_BEGIN T_ARGS_END
|
20
|
+
T_PAREN_BEGIN T_PAREN_END
|
21
|
+
T_ARRAY_BEGIN T_ARRAY_END
|
22
|
+
T_FILE_END
|
23
|
+
|
24
|
+
options no_result_var
|
25
|
+
|
26
|
+
|
27
|
+
prechigh
|
28
|
+
left T_SCOPE
|
29
|
+
left T_DOT T_QUEST
|
30
|
+
left T_OP_EXP
|
31
|
+
left T_OP_MULT T_OP_DIV T_OP_MOD
|
32
|
+
left T_OP_PLUS T_OP_MINUS
|
33
|
+
left T_OP_COMPARE
|
34
|
+
left T_OP_AND T_OP_OR
|
35
|
+
left T_ASSIGN
|
36
|
+
preclow
|
37
|
+
|
38
|
+
|
39
|
+
rule
|
40
|
+
main:
|
41
|
+
declobj_expr_body { ast(:declfile, val[0], val[0]) }
|
42
|
+
;
|
43
|
+
|
44
|
+
|
45
|
+
# Expressions allowable inside object declarations
|
46
|
+
declobj_expr:
|
47
|
+
cdefn
|
48
|
+
| cmeme
|
49
|
+
| meme
|
50
|
+
| deco
|
51
|
+
| declobj
|
52
|
+
| declstr
|
53
|
+
| declid
|
54
|
+
| category
|
55
|
+
| constant
|
56
|
+
;
|
57
|
+
|
58
|
+
# Expressions allowable inside memes
|
59
|
+
meme_expr:
|
60
|
+
declobj
|
61
|
+
| declstr
|
62
|
+
| arg_expr
|
63
|
+
;
|
64
|
+
|
65
|
+
# Expressions allowable as function arguments
|
66
|
+
arg_expr:
|
67
|
+
arg_expr_atom
|
68
|
+
| two_term_expr
|
69
|
+
| assignment
|
70
|
+
| nest_assignment
|
71
|
+
| quest_self
|
72
|
+
| lit_string
|
73
|
+
| lit_symstr
|
74
|
+
| dyn_string
|
75
|
+
| dyn_symstr
|
76
|
+
;
|
77
|
+
|
78
|
+
# Expressions allowable as function arguments and in other assemblies
|
79
|
+
arg_expr_atom:
|
80
|
+
paren_expr
|
81
|
+
| call
|
82
|
+
| quest
|
83
|
+
| constant
|
84
|
+
| id_as_lambig
|
85
|
+
| lit_null
|
86
|
+
| lit_void
|
87
|
+
| lit_true
|
88
|
+
| lit_false
|
89
|
+
| lit_integer
|
90
|
+
| lit_float
|
91
|
+
| lit_symbol
|
92
|
+
| lit_array
|
93
|
+
| lit_self
|
94
|
+
;
|
95
|
+
|
96
|
+
##
|
97
|
+
# Simple literals
|
98
|
+
|
99
|
+
lit_null:
|
100
|
+
T_NULL { ast(:null, val[0]) }
|
101
|
+
;
|
102
|
+
|
103
|
+
lit_void:
|
104
|
+
T_VOID { ast(:void, val[0]) }
|
105
|
+
;
|
106
|
+
|
107
|
+
lit_true:
|
108
|
+
T_TRUE { ast(:true, val[0]) }
|
109
|
+
;
|
110
|
+
|
111
|
+
lit_false:
|
112
|
+
T_FALSE { ast(:false, val[0]) }
|
113
|
+
;
|
114
|
+
|
115
|
+
lit_integer:
|
116
|
+
T_INTEGER { ast(:lit, val[0], Integer(val[0][1])) }
|
117
|
+
;
|
118
|
+
|
119
|
+
lit_float:
|
120
|
+
T_FLOAT { ast(:lit, val[0], Float(val[0][1])) }
|
121
|
+
;
|
122
|
+
|
123
|
+
lit_symbol:
|
124
|
+
T_SYMBOL { ast(:lit, val[0], val[0][1].to_sym) }
|
125
|
+
;
|
126
|
+
|
127
|
+
lit_string:
|
128
|
+
T_STRING_BEGIN T_STRING_BODY T_STRING_END { val[1] }
|
129
|
+
{ ast(:lit, val[1], encode_escapes(val[1][1])) }
|
130
|
+
;
|
131
|
+
|
132
|
+
lit_string_as_symbol: # Used in contexts where a bare string is a symbol
|
133
|
+
T_STRING_BEGIN T_STRING_BODY T_STRING_END { val[1] }
|
134
|
+
{ ast(:lit, val[1], encode_escapes(val[1][1]).to_sym) }
|
135
|
+
;
|
136
|
+
|
137
|
+
lit_symstr:
|
138
|
+
T_SYMSTR_BEGIN T_SYMSTR_BODY T_SYMSTR_END
|
139
|
+
{ ast(:lit, val[1], encode_escapes(val[1][1]).to_sym) }
|
140
|
+
;
|
141
|
+
|
142
|
+
lit_self:
|
143
|
+
T_SELF { ast(:self, val[0]) }
|
144
|
+
;
|
145
|
+
|
146
|
+
##
|
147
|
+
# String interpolations / juxtapositions
|
148
|
+
|
149
|
+
dyn_string_part:
|
150
|
+
arg_expr_atom lit_string { [ast(:evstr, val[0], val[0]), val[1]] }
|
151
|
+
;
|
152
|
+
|
153
|
+
dyn_string_parts:
|
154
|
+
dyn_string_parts dyn_string_part { [*val[0], *val[1]] }
|
155
|
+
| dyn_string_part { val[0] }
|
156
|
+
;
|
157
|
+
|
158
|
+
dyn_string:
|
159
|
+
lit_string dyn_string_parts { ast(:dstr, val[0], val[0].value, val[1]) }
|
160
|
+
;
|
161
|
+
|
162
|
+
dyn_symstr:
|
163
|
+
lit_symstr dyn_string_parts { ast(:dsym, val[0], val[0].value.to_s, val[1])}
|
164
|
+
;
|
165
|
+
|
166
|
+
##
|
167
|
+
# Constants
|
168
|
+
|
169
|
+
constant:
|
170
|
+
constant T_SCOPE T_CONSTANT { ast(:colon2, val[1], val[0], val[2][1].to_sym) }
|
171
|
+
| T_SCOPE T_CONSTANT { ast(:colon3, val[0], val[1][1].to_sym) }
|
172
|
+
| T_CONSTANT { ast(:const, val[0], val[0][1].to_sym) }
|
173
|
+
;
|
174
|
+
|
175
|
+
constant_list_:
|
176
|
+
constant_list_ T_CONST_SEP constant { [*val[0], val[2]] }
|
177
|
+
| constant { val }
|
178
|
+
;
|
179
|
+
|
180
|
+
constant_list:
|
181
|
+
constant_list_
|
182
|
+
{ ast(:array, val[0][0], val[0]) }
|
183
|
+
;
|
184
|
+
|
185
|
+
##
|
186
|
+
# Bare identifiers
|
187
|
+
|
188
|
+
id_as_symbol: # Used in contexts where a bare identifier is a symbol
|
189
|
+
T_IDENTIFIER
|
190
|
+
{ ast(:lit, val[0], val[0][1].to_sym) }
|
191
|
+
;
|
192
|
+
|
193
|
+
id_as_lambig: # Ambiguous - could be local variable or call without args
|
194
|
+
T_IDENTIFIER
|
195
|
+
{ ast(:lambig, val[0], val[0][1].to_sym) }
|
196
|
+
;
|
197
|
+
|
198
|
+
##
|
199
|
+
# Assignment
|
200
|
+
|
201
|
+
assignment:
|
202
|
+
T_IDENTIFIER T_ASSIGN arg_expr
|
203
|
+
{ ast(:lasgn, val[1], val[0][1].to_sym, val[2]) }
|
204
|
+
;
|
205
|
+
|
206
|
+
nest_assignment:
|
207
|
+
arg_expr T_DOT T_IDENTIFIER T_ASSIGN arg_expr
|
208
|
+
{ ast(:call, val[3], val[0], :"#{val[2][1]}=", ast(:array, val[4], [val[4]])) }
|
209
|
+
;
|
210
|
+
|
211
|
+
|
212
|
+
##
|
213
|
+
# Method calls
|
214
|
+
|
215
|
+
call:
|
216
|
+
nest_call
|
217
|
+
| call_with_args
|
218
|
+
| nest_call_with_args
|
219
|
+
| call_iter
|
220
|
+
| nest_call_iter
|
221
|
+
;
|
222
|
+
|
223
|
+
nest_call:
|
224
|
+
arg_expr T_DOT T_IDENTIFIER
|
225
|
+
{ ast(:call, val[2], val[0], val[2][1].to_sym, ast(:array, val[2], [])) }
|
226
|
+
;
|
227
|
+
|
228
|
+
call_with_args:
|
229
|
+
T_IDENTIFIER arg_list
|
230
|
+
{ ast(:call, val[1], ast(:self, val[0]), val[0][1].to_sym, val[1]) }
|
231
|
+
;
|
232
|
+
|
233
|
+
nest_call_with_args:
|
234
|
+
arg_expr T_DOT T_IDENTIFIER arg_list
|
235
|
+
{ ast(:call, val[3], val[0], val[2][1].to_sym, val[3]) }
|
236
|
+
;
|
237
|
+
|
238
|
+
call_iter_body:
|
239
|
+
T_MEME_BEGIN meme_expr_body
|
240
|
+
{ ast(:scope, val[0], nil, val[1], nil) }
|
241
|
+
| param_list T_MEME_BEGIN meme_expr_body
|
242
|
+
{ ast(:scope, val[1], val[0], val[2], nil) }
|
243
|
+
;
|
244
|
+
|
245
|
+
call_iter:
|
246
|
+
T_IDENTIFIER call_iter_body
|
247
|
+
{ ast(:iter, val[0], ast(:call, val[0], ast(:self, val[0]), val[0][1].to_sym, nil), val[1]) }
|
248
|
+
| T_IDENTIFIER arg_list call_iter_body
|
249
|
+
{ ast(:iter, val[0], ast(:call, val[0], ast(:self, val[0]), val[0][1].to_sym, val[1]), val[2]) }
|
250
|
+
;
|
251
|
+
|
252
|
+
nest_call_iter:
|
253
|
+
arg_expr T_DOT T_IDENTIFIER call_iter_body
|
254
|
+
{ ast(:iter, val[2], ast(:call, val[2], val[0], val[2][1].to_sym, nil), val[3]) }
|
255
|
+
| arg_expr T_DOT T_IDENTIFIER arg_list call_iter_body
|
256
|
+
{ ast(:iter, val[2], ast(:call, val[2], val[0], val[2][1].to_sym, val[3]), val[4]) }
|
257
|
+
;
|
258
|
+
|
259
|
+
##
|
260
|
+
# Method quests
|
261
|
+
|
262
|
+
questable:
|
263
|
+
T_IDENTIFIER
|
264
|
+
{ ast(:quest, val[0], ast(:self, val[0]), ast(:call, val[0], ast(:self, val[0]), val[0][1].to_sym, nil)) }
|
265
|
+
| call_with_args
|
266
|
+
{ ast(:quest, val[0], ast(:self, val[0]), val[0]) }
|
267
|
+
| call_iter
|
268
|
+
{ ast(:quest, val[0], ast(:self, val[0]), val[0]) }
|
269
|
+
;
|
270
|
+
|
271
|
+
quest_self:
|
272
|
+
T_QUEST questable { val[1] }
|
273
|
+
;
|
274
|
+
|
275
|
+
quest:
|
276
|
+
arg_expr_atom T_QUEST questable { val[2].receiver = val[0]; val[2] }
|
277
|
+
;
|
278
|
+
|
279
|
+
##
|
280
|
+
# Argument lists
|
281
|
+
|
282
|
+
arg_to_proc:
|
283
|
+
T_OP_TOPROC arg_expr_atom { ast(:block_pass, val[0], nil, val[1]) }
|
284
|
+
;
|
285
|
+
|
286
|
+
arg_splat:
|
287
|
+
T_OP_MULT arg_expr_atom { ast(:splat, val[0], val[1]) }
|
288
|
+
;
|
289
|
+
|
290
|
+
in_arg_expr:
|
291
|
+
arg_expr
|
292
|
+
| arg_splat
|
293
|
+
| arg_to_proc
|
294
|
+
;
|
295
|
+
|
296
|
+
in_arg_sepd_expr:
|
297
|
+
T_ARG_SEP { nil }
|
298
|
+
| T_ARG_SEP in_arg_expr { val[1] }
|
299
|
+
;
|
300
|
+
|
301
|
+
in_arg_sepd_exprs:
|
302
|
+
in_arg_sepd_exprs in_arg_sepd_expr { [*val[0], val[1]].compact }
|
303
|
+
| in_arg_sepd_expr { val.compact }
|
304
|
+
;
|
305
|
+
|
306
|
+
arg_list_:
|
307
|
+
in_arg_expr in_arg_sepd_exprs T_ARGS_END { ast(:array, val[0], [val[0], *val[1]]) }
|
308
|
+
| in_arg_sepd_exprs T_ARGS_END { val[0].empty? ? ast(:null, val[1]) : ast(:array, val[0][0], val[0]) }
|
309
|
+
| in_arg_expr T_ARGS_END { ast(:array, val[0], [val[0]]) }
|
310
|
+
| T_ARGS_END { ast(:array, val[0], []) }
|
311
|
+
;
|
312
|
+
|
313
|
+
arg_list:
|
314
|
+
T_ARGS_BEGIN arg_list_ { args_assemble(val[0], val[1]) }
|
315
|
+
;
|
316
|
+
|
317
|
+
##
|
318
|
+
# Parameter lists
|
319
|
+
|
320
|
+
param:
|
321
|
+
T_IDENTIFIER
|
322
|
+
{ [:required, val[0][1].to_sym] }
|
323
|
+
| T_IDENTIFIER T_ASSIGN arg_expr
|
324
|
+
{ [:optional, ast(:lasgn, val[1], val[0][1].to_sym, val[2])] }
|
325
|
+
| T_OP_MULT T_IDENTIFIER
|
326
|
+
{ [:rest, val[1][1].to_sym] }
|
327
|
+
| T_OP_TOPROC T_IDENTIFIER
|
328
|
+
{ [:block, val[1][1].to_sym] }
|
329
|
+
;
|
330
|
+
|
331
|
+
param_sepd:
|
332
|
+
T_ARG_SEP param { val[1] }
|
333
|
+
| T_ARG_SEP { nil }
|
334
|
+
;
|
335
|
+
|
336
|
+
param_sepds:
|
337
|
+
param_sepds param_sepd { [*val[0], val[1]].compact }
|
338
|
+
| param_sepd { val.compact }
|
339
|
+
;
|
340
|
+
|
341
|
+
param_list_:
|
342
|
+
param param_sepds T_PARAMS_END { [val[0], *val[1]] }
|
343
|
+
| param_sepds T_PARAMS_END { val[0] }
|
344
|
+
| param T_PARAMS_END { [val[0]] }
|
345
|
+
| T_PARAMS_END { [] }
|
346
|
+
;
|
347
|
+
|
348
|
+
param_list:
|
349
|
+
T_PARAMS_BEGIN param_list_
|
350
|
+
{
|
351
|
+
required, optional, rest, block = 4.times.map { Array.new }
|
352
|
+
|
353
|
+
required << val[1].shift[1] while val[1][0] && val[1][0][0] == :required
|
354
|
+
optional << val[1].shift[1] while val[1][0] && val[1][0][0] == :optional
|
355
|
+
optional = optional.empty? ? nil : ast(:block, val[0], optional)
|
356
|
+
rest << val[1].shift[1] while val[1][0] && val[1][0][0] == :rest
|
357
|
+
block << val[1].shift[1] while val[1][0] && val[1][0][0] == :block
|
358
|
+
|
359
|
+
ast(:args, val[0], required, optional, rest.first, nil, nil, nil, block.first)
|
360
|
+
}
|
361
|
+
;
|
362
|
+
|
363
|
+
##
|
364
|
+
# Array literals
|
365
|
+
|
366
|
+
lit_array_:
|
367
|
+
in_arg_expr in_arg_sepd_exprs T_ARRAY_END { ast(:array, val[0], [val[0], *val[1]]) }
|
368
|
+
| in_arg_sepd_exprs T_ARRAY_END { val[0].empty? ? ast(:null, val[1]) : ast(:array, val[0][0], val[0]) }
|
369
|
+
| in_arg_expr T_ARRAY_END { ast(:array, val[0], [val[0]]) }
|
370
|
+
| T_ARRAY_END { ast(:array, val[0], []) }
|
371
|
+
;
|
372
|
+
|
373
|
+
lit_array:
|
374
|
+
T_ARRAY_BEGIN lit_array_ { args_assemble(val[0], val[1]) }
|
375
|
+
;
|
376
|
+
|
377
|
+
##
|
378
|
+
# Two-term operators
|
379
|
+
|
380
|
+
two_term_expr:
|
381
|
+
arg_expr T_OP_PLUS arg_expr
|
382
|
+
{ ast(:call, val[1], val[0], :'+', ast(:array, val[2], [val[2]])) }
|
383
|
+
| arg_expr T_OP_MINUS arg_expr
|
384
|
+
{ ast(:call, val[1], val[0], :'-', ast(:array, val[2], [val[2]])) }
|
385
|
+
| arg_expr T_OP_MULT arg_expr
|
386
|
+
{ ast(:call, val[1], val[0], :'*', ast(:array, val[2], [val[2]])) }
|
387
|
+
| arg_expr T_OP_DIV arg_expr
|
388
|
+
{ ast(:call, val[1], val[0], :'/', ast(:array, val[2], [val[2]])) }
|
389
|
+
| arg_expr T_OP_MOD arg_expr
|
390
|
+
{ ast(:call, val[1], val[0], :'%', ast(:array, val[2], [val[2]])) }
|
391
|
+
| arg_expr T_OP_EXP arg_expr
|
392
|
+
{ ast(:call, val[1], val[0], :'**', ast(:array, val[2], [val[2]])) }
|
393
|
+
| arg_expr T_OP_COMPARE arg_expr
|
394
|
+
{ ast(:call, val[1], val[0], val[1][1].to_sym, ast(:array, val[2], [val[2]])) }
|
395
|
+
| arg_expr T_OP_AND arg_expr
|
396
|
+
{ ast(:and, val[1], val[0], val[2]) }
|
397
|
+
| arg_expr T_OP_OR arg_expr
|
398
|
+
{ ast(:or, val[1], val[0], val[2]) }
|
399
|
+
;
|
400
|
+
|
401
|
+
##
|
402
|
+
# Object declarations
|
403
|
+
|
404
|
+
declobj_sepd_expr:
|
405
|
+
T_EXPR_SEP declobj_expr { val[1] }
|
406
|
+
| T_EXPR_SEP { nil }
|
407
|
+
;
|
408
|
+
|
409
|
+
declobj_sepd_exprs:
|
410
|
+
declobj_sepd_exprs declobj_sepd_expr { [*val[0], val[1]].compact }
|
411
|
+
| declobj_sepd_expr { val.compact }
|
412
|
+
;
|
413
|
+
|
414
|
+
declobj_expr_body:
|
415
|
+
declobj_expr declobj_sepd_exprs T_DECLARE_END { ast(:block, val[0], [val[0], *val[1]]) }
|
416
|
+
| declobj_sepd_exprs T_DECLARE_END { val[0].empty? ? ast(:null, val[1]) : ast(:block, val[0][0], val[0]) }
|
417
|
+
| declobj_expr T_DECLARE_END { ast(:block, val[0], [val[0]]) }
|
418
|
+
| T_DECLARE_END { ast(:null, val[0]) }
|
419
|
+
;
|
420
|
+
|
421
|
+
declobj:
|
422
|
+
constant_list T_DECLARE_BEGIN declobj_expr_body
|
423
|
+
{ ast(:declobj, val[1], val[0], val[2]) }
|
424
|
+
;
|
425
|
+
|
426
|
+
cdefn:
|
427
|
+
constant T_DEFINE declobj
|
428
|
+
{ ast(:cdefn, val[1], val[0], val[2]) }
|
429
|
+
;
|
430
|
+
|
431
|
+
##
|
432
|
+
# String declarations
|
433
|
+
|
434
|
+
declstr_body:
|
435
|
+
T_DECLSTR_BODY
|
436
|
+
{ ast(:str, val[0], val[0][1]) }
|
437
|
+
;
|
438
|
+
|
439
|
+
declstr:
|
440
|
+
constant_list T_DECLSTR_BEGIN declstr_body T_DECLSTR_END
|
441
|
+
{ ast(:declstr, val[1], val[0], val[2]) }
|
442
|
+
;
|
443
|
+
|
444
|
+
##
|
445
|
+
# Memes and etc..
|
446
|
+
|
447
|
+
meme_sepd_expr:
|
448
|
+
T_EXPR_SEP meme_expr { val[1] }
|
449
|
+
| T_EXPR_SEP { nil }
|
450
|
+
;
|
451
|
+
|
452
|
+
meme_sepd_exprs:
|
453
|
+
meme_sepd_exprs meme_sepd_expr { [*val[0], val[1]].compact }
|
454
|
+
| meme_sepd_expr { val.compact }
|
455
|
+
;
|
456
|
+
|
457
|
+
meme_expr_body:
|
458
|
+
meme_expr meme_sepd_exprs T_MEME_END { ast(:block, val[0], [val[0], *val[1]]) }
|
459
|
+
| meme_sepd_exprs T_MEME_END { val[0].empty? ? ast(:null, val[1]) : ast(:block, val[0][0], val[0]) }
|
460
|
+
| meme_expr T_MEME_END { ast(:block, val[0], [val[0]]) }
|
461
|
+
| T_MEME_END { ast(:null, val[0]) }
|
462
|
+
;
|
463
|
+
|
464
|
+
paren_expr_body:
|
465
|
+
meme_expr meme_sepd_exprs T_PAREN_END { ast(:block, val[0], [val[0], *val[1]]) }
|
466
|
+
| meme_sepd_exprs T_PAREN_END { val[0].empty? ? ast(:null, val[1]) : ast(:block, val[0][0], val[0]) }
|
467
|
+
| meme_expr T_PAREN_END { val[0] }
|
468
|
+
| T_PAREN_END { ast(:null, val[0]) }
|
469
|
+
;
|
470
|
+
|
471
|
+
paren_expr:
|
472
|
+
T_PAREN_BEGIN paren_expr_body { val[1] }
|
473
|
+
;
|
474
|
+
|
475
|
+
cmeme:
|
476
|
+
constant T_MEME_BEGIN meme_expr_body
|
477
|
+
{ ast(:cdecl, val[1], val[0], val[2]) }
|
478
|
+
;
|
479
|
+
|
480
|
+
meme_name:
|
481
|
+
id_as_symbol
|
482
|
+
| lit_string_as_symbol
|
483
|
+
;
|
484
|
+
|
485
|
+
meme:
|
486
|
+
meme_name param_list T_MEME_BEGIN meme_expr_body
|
487
|
+
{ ast(:meme, val[1], val[0], nil, val[1], val[3]) }
|
488
|
+
| meme_name T_MEME_BEGIN meme_expr_body
|
489
|
+
{ ast(:meme, val[1], val[0], nil, nil, val[2]) }
|
490
|
+
| meme_name
|
491
|
+
{ ast(:meme, val[0], val[0], nil, nil, nil) }
|
492
|
+
;
|
493
|
+
|
494
|
+
deco_able:
|
495
|
+
meme
|
496
|
+
| deco
|
497
|
+
;
|
498
|
+
|
499
|
+
deco:
|
500
|
+
T_IDENTIFIER deco_able
|
501
|
+
{
|
502
|
+
val[1].decorations.body.push ast(:lit, val[0], val[0][1].to_sym)
|
503
|
+
val[1]
|
504
|
+
}
|
505
|
+
;
|
506
|
+
|
507
|
+
declid:
|
508
|
+
T_DECLID_TAG T_DECLID_VALUE
|
509
|
+
{ ast(:declid, val[0], ast(:lit, val[1], val[1][1].to_sym)) }
|
510
|
+
;
|
511
|
+
|
512
|
+
category:
|
513
|
+
T_CATEGORY_BEGIN T_CATEGORY_BODY T_CATEGORY_END
|
514
|
+
{ ast(:category, val[0], ast(:lit, val[1], val[1][1].to_sym)) }
|
515
|
+
;
|
516
|
+
|
517
|
+
---- inner
|
518
|
+
attr_accessor :processor
|
519
|
+
|
520
|
+
def parse string
|
521
|
+
@tokens = Myco::ToolSet::Parser::Lexer.new(string).lex
|
522
|
+
do_parse
|
523
|
+
end
|
524
|
+
|
525
|
+
def next_token
|
526
|
+
tok = @tokens.shift
|
527
|
+
[ tok[0], tok ] if tok
|
528
|
+
end
|
529
|
+
|
530
|
+
# Generate an AST::Node of the given type
|
531
|
+
#
|
532
|
+
# @param type [Symbol] The type of AST::Node to generate
|
533
|
+
# @param locator [Array,AST::Node] The object from which to determine the
|
534
|
+
# source location where the AST::Node is to reference as its location.
|
535
|
+
# If it is an lexer token (Array), the location is pulled from it;
|
536
|
+
# if it is an AST::Node, the location for this node will be copied from it.
|
537
|
+
# @param args [Array] The arguments to pass to the processor method that
|
538
|
+
# will generate the AST::Node; usually the same as the arguments that will
|
539
|
+
# eventually be passed to the AST::Node's constructor.
|
540
|
+
#
|
541
|
+
def ast type, locator, *args
|
542
|
+
# TODO: integrate columns from location instead of just rows
|
543
|
+
line = locator.is_a?(Array) ? locator[2].first : locator.line
|
544
|
+
@processor.send :"process_#{type}", line, *args
|
545
|
+
end
|
546
|
+
|
547
|
+
def encode_escapes str
|
548
|
+
str.gsub /\\(.)/ do "#{$1}" end
|
549
|
+
end
|
550
|
+
|
551
|
+
# Given a locator and an ast(:array) node, refactor the splat-related nodes
|
552
|
+
# in a copy of the original node body and return a replacement for the node.
|
553
|
+
def args_assemble loc, orig_node
|
554
|
+
list = orig_node.body.dup
|
555
|
+
tmp = []
|
556
|
+
|
557
|
+
special_type_check = Proc.new { |x|
|
558
|
+
case x
|
559
|
+
when AST::SplatValue; :splat
|
560
|
+
when AST::ConcatArgs; :argscat
|
561
|
+
when AST::PushArgs; :argspush
|
562
|
+
when AST::BlockPass; :block_pass
|
563
|
+
else; nil
|
564
|
+
end
|
565
|
+
}
|
566
|
+
|
567
|
+
# Get the original value in the new_node
|
568
|
+
tmp << list.shift until list.empty? or special_type_check.call(list.first)
|
569
|
+
new_node = tmp.empty? ? list.shift : ast(:array, loc, tmp)
|
570
|
+
|
571
|
+
# Continue to reduce until all elements have been used
|
572
|
+
until list.empty?
|
573
|
+
arg = list.shift
|
574
|
+
type = special_type_check.call(arg)
|
575
|
+
if type == :block_pass
|
576
|
+
new_node = arg.tap { |n| n.arguments = new_node }
|
577
|
+
elsif type != nil
|
578
|
+
new_node = ast(:argscat, loc, new_node, arg)
|
579
|
+
else
|
580
|
+
new_node = ast(:argspush, loc, new_node, arg)
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
new_node || orig_node
|
585
|
+
end
|