myco 0.1.0.dev → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -7
  2. data/LICENSE +1 -1
  3. data/README.md +79 -0
  4. data/lib/myco/backtrace.rb +1 -1
  5. data/lib/myco/bootstrap/component.rb +78 -39
  6. data/lib/myco/bootstrap/find_constant.rb +12 -1
  7. data/lib/myco/bootstrap/instance.rb +5 -12
  8. data/lib/myco/bootstrap/meme.rb +176 -28
  9. data/lib/myco/bootstrap.my +8 -7
  10. data/lib/myco/code_loader.rb +332 -0
  11. data/lib/myco/command/inoculate.my +83 -0
  12. data/lib/myco/command.my +26 -26
  13. data/lib/myco/core/BasicDecorators.my +62 -0
  14. data/lib/myco/core/BasicObject.my +12 -34
  15. data/lib/myco/core/Decorator.my +1 -0
  16. data/lib/myco/core/FileToplevel.my +0 -3
  17. data/lib/myco/core/Myco.my +4 -0
  18. data/lib/myco/core/Object.my +6 -4
  19. data/lib/myco/eval.rb +17 -18
  20. data/lib/myco/misc.rb +16 -0
  21. data/lib/myco/parser/ast/argument_assembly.rb +76 -0
  22. data/lib/myco/parser/ast/array_assembly.rb +57 -0
  23. data/lib/myco/parser/ast/branch_operator.rb +73 -0
  24. data/lib/myco/parser/ast/constant_access.rb +4 -18
  25. data/lib/myco/parser/ast/constant_define.rb +3 -3
  26. data/lib/myco/parser/ast/constant_reopen.rb +12 -13
  27. data/lib/myco/parser/ast/declare_category.rb +8 -6
  28. data/lib/myco/parser/ast/declare_decorator.rb +4 -4
  29. data/lib/myco/parser/ast/declare_file.rb +4 -4
  30. data/lib/myco/parser/ast/declare_meme.rb +53 -11
  31. data/lib/myco/parser/ast/declare_object.rb +9 -7
  32. data/lib/myco/parser/ast/declare_string.rb +5 -5
  33. data/lib/myco/parser/ast/invoke.rb +18 -36
  34. data/lib/myco/parser/ast/invoke_method.rb +28 -0
  35. data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +9 -13
  36. data/lib/myco/parser/ast/misc.rb +128 -33
  37. data/lib/myco/parser/ast/myco_module_scope.rb +26 -0
  38. data/lib/myco/parser/ast/quest.rb +3 -3
  39. data/lib/myco/parser/ast/to_ruby/array_assembly.rb +15 -0
  40. data/lib/myco/parser/ast/to_ruby/block.rb +14 -0
  41. data/lib/myco/parser/ast/to_ruby/block_pass.rb +6 -0
  42. data/lib/myco/parser/ast/to_ruby/branch_operator.rb +9 -0
  43. data/lib/myco/parser/ast/to_ruby/constant_access.rb +10 -0
  44. data/lib/myco/parser/ast/to_ruby/constant_assignment.rb +6 -0
  45. data/lib/myco/parser/ast/to_ruby/constant_define.rb +9 -0
  46. data/lib/myco/parser/ast/to_ruby/constant_reopen.rb +6 -0
  47. data/lib/myco/parser/ast/to_ruby/declare_category.rb +7 -0
  48. data/lib/myco/parser/ast/to_ruby/declare_decorator.rb +6 -0
  49. data/lib/myco/parser/ast/to_ruby/declare_file.rb +6 -0
  50. data/lib/myco/parser/ast/to_ruby/declare_meme.rb +16 -0
  51. data/lib/myco/parser/ast/to_ruby/declare_object.rb +8 -0
  52. data/lib/myco/parser/ast/to_ruby/declare_string.rb +6 -0
  53. data/lib/myco/parser/ast/to_ruby/dynamic_string.rb +14 -0
  54. data/lib/myco/parser/ast/to_ruby/dynamic_symbol.rb +7 -0
  55. data/lib/myco/parser/ast/to_ruby/eval_expression.rb +6 -0
  56. data/lib/myco/parser/ast/to_ruby/false_literal.rb +6 -0
  57. data/lib/myco/parser/ast/to_ruby/hash_literal.rb +16 -0
  58. data/lib/myco/parser/ast/to_ruby/invoke.rb +6 -0
  59. data/lib/myco/parser/ast/to_ruby/invoke_method.rb +35 -0
  60. data/lib/myco/parser/ast/to_ruby/iter.rb +10 -0
  61. data/lib/myco/parser/ast/to_ruby/local_variable_access_ambiguous.rb +16 -0
  62. data/lib/myco/parser/ast/to_ruby/local_variable_assignment.rb +8 -0
  63. data/lib/myco/parser/ast/to_ruby/myco_module_scope.rb +8 -0
  64. data/lib/myco/parser/ast/to_ruby/null_literal.rb +6 -0
  65. data/lib/myco/parser/ast/to_ruby/parameters.rb +60 -0
  66. data/lib/myco/parser/ast/to_ruby/quest.rb +13 -0
  67. data/lib/myco/parser/ast/to_ruby/return.rb +7 -0
  68. data/lib/myco/parser/ast/to_ruby/scoped_constant.rb +11 -0
  69. data/lib/myco/parser/ast/to_ruby/self.rb +6 -0
  70. data/lib/myco/parser/ast/to_ruby/splat_value.rb +33 -0
  71. data/lib/myco/parser/ast/to_ruby/string_literal.rb +6 -0
  72. data/lib/myco/parser/ast/to_ruby/symbol_literal.rb +6 -0
  73. data/lib/myco/parser/ast/to_ruby/toplevel_constant.rb +11 -0
  74. data/lib/myco/parser/ast/to_ruby/true_literal.rb +6 -0
  75. data/lib/myco/parser/ast/to_ruby/void_literal.rb +6 -0
  76. data/lib/myco/parser/ast/to_ruby.rb +138 -0
  77. data/lib/myco/parser/ast.rb +6 -0
  78. data/lib/myco/parser/peg_parser.rb +361 -181
  79. data/lib/myco/parser.rb +27 -11
  80. data/lib/myco/tools/BasicCommand.my +42 -0
  81. data/lib/myco/tools/Generator.my +18 -0
  82. data/lib/myco/toolset.rb +0 -3
  83. data/lib/myco/version.rb +1 -4
  84. data/lib/myco.rb +2 -0
  85. metadata +230 -160
  86. data/lib/myco/parser/builder.output +0 -3995
  87. data/lib/myco/parser/builder.racc +0 -585
  88. data/lib/myco/parser/builder.rb +0 -1592
  89. data/lib/myco/parser/lexer.rb +0 -2306
  90. data/lib/myco/parser/lexer.rl +0 -393
  91. data/lib/myco/parser/lexer_char_classes.rl +0 -56
  92. data/lib/myco/parser/lexer_common.rb +0 -95
  93. data/lib/myco/parser/lexer_skeleton.rl +0 -154
  94. data/lib/myco/parser/peg_parser.kpeg +0 -759
  95. data/lib/myco/tools/OptionParser.my +0 -38
@@ -1,585 +0,0 @@
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