melbourne 1.0.0

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