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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +2 -0
  3. data/bin/myco +7 -0
  4. data/lib/myco/backtrace.rb +56 -0
  5. data/lib/myco/bootstrap/component.rb +142 -0
  6. data/lib/myco/bootstrap/empty_object.rb +4 -0
  7. data/lib/myco/bootstrap/file_toplevel.rb +5 -0
  8. data/lib/myco/bootstrap/find_constant.rb +86 -0
  9. data/lib/myco/bootstrap/instance.rb +52 -0
  10. data/lib/myco/bootstrap/meme.rb +160 -0
  11. data/lib/myco/bootstrap/void.rb +40 -0
  12. data/lib/myco/bootstrap.my +15 -0
  13. data/lib/myco/bootstrap.rb +10 -0
  14. data/lib/myco/command.my +33 -0
  15. data/lib/myco/core/BasicObject.my +46 -0
  16. data/lib/myco/core/Category.my +5 -0
  17. data/lib/myco/core/Decorator.my +18 -0
  18. data/lib/myco/core/FileToplevel.my +23 -0
  19. data/lib/myco/core/Object.my +24 -0
  20. data/lib/myco/core/Switch.my +31 -0
  21. data/lib/myco/eval.rb +63 -0
  22. data/lib/myco/parser/ast/constant_access.rb +29 -0
  23. data/lib/myco/parser/ast/constant_define.rb +40 -0
  24. data/lib/myco/parser/ast/constant_reopen.rb +47 -0
  25. data/lib/myco/parser/ast/declare_category.rb +51 -0
  26. data/lib/myco/parser/ast/declare_decorator.rb +35 -0
  27. data/lib/myco/parser/ast/declare_file.rb +54 -0
  28. data/lib/myco/parser/ast/declare_meme.rb +44 -0
  29. data/lib/myco/parser/ast/declare_object.rb +75 -0
  30. data/lib/myco/parser/ast/declare_string.rb +37 -0
  31. data/lib/myco/parser/ast/invoke.rb +66 -0
  32. data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +38 -0
  33. data/lib/myco/parser/ast/misc.rb +61 -0
  34. data/lib/myco/parser/ast/myco_module_scope.rb +58 -0
  35. data/lib/myco/parser/ast/quest.rb +82 -0
  36. data/lib/myco/parser/ast.rb +15 -0
  37. data/lib/myco/parser/builder.output +3995 -0
  38. data/lib/myco/parser/builder.racc +585 -0
  39. data/lib/myco/parser/builder.rb +1592 -0
  40. data/lib/myco/parser/lexer.rb +2306 -0
  41. data/lib/myco/parser/lexer.rl +393 -0
  42. data/lib/myco/parser/lexer_char_classes.rl +56 -0
  43. data/lib/myco/parser/lexer_common.rb +95 -0
  44. data/lib/myco/parser/lexer_skeleton.rl +154 -0
  45. data/lib/myco/parser/peg_parser.kpeg +759 -0
  46. data/lib/myco/parser/peg_parser.rb +7094 -0
  47. data/lib/myco/parser.rb +40 -0
  48. data/lib/myco/tools/OptionParser.my +38 -0
  49. data/lib/myco/tools/mycompile.my +51 -0
  50. data/lib/myco/toolset.rb +16 -0
  51. data/lib/myco/version.rb +22 -0
  52. data/lib/myco.rb +15 -0
  53. 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