mutant-melbourne 2.0.1

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