mutant-melbourne 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/LICENSE +25 -0
  2. data/README.md +69 -0
  3. data/Rakefile +14 -0
  4. data/ext/melbourne/.gitignore +3 -0
  5. data/ext/melbourne/bstring-license.txt +29 -0
  6. data/ext/melbourne/bstrlib.c +2687 -0
  7. data/ext/melbourne/bstrlib.h +267 -0
  8. data/ext/melbourne/encoding_compat.cpp +188 -0
  9. data/ext/melbourne/encoding_compat.hpp +57 -0
  10. data/ext/melbourne/extconf.rb +87 -0
  11. data/ext/melbourne/grammar18.cpp +11280 -0
  12. data/ext/melbourne/grammar18.hpp +13 -0
  13. data/ext/melbourne/grammar18.y +6088 -0
  14. data/ext/melbourne/grammar19.cpp +12420 -0
  15. data/ext/melbourne/grammar19.hpp +11 -0
  16. data/ext/melbourne/grammar19.y +7113 -0
  17. data/ext/melbourne/lex.c.blt +152 -0
  18. data/ext/melbourne/lex.c.tab +136 -0
  19. data/ext/melbourne/local_state.hpp +43 -0
  20. data/ext/melbourne/melbourne.cpp +88 -0
  21. data/ext/melbourne/melbourne.hpp +19 -0
  22. data/ext/melbourne/node18.hpp +262 -0
  23. data/ext/melbourne/node19.hpp +271 -0
  24. data/ext/melbourne/node_types.rb +304 -0
  25. data/ext/melbourne/node_types18.cpp +255 -0
  26. data/ext/melbourne/node_types18.hpp +129 -0
  27. data/ext/melbourne/node_types19.cpp +249 -0
  28. data/ext/melbourne/node_types19.hpp +126 -0
  29. data/ext/melbourne/parser_state18.hpp +181 -0
  30. data/ext/melbourne/parser_state19.hpp +251 -0
  31. data/ext/melbourne/quark.cpp +42 -0
  32. data/ext/melbourne/quark.hpp +45 -0
  33. data/ext/melbourne/symbols.cpp +224 -0
  34. data/ext/melbourne/symbols.hpp +119 -0
  35. data/ext/melbourne/var_table18.cpp +83 -0
  36. data/ext/melbourne/var_table18.hpp +33 -0
  37. data/ext/melbourne/var_table19.cpp +65 -0
  38. data/ext/melbourne/var_table19.hpp +35 -0
  39. data/ext/melbourne/visitor18.cpp +963 -0
  40. data/ext/melbourne/visitor18.hpp +12 -0
  41. data/ext/melbourne/visitor19.cpp +960 -0
  42. data/ext/melbourne/visitor19.hpp +15 -0
  43. data/lib/compiler/ast/constants.rb +81 -0
  44. data/lib/compiler/ast/control_flow.rb +290 -0
  45. data/lib/compiler/ast/data.rb +14 -0
  46. data/lib/compiler/ast/definitions.rb +749 -0
  47. data/lib/compiler/ast/encoding.rb +18 -0
  48. data/lib/compiler/ast/exceptions.rb +138 -0
  49. data/lib/compiler/ast/file.rb +11 -0
  50. data/lib/compiler/ast/grapher.rb +89 -0
  51. data/lib/compiler/ast/literals.rb +207 -0
  52. data/lib/compiler/ast/node.rb +362 -0
  53. data/lib/compiler/ast/operators.rb +106 -0
  54. data/lib/compiler/ast/self.rb +15 -0
  55. data/lib/compiler/ast/sends.rb +615 -0
  56. data/lib/compiler/ast/transforms.rb +298 -0
  57. data/lib/compiler/ast/values.rb +88 -0
  58. data/lib/compiler/ast/variables.rb +351 -0
  59. data/lib/compiler/ast.rb +20 -0
  60. data/lib/compiler/locals.rb +109 -0
  61. data/lib/melbourne/processor.rb +651 -0
  62. data/lib/melbourne/version.rb +3 -0
  63. data/lib/melbourne.rb +143 -0
  64. metadata +112 -0
@@ -0,0 +1,960 @@
1
+ #include <sstream>
2
+
3
+ #include "melbourne.hpp"
4
+ #include "parser_state19.hpp"
5
+ #include "visitor19.hpp"
6
+ #include "symbols.hpp"
7
+
8
+ namespace melbourne {
9
+ namespace grammar19 {
10
+
11
+ void create_error(rb_parser_state *parser_state, char *msg) {
12
+ VALUE err_msg;
13
+
14
+ // Cleanup one of the common and ugly syntax errors.
15
+ if(std::string("syntax error, unexpected $end, expecting kEND") ==
16
+ std::string(msg)) {
17
+ if(start_lines->size() > 0) {
18
+ StartPosition& pos = start_lines->back();
19
+
20
+ std::ostringstream ss;
21
+ ss << "missing 'end' for '"
22
+ << pos.kind
23
+ << "' started on line "
24
+ << pos.line;
25
+ err_msg = rb_str_new2(ss.str().c_str());
26
+
27
+ } else {
28
+ err_msg = rb_str_new2("missing 'end' for unknown start");
29
+ }
30
+ } else {
31
+ err_msg = 0;
32
+
33
+ std::string pmsg(msg);
34
+ std::string comma(", ");
35
+
36
+ size_t one = pmsg.find(comma);
37
+ if(one != std::string::npos) {
38
+ size_t two = pmsg.find(comma, one+1);
39
+ if(two != std::string::npos) {
40
+ std::string sub = pmsg.substr(two+2);
41
+
42
+ err_msg = rb_str_new2(sub.c_str());
43
+ }
44
+ }
45
+
46
+ if(!err_msg) err_msg = rb_str_new2(msg);
47
+ }
48
+
49
+ int col = (int)(lex_p - lex_pbeg);
50
+
51
+ rb_funcall(processor,
52
+ rb_intern("process_parse_error"),4,
53
+ err_msg,
54
+ INT2FIX(col),
55
+ INT2FIX(ruby_sourceline),
56
+ lex_lastline);
57
+
58
+ parse_error = true;
59
+ }
60
+
61
+ #define nd_3rd u3.node
62
+
63
+ VALUE process_parse_tree(rb_parser_state*, VALUE, NODE*, ID*);
64
+
65
+ static VALUE process_dynamic(rb_parser_state *parser_state,
66
+ VALUE ptp, NODE *node, ID *locals)
67
+ {
68
+ VALUE array = rb_ary_new();
69
+
70
+ while(node) {
71
+ if (node->nd_head) {
72
+ rb_ary_push(array, process_parse_tree(parser_state, ptp, node->nd_head, locals));
73
+ }
74
+ node = node->nd_next;
75
+ }
76
+
77
+ return array;
78
+ }
79
+
80
+ static VALUE process_iter(rb_parser_state *parser_state,
81
+ VALUE ptp, NODE *node, ID *locals, int *level, ID method, VALUE line)
82
+ {
83
+ VALUE iter, body, args;
84
+
85
+ iter = process_parse_tree(parser_state, ptp, node->nd_iter, locals);
86
+ (*level)++;
87
+ if (node->nd_var != (NODE *)1
88
+ && node->nd_var != (NODE *)2
89
+ && node->nd_var != NULL) {
90
+ args = process_parse_tree(parser_state, ptp, node->nd_var, locals);
91
+ } else {
92
+ if (node->nd_var == NULL) {
93
+ // e.g. proc {}
94
+ args = Qnil;
95
+ } else {
96
+ // e.g. proc {||}
97
+ args = INT2FIX(0);
98
+ }
99
+ }
100
+ (*level)--;
101
+ body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
102
+ return rb_funcall(ptp, method, 4, line, iter, args, body);
103
+ }
104
+
105
+ /* Visits all the nodes in the parse tree.
106
+ * Adapted from ParseTree by Ryan Davis and Eric Hodel.
107
+ */
108
+ VALUE process_parse_tree(rb_parser_state *parser_state,
109
+ VALUE ptp, NODE *n, ID *locals)
110
+ {
111
+ NODE * volatile node = n;
112
+
113
+ static int masgn_level = 0;
114
+ static unsigned case_level = 0;
115
+ static unsigned when_level = 0;
116
+ static unsigned inside_case_args = 0;
117
+
118
+ VALUE line, tree = Qnil;
119
+
120
+ if(!node) return tree;
121
+
122
+ again:
123
+
124
+ if(node) {
125
+ line = INT2FIX(nd_line(node));
126
+ } else {
127
+ return rb_funcall(ptp, rb_intern("process_dangling_node"), 0);
128
+ }
129
+
130
+ // fprintf(stderr, "%s\n", get_node_type_string((enum node_type)nd_type(node)));
131
+
132
+ switch(nd_type(node)) {
133
+
134
+ case NODE_BLOCK: {
135
+ VALUE array = rb_ary_new();
136
+
137
+ while (node) {
138
+ rb_ary_push(array, process_parse_tree(parser_state, ptp, node->nd_head, locals));
139
+ node = node->nd_next;
140
+ }
141
+ tree = rb_funcall(ptp, rb_sBlock, 2, line, array);
142
+ break;
143
+ }
144
+ case NODE_DEFINED: {
145
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_head, locals);
146
+ tree = rb_funcall(ptp, rb_sDefined, 2, line, expr);
147
+ break;
148
+ }
149
+ case NODE_COLON2: {
150
+ VALUE container = process_parse_tree(parser_state, ptp, node->nd_head, locals);
151
+ tree = rb_funcall(ptp, rb_sColon2, 3, line,
152
+ container, ID2SYM(node->nd_mid));
153
+ break;
154
+ }
155
+ case NODE_MATCH2: {
156
+ VALUE pattern = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
157
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
158
+ tree = rb_funcall(ptp, rb_sMatch2, 3, line, pattern, value);
159
+ break;
160
+ }
161
+ case NODE_MATCH3: {
162
+ VALUE pattern = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
163
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
164
+ tree = rb_funcall(ptp, rb_sMatch3, 3, line, pattern, value);
165
+ break;
166
+ }
167
+ case NODE_BEGIN: {
168
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
169
+ tree = rb_funcall(ptp, rb_sBegin, 2, line, body);
170
+ break;
171
+ }
172
+ case NODE_IF: {
173
+ VALUE cond, body = Qnil, else_body = Qnil;
174
+
175
+ cond = process_parse_tree(parser_state, ptp, node->nd_cond, locals);
176
+ if (node->nd_body) {
177
+ body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
178
+ }
179
+ if (node->nd_else) {
180
+ else_body = process_parse_tree(parser_state, ptp, node->nd_else, locals);
181
+ }
182
+ tree = rb_funcall(ptp, rb_sIf, 4, line, cond, body, else_body);
183
+ break;
184
+ }
185
+ case NODE_CASE: {
186
+ VALUE expr = Qnil, els = Qnil;
187
+ NODE* else_node = 0;
188
+
189
+ case_level++;
190
+ if(node->nd_head) {
191
+ expr = process_parse_tree(parser_state, ptp, node->nd_head, locals); /* expr */
192
+ }
193
+
194
+ VALUE whens = rb_ary_new();
195
+ node = node->nd_body;
196
+ while(node) {
197
+ if (nd_type(node) == NODE_WHEN) { /* when */
198
+ rb_ary_push(whens, process_parse_tree(parser_state, ptp, node, locals));
199
+ node = node->nd_next;
200
+ } else {
201
+ else_node = node;
202
+ break; /* else */
203
+ }
204
+ }
205
+
206
+ case_level--;
207
+
208
+ // Be sure to decrease the case_level before processing the else.
209
+ // See http://github.com/rubinius/rubinius/issues#issue/240 for an example of
210
+ // why.
211
+ if(else_node) {
212
+ els = process_parse_tree(parser_state, ptp, else_node, locals);
213
+ }
214
+
215
+ tree = rb_funcall(ptp, rb_sCase, 4, line, expr, whens, els);
216
+ break;
217
+ }
218
+ case NODE_WHEN: {
219
+ VALUE body = Qnil;
220
+
221
+ when_level++;
222
+ /* when without case, ie, no expr in case */
223
+ if(!inside_case_args && case_level < when_level) {
224
+ if(when_level > 0) when_level--;
225
+ node = NEW_CASE(0, node);
226
+ goto again;
227
+ }
228
+ inside_case_args++;
229
+ VALUE args = process_parse_tree(parser_state, ptp, node->nd_head, locals); /* args */
230
+ inside_case_args--;
231
+
232
+ if(node->nd_body) {
233
+ body = process_parse_tree(parser_state, ptp, node->nd_body, locals); /* body */
234
+ }
235
+ if(when_level > 0) when_level--;
236
+
237
+ tree = rb_funcall(ptp, rb_sWhen, 3, line, args, body);
238
+ break;
239
+ }
240
+ case NODE_WHILE: {
241
+ VALUE cond, body = Qnil, post_cond;
242
+
243
+ cond = process_parse_tree(parser_state, ptp, node->nd_cond, locals);
244
+ if(node->nd_body) {
245
+ body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
246
+ }
247
+ post_cond = node->nd_3rd == 0 ? Qfalse : Qtrue;
248
+ tree = rb_funcall(ptp, rb_sWhile, 4, line, cond, body, post_cond);
249
+ break;
250
+ }
251
+ case NODE_UNTIL: {
252
+ VALUE cond, body = Qnil, post_cond;
253
+
254
+ cond = process_parse_tree(parser_state, ptp, node->nd_cond, locals);
255
+ if(node->nd_body) {
256
+ body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
257
+ }
258
+ post_cond = node->nd_3rd == 0 ? Qfalse : Qtrue;
259
+ tree = rb_funcall(ptp, rb_sUntil, 4, line, cond, body, post_cond);
260
+ break;
261
+ }
262
+ case NODE_BLOCK_PASS: {
263
+ VALUE args = Qnil;
264
+
265
+ if(node->nd_1st) {
266
+ args = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
267
+ }
268
+
269
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
270
+
271
+ tree = rb_funcall(ptp, rb_sBlockPass, 3, line, args, body);
272
+ break;
273
+ }
274
+ case NODE_FOR:
275
+ tree = process_iter(parser_state, ptp, node, locals, &masgn_level, rb_sFor, line);
276
+ break;
277
+
278
+ case NODE_ITER: {
279
+ VALUE iter = process_parse_tree(parser_state, ptp, node->nd_iter, locals);
280
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
281
+ tree = rb_funcall(ptp, rb_sIter, 3, line, iter, body);
282
+ break;
283
+ }
284
+ case NODE_LAMBDA: {
285
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_body, locals);
286
+ tree = rb_funcall(ptp, rb_sLambda, 2, line, scope);
287
+ break;
288
+ }
289
+ case NODE_BREAK: {
290
+ VALUE expr = Qnil;
291
+
292
+ if (node->nd_stts) {
293
+ expr = process_parse_tree(parser_state, ptp, node->nd_stts, locals);
294
+ }
295
+ tree = rb_funcall(ptp, rb_sBreak, 2, line, expr);
296
+ break;
297
+ }
298
+ case NODE_NEXT: {
299
+ VALUE expr = Qnil;
300
+
301
+ if (node->nd_stts) {
302
+ expr = process_parse_tree(parser_state, ptp, node->nd_stts, locals);
303
+ }
304
+ tree = rb_funcall(ptp, rb_sNext, 2, line, expr);
305
+ break;
306
+ }
307
+ case NODE_YIELD: {
308
+ VALUE expr = Qnil;
309
+
310
+ if (node->nd_stts) {
311
+ expr = process_parse_tree(parser_state, ptp, node->nd_stts, locals);
312
+ }
313
+ tree = rb_funcall(ptp, rb_sYield, 3, line, expr, node->u3.value);
314
+ break;
315
+ }
316
+ case NODE_RESCUE: {
317
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
318
+ VALUE resc = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
319
+ VALUE els = process_parse_tree(parser_state, ptp, node->nd_3rd, locals);
320
+ tree = rb_funcall(ptp, rb_sRescue, 4, line, body, resc, els);
321
+ break;
322
+ }
323
+ case NODE_RESBODY: {
324
+ /* rescue body:
325
+ * begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
326
+ * stmt rescue stmt
327
+ * a = b rescue c
328
+ */
329
+
330
+ VALUE conditions = Qnil;
331
+
332
+ if(node->nd_3rd) {
333
+ conditions = process_parse_tree(parser_state, ptp, node->nd_3rd, locals);
334
+ }
335
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
336
+ VALUE next = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
337
+ tree = rb_funcall(ptp, rb_sResbody, 4, line, conditions, body, next);
338
+ break;
339
+ }
340
+ case NODE_ENSURE: {
341
+ VALUE head, ensr = Qnil;
342
+
343
+ head = process_parse_tree(parser_state, ptp, node->nd_head, locals);
344
+ if (node->nd_ensr) {
345
+ ensr = process_parse_tree(parser_state, ptp, node->nd_ensr, locals);
346
+ }
347
+ tree = rb_funcall(ptp, rb_sEnsure, 3, line, head, ensr);
348
+ break;
349
+ }
350
+ case NODE_AND: {
351
+ VALUE left = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
352
+ VALUE right = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
353
+ tree = rb_funcall(ptp, rb_sAnd, 3, line, left, right);
354
+ break;
355
+ }
356
+ case NODE_OR: {
357
+ VALUE left = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
358
+ VALUE right = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
359
+ tree = rb_funcall(ptp, rb_sOr, 3, line, left, right);
360
+ break;
361
+ }
362
+ case NODE_DOT2: {
363
+ VALUE start = process_parse_tree(parser_state, ptp, node->nd_beg, locals);
364
+ VALUE finish = process_parse_tree(parser_state, ptp, node->nd_end, locals);
365
+ tree = rb_funcall(ptp, rb_sDot2, 3, line, start, finish);
366
+ break;
367
+ }
368
+ case NODE_DOT3: {
369
+ VALUE start = process_parse_tree(parser_state, ptp, node->nd_beg, locals);
370
+ VALUE finish = process_parse_tree(parser_state, ptp, node->nd_end, locals);
371
+ tree = rb_funcall(ptp, rb_sDot3, 3, line, start, finish);
372
+ break;
373
+ }
374
+ case NODE_FLIP2: {
375
+ VALUE start = process_parse_tree(parser_state, ptp, node->nd_beg, locals);
376
+ VALUE finish = process_parse_tree(parser_state, ptp, node->nd_end, locals);
377
+ tree = rb_funcall(ptp, rb_sFlip2, 3, line, start, finish);
378
+ break;
379
+ }
380
+ case NODE_FLIP3: {
381
+ VALUE start = process_parse_tree(parser_state, ptp, node->nd_beg, locals);
382
+ VALUE finish = process_parse_tree(parser_state, ptp, node->nd_end, locals);
383
+ tree = rb_funcall(ptp, rb_sFlip3, 3, line, start, finish);
384
+ break;
385
+ }
386
+ case NODE_RETURN: {
387
+ VALUE expr = Qnil;
388
+
389
+ if (node->nd_stts) {
390
+ expr = process_parse_tree(parser_state, ptp, node->nd_stts, locals);
391
+ }
392
+ tree = rb_funcall(ptp, rb_sReturn, 2, line, expr);
393
+ break;
394
+ }
395
+ case NODE_ARGSCAT: {
396
+ VALUE array = process_parse_tree(parser_state, ptp, node->nd_head, locals);
397
+ VALUE rest = process_parse_tree(parser_state, ptp, node->nd_body, locals);
398
+ tree = rb_funcall(ptp, rb_sArgsCat, 3, line, array, rest);
399
+ break;
400
+ }
401
+ case NODE_ARGSPUSH: {
402
+ VALUE head = process_parse_tree(parser_state, ptp, node->nd_head, locals);
403
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
404
+ tree = rb_funcall(ptp, rb_sArgsPush, 3, line, head, body);
405
+ break;
406
+ }
407
+ case NODE_CALL: {
408
+ VALUE args = Qnil;
409
+
410
+ VALUE recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
411
+ if (node->nd_args) {
412
+ args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
413
+ }
414
+ tree = rb_funcall(ptp, rb_sCall, 4, line, recv, ID2SYM(node->nd_mid), args);
415
+ break;
416
+ }
417
+ case NODE_FCALL: {
418
+ VALUE args = Qnil;
419
+
420
+ if (node->nd_args) {
421
+ args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
422
+ }
423
+ tree = rb_funcall(ptp, rb_sFCall, 3, line, ID2SYM(node->nd_mid), args);
424
+ break;
425
+ }
426
+ case NODE_VCALL:
427
+ tree = rb_funcall(ptp, rb_sVCall, 2, line, ID2SYM(node->nd_mid));
428
+ break;
429
+
430
+ case NODE_SUPER: {
431
+ VALUE args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
432
+ tree = rb_funcall(ptp, rb_sSuper, 2, line, args);
433
+ break;
434
+ }
435
+ case NODE_SCOPE: {
436
+ VALUE args = Qnil;
437
+ VALUE bv_locals = Qnil;
438
+
439
+ if(node->nd_args) {
440
+ if(nd_type(node->nd_args) == NODE_ARGS_AUX) {
441
+ args = process_parse_tree(parser_state, ptp, node->nd_args->nd_1st, node->nd_tbl);
442
+ bv_locals = process_parse_tree(parser_state, ptp, node->nd_args->nd_2nd, node->nd_tbl);
443
+ } else {
444
+ args = process_parse_tree(parser_state, ptp, node->nd_args, node->nd_tbl);
445
+ }
446
+ }
447
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, node->nd_tbl);
448
+ tree = rb_funcall(ptp, rb_sScope, 4, line, args, body, bv_locals);
449
+ break;
450
+ }
451
+ case NODE_OP_ASGN1: {
452
+ VALUE op;
453
+
454
+ VALUE recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
455
+ VALUE args = process_parse_tree(parser_state, ptp, node->nd_args->nd_2nd, locals);
456
+ switch(node->nd_mid) {
457
+ case 0:
458
+ op = ID2SYM(parser_intern("or"));
459
+ break;
460
+ case 1:
461
+ op = ID2SYM(parser_intern("and"));
462
+ break;
463
+ default:
464
+ op = ID2SYM(node->nd_mid);
465
+ }
466
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_args->nd_head, locals);
467
+ tree = rb_funcall(ptp, rb_sOpAsgn1, 5, line, recv, value, op, args);
468
+ break;
469
+ }
470
+ case NODE_OP_ASGN2: {
471
+ VALUE op;
472
+
473
+ VALUE recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
474
+ switch(node->nd_next->nd_mid) {
475
+ case 0:
476
+ op = ID2SYM(parser_intern("or"));
477
+ break;
478
+ case 1:
479
+ op = ID2SYM(parser_intern("and"));
480
+ break;
481
+ default:
482
+ op = ID2SYM(node->nd_next->nd_mid);
483
+ }
484
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
485
+ tree = rb_funcall(ptp, rb_sOpAsgn2, 5, line,
486
+ recv, ID2SYM(node->nd_next->nd_aid), op, value);
487
+ break;
488
+ }
489
+ case NODE_OP_ASGN_AND: {
490
+ VALUE var = process_parse_tree(parser_state, ptp, node->nd_head, locals);
491
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
492
+ tree = rb_funcall(ptp, rb_sOpAsgnAnd, 3, line, var, value);
493
+ break;
494
+ }
495
+ case NODE_OP_ASGN_OR: {
496
+ VALUE var = process_parse_tree(parser_state, ptp, node->nd_head, locals);
497
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
498
+ tree = rb_funcall(ptp, rb_sOpAsgnOr, 3, line, var, value);
499
+ break;
500
+ }
501
+ case NODE_MASGN: {
502
+ VALUE args = Qnil;
503
+
504
+ masgn_level++;
505
+ VALUE head = process_parse_tree(parser_state, ptp, node->nd_head, locals);
506
+ if (node->nd_args) {
507
+ if(node->nd_args != (NODE *)-1) {
508
+ args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
509
+ } else {
510
+ args = Qtrue;
511
+ }
512
+ }
513
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
514
+ tree = rb_funcall(ptp, rb_sMAsgn, 4, line, head, value, args);
515
+ masgn_level--;
516
+ break;
517
+ }
518
+ case NODE_LASGN: {
519
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_value, locals);
520
+ tree = rb_funcall(ptp, rb_sLAsgn, 3, line, ID2SYM(node->nd_vid), expr);
521
+ break;
522
+ }
523
+ case NODE_IASGN: {
524
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_value, locals);
525
+ tree = rb_funcall(ptp, rb_sIAsgn, 3, line, ID2SYM(node->nd_vid), expr);
526
+ break;
527
+ }
528
+ case NODE_CVASGN: {
529
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_value, locals);
530
+ tree = rb_funcall(ptp, rb_sCVAsgn, 3, line, ID2SYM(node->nd_vid), expr);
531
+ break;
532
+ }
533
+ case NODE_CVDECL: {
534
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_value, locals);
535
+ tree = rb_funcall(ptp, rb_sCVDecl, 3, line, ID2SYM(node->nd_vid), expr);
536
+ break;
537
+ }
538
+ case NODE_GASGN: {
539
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_value, locals);
540
+ tree = rb_funcall(ptp, rb_sGAsgn, 3, line, ID2SYM(node->nd_vid), expr);
541
+ break;
542
+ }
543
+ case NODE_CDECL: {
544
+ VALUE expr;
545
+
546
+ if(node->nd_vid) {
547
+ expr = ID2SYM(node->nd_vid);
548
+ } else {
549
+ expr = process_parse_tree(parser_state, ptp, node->nd_else, locals);
550
+ }
551
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
552
+ tree = rb_funcall(ptp, rb_sCDecl, 3, line, expr, value);
553
+ break;
554
+ }
555
+ case NODE_VALIAS: /* u1 u2 (alias $global $global2) */
556
+ tree = rb_funcall(ptp, rb_sVAlias, 3, line,
557
+ ID2SYM(node->u1.id), ID2SYM(node->u2.id));
558
+ break;
559
+
560
+ case NODE_ALIAS: { /* u1 u2 (alias :blah :blah2) */
561
+ VALUE to = process_parse_tree(parser_state, ptp, node->u1.node, locals);
562
+ VALUE from = process_parse_tree(parser_state, ptp, node->u2.node, locals);
563
+ tree = rb_funcall(ptp, rb_sAlias, 3, line, to, from);
564
+ break;
565
+ }
566
+ case NODE_UNDEF: { /* u2 (undef instvar) */
567
+ VALUE name = process_parse_tree(parser_state, ptp, node->u2.node, locals);
568
+ tree = rb_funcall(ptp, rb_sUndef, 2, line, name);
569
+ break;
570
+ }
571
+ case NODE_COLON3: /* u2 (::OUTER_CONST) */
572
+ tree = rb_funcall(ptp, rb_sColon3, 2, line, ID2SYM(node->u2.id));
573
+ break;
574
+
575
+ case NODE_HASH: {
576
+ VALUE array = rb_ary_new();
577
+
578
+ node = node->nd_head;
579
+ while (node) {
580
+ rb_ary_push(array, process_parse_tree(parser_state, ptp, node->nd_head, locals));
581
+ if (!(node = node->nd_next)) {
582
+ // @todo: properly process the parse error
583
+ printf("odd number list for Hash");
584
+ abort();
585
+ }
586
+ rb_ary_push(array, process_parse_tree(parser_state, ptp, node->nd_head, locals));
587
+ node = node->nd_next;
588
+ }
589
+ tree = rb_funcall(ptp, rb_sHash, 2, line, array);
590
+ break;
591
+ }
592
+ case NODE_ARRAY: {
593
+ VALUE array = rb_ary_new();
594
+
595
+ while (node) {
596
+ rb_ary_push(array, process_parse_tree(parser_state, ptp, node->nd_head, locals));
597
+ node = node->nd_next;
598
+ }
599
+ tree = rb_funcall(ptp, rb_sArray, 2, line, array);
600
+ break;
601
+ }
602
+ case NODE_DSTR: {
603
+ VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
604
+ tree = rb_funcall(ptp, rb_sDStr, 3, line, node->nd_lit, array);
605
+ break;
606
+ }
607
+ case NODE_DSYM: {
608
+ VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
609
+ tree = rb_funcall(ptp, rb_sDSym, 3, line, node->nd_lit, array);
610
+ break;
611
+ }
612
+ case NODE_DXSTR: {
613
+ VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
614
+ tree = rb_funcall(ptp, rb_sDXStr, 3, line, node->nd_lit, array);
615
+ break;
616
+ }
617
+ case NODE_DREGX: {
618
+ VALUE flags = Qnil;
619
+
620
+ VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
621
+ if (node->nd_cflag) flags = INT2FIX(node->nd_cflag);
622
+ tree = rb_funcall(ptp, rb_sDRegx, 4, line, node->nd_lit, array, flags);
623
+ break;
624
+ }
625
+ case NODE_DREGX_ONCE: {
626
+ VALUE flags = Qnil;
627
+
628
+ VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
629
+ if (node->nd_cflag) flags = INT2FIX(node->nd_cflag);
630
+ tree = rb_funcall(ptp, rb_sDRegxOnce, 4, line, node->nd_lit, array, flags);
631
+ break;
632
+ }
633
+ case NODE_DEFN: {
634
+ VALUE body = Qnil;
635
+
636
+ if (node->nd_defn) {
637
+ body = process_parse_tree(parser_state, ptp, node->nd_defn, locals);
638
+ }
639
+ tree = rb_funcall(ptp, rb_sDefn, 3, line, ID2SYM(node->nd_mid), body);
640
+ break;
641
+ }
642
+ case NODE_DEFS: {
643
+ VALUE recv = Qnil, body = Qnil;
644
+
645
+ if (node->nd_defn) {
646
+ recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
647
+ body = process_parse_tree(parser_state, ptp, node->nd_defn, locals);
648
+ }
649
+ tree = rb_funcall(ptp, rb_sDefs, 4, line, recv, ID2SYM(node->nd_mid), body);
650
+ break;
651
+ }
652
+ case NODE_CLASS: {
653
+ VALUE name, super = Qnil;
654
+
655
+ if (nd_type(node->nd_cpath) == NODE_COLON2 && !node->nd_cpath->nd_vid) {
656
+ name = ID2SYM((ID)node->nd_cpath->nd_mid);
657
+ } else {
658
+ name = process_parse_tree(parser_state, ptp, node->nd_cpath, locals);
659
+ }
660
+ if(node->nd_super) {
661
+ super = process_parse_tree(parser_state, ptp, node->nd_super, locals);
662
+ }
663
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
664
+ tree = rb_funcall(ptp, rb_sClass, 4, line, name, super, body);
665
+ break;
666
+ }
667
+ case NODE_MODULE: {
668
+ VALUE name;
669
+
670
+ if (nd_type(node->nd_cpath) == NODE_COLON2 && !node->nd_cpath->nd_vid) {
671
+ name = ID2SYM((ID)node->nd_cpath->nd_mid);
672
+ } else {
673
+ name = process_parse_tree(parser_state, ptp, node->nd_cpath, locals);
674
+ }
675
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
676
+ tree = rb_funcall(ptp, rb_sModule, 3, line, name, body);
677
+ break;
678
+ }
679
+ case NODE_SCLASS: {
680
+ VALUE recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
681
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
682
+ tree = rb_funcall(ptp, rb_sSClass, 3, line, recv, body);
683
+ break;
684
+ }
685
+ case NODE_OPT_ARG: {
686
+ VALUE args = rb_ary_new();
687
+
688
+ do {
689
+ rb_ary_push(args, process_parse_tree(parser_state, ptp, node->nd_body, locals));
690
+ node = node->nd_next;
691
+ } while(node);
692
+
693
+ tree = rb_funcall(ptp, rb_sOptArg, 2, line, args);
694
+ break;
695
+ }
696
+ case NODE_ARGS: {
697
+ VALUE args = Qnil;
698
+ VALUE opts = Qnil;
699
+ VALUE splat = Qnil;
700
+ VALUE post = Qnil;
701
+ VALUE block = Qnil;
702
+
703
+ int total_args = 0;
704
+ ID* args_ary = 0;
705
+
706
+ NODE* aux = node->nd_args;
707
+ NODE* post_args = aux->nd_next;
708
+ NODE* masgn = 0;
709
+ NODE* next = 0;
710
+
711
+ if(node->nd_argc > 0) {
712
+ total_args = (int)locals[0];
713
+ args_ary = locals + 1;
714
+
715
+ if(post_args && post_args->nd_next && nd_type(post_args->nd_next) == NODE_AND) {
716
+ if(nd_type(post_args->nd_next->nd_head) == NODE_BLOCK) {
717
+ masgn = post_args->nd_next->nd_head->nd_head;
718
+ next = post_args->nd_next->nd_head->nd_next;
719
+ } else {
720
+ masgn = post_args->nd_next->nd_head;
721
+ next = masgn->nd_next;
722
+ // -1 comes from: mlhs_head tSTAR
723
+ if(masgn->nd_cnt == -1) next = 0;
724
+ }
725
+ }
726
+
727
+ args = rb_ary_new();
728
+ for(int i = 0; i < node->nd_argc && i < total_args; i++) {
729
+ VALUE arg = Qnil;
730
+
731
+ if(!INTERNAL_ID_P(args_ary[i])) {
732
+ arg = ID2SYM(args_ary[i]);
733
+ } else if(masgn) {
734
+ arg = process_parse_tree(parser_state, ptp, masgn, locals);
735
+ if(next && nd_type(next) == NODE_BLOCK) {
736
+ masgn = next->nd_head;
737
+ next = next->nd_next;
738
+ } else {
739
+ masgn = next;
740
+ if(masgn) next = masgn->nd_next;
741
+ }
742
+ }
743
+
744
+ rb_ary_push(args, arg);
745
+ }
746
+ }
747
+
748
+ if(node->nd_opt) {
749
+ opts = process_parse_tree(parser_state, ptp, node->nd_opt, locals);
750
+ }
751
+
752
+ if(INTERNAL_ID_P(aux->nd_rest)) {
753
+ splat = Qtrue;
754
+ } else if(aux->nd_rest) {
755
+ if(aux->nd_rest == 1) {
756
+ // m { |a,| ... }
757
+ splat = Qfalse;
758
+ } else {
759
+ splat = ID2SYM(aux->nd_rest);
760
+ }
761
+ }
762
+ if(aux->nd_mid) block = ID2SYM(aux->nd_mid);
763
+
764
+ if(post_args && post_args->nd_pid) {
765
+ total_args = (int)locals[0];
766
+ args_ary = locals + 1;
767
+
768
+ int start;
769
+ for(start = 0; start < total_args; start++) {
770
+ if(args_ary[start] == post_args->nd_pid)
771
+ break;
772
+ }
773
+
774
+ post = rb_ary_new();
775
+ for(int i = 0; i < post_args->nd_argc && start + i < total_args; i++) {
776
+ rb_ary_push(post, ID2SYM(args_ary[start + i]));
777
+ }
778
+ }
779
+
780
+ tree = rb_funcall(ptp, rb_sArgs, 6, line, args, opts, splat, post, block);
781
+ break;
782
+ }
783
+ case NODE_LVAR:
784
+ if(!INTERNAL_ID_P(node->nd_vid)) {
785
+ tree = rb_funcall(ptp, rb_sLVar, 2, line, ID2SYM(node->nd_vid));
786
+ }
787
+ break;
788
+
789
+ case NODE_IVAR:
790
+ tree = rb_funcall(ptp, rb_sIVar, 2, line, ID2SYM(node->nd_vid));
791
+ break;
792
+
793
+ case NODE_CVAR:
794
+ tree = rb_funcall(ptp, rb_sCVar, 2, line, ID2SYM(node->nd_vid));
795
+ break;
796
+
797
+ case NODE_GVAR:
798
+ tree = rb_funcall(ptp, rb_sGVar, 2, line, ID2SYM(node->nd_vid));
799
+ break;
800
+
801
+ case NODE_CONST:
802
+ tree = rb_funcall(ptp, rb_sConst, 2, line, ID2SYM(node->nd_vid));
803
+ break;
804
+
805
+ case NODE_XSTR: /* u1 (%x{ls}) */
806
+ tree = rb_funcall(ptp, rb_sXStr, 2, line, node->nd_lit);
807
+ break;
808
+
809
+ case NODE_STR: /* u1 */
810
+ tree = rb_funcall(ptp, rb_sStr, 2, line, node->nd_lit);
811
+ break;
812
+
813
+ case NODE_REGEX:
814
+ tree = rb_funcall(ptp, rb_sRegex, 3, line, node->nd_lit,
815
+ INT2FIX(node->nd_cnt));
816
+ break;
817
+
818
+ case NODE_MATCH:
819
+ tree = rb_funcall(ptp, rb_sMatch, 3, line, node->nd_lit,
820
+ INT2FIX(node->nd_cnt));
821
+ break;
822
+
823
+ case NODE_LIT:
824
+ tree = rb_funcall(ptp, rb_sLit, 2, line, node->nd_lit);
825
+ break;
826
+
827
+ case NODE_VALUES: {
828
+ VALUE first = process_parse_tree(parser_state, ptp, node->nd_head, locals);
829
+ VALUE rest = process_parse_tree(parser_state, ptp, node->nd_args, locals);
830
+ tree = rb_funcall(ptp, rb_sValues, 3, line, first, rest);
831
+ break;
832
+ }
833
+
834
+ case NODE_NUMBER:
835
+ tree = rb_funcall(ptp, rb_sNumber, 2, line, node->nd_lit);
836
+ break;
837
+
838
+ case NODE_FLOAT:
839
+ tree = rb_funcall(ptp, rb_sFloat, 2, line, node->nd_lit);
840
+ break;
841
+
842
+ case NODE_NTH_REF: /* u2 u3 ($1) - u3 is local_cnt('~') ignorable? */
843
+ tree = rb_funcall(ptp, rb_sNthRef, 2, line, INT2FIX(node->nd_nth));
844
+ break;
845
+
846
+ case NODE_BACK_REF: { /* u2 u3 ($& etc) */
847
+ char str[2];
848
+ str[0] = node->nd_nth;
849
+ str[1] = 0;
850
+ tree = rb_funcall(ptp, rb_sBackRef, 2, line, ID2SYM(parser_intern(str)));
851
+ break;
852
+ }
853
+
854
+ case NODE_BLOCK_ARG: /* u1 u3 (def x(&b) */
855
+ tree = rb_funcall(ptp, rb_sBlockArg, 2, line, ID2SYM(node->u1.id));
856
+ break;
857
+
858
+ case NODE_RETRY:
859
+ tree = rb_funcall(ptp, rb_sRetry, 1, line);
860
+ break;
861
+
862
+ case NODE_FALSE:
863
+ tree = rb_funcall(ptp, rb_sFalse, 1, line);
864
+ break;
865
+
866
+ case NODE_NIL:
867
+ tree = rb_funcall(ptp, rb_sNil, 1, line);
868
+ break;
869
+
870
+ case NODE_SELF:
871
+ tree = rb_funcall(ptp, rb_sSelf, 1, line);
872
+ break;
873
+
874
+ case NODE_TRUE:
875
+ tree = rb_funcall(ptp, rb_sTrue, 1, line);
876
+ break;
877
+
878
+ case NODE_ZARRAY:
879
+ tree = rb_funcall(ptp, rb_sZArray, 1, line);
880
+ break;
881
+
882
+ case NODE_ZSUPER:
883
+ tree = rb_funcall(ptp, rb_sZSuper, 1, line);
884
+ break;
885
+
886
+ case NODE_REDO:
887
+ tree = rb_funcall(ptp, rb_sRedo, 1, line);
888
+ break;
889
+
890
+ case NODE_FILE:
891
+ tree = rb_funcall(ptp, rb_sFile, 1, line);
892
+ break;
893
+
894
+ case NODE_ENCODING:
895
+ tree = rb_funcall(ptp, rb_sEncoding, 2, line, node->nd_lit);
896
+ break;
897
+
898
+ case NODE_SPLAT: {
899
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_head, locals);
900
+ tree = rb_funcall(ptp, rb_sSplat, 2, line, expr);
901
+ break;
902
+ }
903
+ case NODE_TO_ARY: {
904
+ VALUE expr = process_parse_tree(parser_state, ptp, node->nd_head, locals);
905
+ tree = rb_funcall(ptp, rb_sToAry, 2, line, expr);
906
+ break;
907
+ }
908
+ case NODE_ATTRASGN: { /* literal.meth = y u1 u2 u3 */
909
+ VALUE recv;
910
+
911
+ /* node id node */
912
+ if (node->nd_1st == RNODE(1)) {
913
+ recv = process_parse_tree(parser_state, ptp, NEW_SELF(), locals);
914
+ } else {
915
+ recv = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
916
+ }
917
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_3rd, locals);
918
+ tree = rb_funcall(ptp, rb_sAttrAsgn, 4, line,
919
+ recv, ID2SYM(node->u2.id), value);
920
+ break;
921
+ }
922
+ case NODE_EVSTR: {
923
+ VALUE value = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
924
+ tree = rb_funcall(ptp, rb_sEvStr, 2, line, value);
925
+ break;
926
+ }
927
+ case NODE_PREEXE: { /* BEGIN { ... } */
928
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
929
+ tree = rb_funcall(ptp, rb_sPreExe, 2, line, scope);
930
+ break;
931
+ }
932
+ case NODE_POSTEXE: { /* END { ... } */
933
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
934
+ tree = rb_funcall(ptp, rb_sPostExe, 2, line, scope);
935
+ break;
936
+ }
937
+ case NODE_POSTARG: {
938
+ VALUE into = Qnil;
939
+ if(node->nd_1st != RNODE(-1)) {
940
+ into = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
941
+ }
942
+
943
+ VALUE rest = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
944
+
945
+ tree = rb_funcall(ptp, rb_sPostArg, 3, line, into, rest);
946
+ break;
947
+ }
948
+ default: {
949
+ VALUE node_name = rb_str_new2(get_node_type_string((enum node_type)nd_type(node)));
950
+ VALUE node_type = INT2FIX(nd_type(node));
951
+ tree = rb_funcall(ptp, rb_intern("process_missing_node"), 3,
952
+ line, node_name, node_type);
953
+ break;
954
+ }
955
+ }
956
+
957
+ return tree;
958
+ }
959
+ }; // namespace grammar19
960
+ };