rubinius-melbourne 1.0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,119 @@
1
+ #ifndef MEL_SYMBOLS_HPP
2
+ #define MEL_SYMBOLS_HPP
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ namespace MELBOURNE {
9
+ extern ID rb_sAlias;
10
+ extern ID rb_sAnd;
11
+ extern ID rb_sArgs;
12
+ extern ID rb_sArgsCat;
13
+ extern ID rb_sArgsPush;
14
+ extern ID rb_sArray;
15
+ extern ID rb_sAttrAsgn;
16
+ extern ID rb_sBackRef;
17
+ extern ID rb_sBegin;
18
+ extern ID rb_sBlock;
19
+ extern ID rb_sBlockArg;
20
+ extern ID rb_sBlockPass;
21
+ extern ID rb_sBreak;
22
+ extern ID rb_sCall;
23
+ extern ID rb_sCase;
24
+ extern ID rb_sCDecl;
25
+ extern ID rb_sClass;
26
+ extern ID rb_sColon2;
27
+ extern ID rb_sColon3;
28
+ extern ID rb_sConst;
29
+ extern ID rb_sCVar;
30
+ extern ID rb_sCVAsgn;
31
+ extern ID rb_sCVDecl;
32
+ extern ID rb_sData;
33
+ extern ID rb_sDefined;
34
+ extern ID rb_sDefn;
35
+ extern ID rb_sDefs;
36
+ extern ID rb_sDot2;
37
+ extern ID rb_sDot3;
38
+ extern ID rb_sDRegx;
39
+ extern ID rb_sDRegxOnce;
40
+ extern ID rb_sDStr;
41
+ extern ID rb_sDSym;
42
+ extern ID rb_sDXStr;
43
+ extern ID rb_sEncoding;
44
+ extern ID rb_sEnsure;
45
+ extern ID rb_sEvStr;
46
+ extern ID rb_sFalse;
47
+ extern ID rb_sFCall;
48
+ extern ID rb_sFile;
49
+ extern ID rb_sFixnum;
50
+ extern ID rb_sFlip2;
51
+ extern ID rb_sFlip3;
52
+ extern ID rb_sFloat;
53
+ extern ID rb_sFor;
54
+ extern ID rb_sGAsgn;
55
+ extern ID rb_sGVar;
56
+ extern ID rb_sHash;
57
+ extern ID rb_sIAsgn;
58
+ extern ID rb_sIf;
59
+ extern ID rb_sIter;
60
+ extern ID rb_sIVar;
61
+ extern ID rb_sLAsgn;
62
+ extern ID rb_sLambda;
63
+ extern ID rb_sLit;
64
+ extern ID rb_sLVar;
65
+ extern ID rb_sMAsgn;
66
+ extern ID rb_sMatch;
67
+ extern ID rb_sMatch2;
68
+ extern ID rb_sMatch3;
69
+ extern ID rb_sModule;
70
+ extern ID rb_sNegate;
71
+ extern ID rb_sNext;
72
+ extern ID rb_sNil;
73
+ extern ID rb_sNot;
74
+ extern ID rb_sNthRef;
75
+ extern ID rb_sNumber;
76
+ extern ID rb_sOpAsgn1;
77
+ extern ID rb_sOpAsgn2;
78
+ extern ID rb_sOpAsgnAnd;
79
+ extern ID rb_sOpAsgnOr;
80
+ extern ID rb_sOptArg;
81
+ extern ID rb_sOr;
82
+ extern ID rb_sPostExe;
83
+ extern ID rb_sPostArg;
84
+ extern ID rb_sPreExe;
85
+ extern ID rb_sRedo;
86
+ extern ID rb_sRegex;
87
+ extern ID rb_sResbody;
88
+ extern ID rb_sRescue;
89
+ extern ID rb_sRetry;
90
+ extern ID rb_sReturn;
91
+ extern ID rb_sSClass;
92
+ extern ID rb_sScope;
93
+ extern ID rb_sSelf;
94
+ extern ID rb_sSplat;
95
+ extern ID rb_sStr;
96
+ extern ID rb_sSuper;
97
+ extern ID rb_sSValue;
98
+ extern ID rb_sToAry;
99
+ extern ID rb_sTrue;
100
+ extern ID rb_sUndef;
101
+ extern ID rb_sUntil;
102
+ extern ID rb_sVAlias;
103
+ extern ID rb_sValues;
104
+ extern ID rb_sVCall;
105
+ extern ID rb_sWhen;
106
+ extern ID rb_sWhile;
107
+ extern ID rb_sXStr;
108
+ extern ID rb_sYield;
109
+ extern ID rb_sZArray;
110
+ extern ID rb_sZSuper;
111
+
112
+ void init_symbols();
113
+ };
114
+
115
+ #ifdef __cplusplus
116
+ } /* extern "C" { */
117
+ #endif
118
+
119
+ #endif
@@ -0,0 +1,81 @@
1
+ #include <vector>
2
+ #include <stdlib.h>
3
+ #include <assert.h>
4
+
5
+ #include "namespace.h"
6
+ #include "melbourne.hpp"
7
+ #include "var_table.hpp"
8
+
9
+ namespace MELBOURNE {
10
+
11
+ struct var_table_t {
12
+ struct var_table_t *next;
13
+ std::vector<quark> *quarks;
14
+ };
15
+
16
+ var_table var_table_create() {
17
+ var_table vt = ALLOC(struct var_table_t);
18
+ vt->quarks = new std::vector<quark>();
19
+ vt->next = NULL;
20
+ return vt;
21
+ }
22
+
23
+ void var_table_destroy(var_table vt) {
24
+ while (vt) {
25
+ var_table cur = vt;
26
+ delete cur->quarks;
27
+ vt = vt->next;
28
+ free(cur);
29
+ }
30
+ }
31
+
32
+ var_table var_table_push(var_table cur) {
33
+ var_table vt = var_table_create();
34
+ vt->next = cur;
35
+ return vt;
36
+ }
37
+
38
+ var_table var_table_pop(var_table cur) {
39
+ var_table nw = NULL;
40
+
41
+ if(cur) {
42
+ delete cur->quarks;
43
+ nw = cur->next;
44
+ free(cur);
45
+ }
46
+ return nw;
47
+ }
48
+
49
+ int var_table_find(const var_table tbl, const quark needle) {
50
+ for(size_t i = 0; i < tbl->quarks->size(); i++) {
51
+ if(tbl->quarks->at(i) == needle) return (int)i;
52
+ }
53
+ return -1;
54
+ }
55
+
56
+ int var_table_find_chained(const var_table tbl, const quark needle) {
57
+ for(size_t i = 0; i < tbl->quarks->size(); i++) {
58
+ if(tbl->quarks->at(i) == needle) return (int)i;
59
+ }
60
+
61
+ if(tbl->next) {
62
+ return var_table_find_chained(tbl->next, needle);
63
+ }
64
+ return -1;
65
+ }
66
+
67
+ int var_table_add(var_table tbl, const quark item) {
68
+ tbl->quarks->push_back(item);
69
+ return (int)tbl->quarks->size();
70
+ }
71
+
72
+ int var_table_size(const var_table tbl)
73
+ {
74
+ return (int)tbl->quarks->size();
75
+ }
76
+
77
+ quark var_table_get(const var_table tbl, const int index)
78
+ {
79
+ return tbl->quarks->at(index);
80
+ }
81
+ };
@@ -0,0 +1,31 @@
1
+ #ifndef MEL_VAR_TABLE_HPP
2
+ #define MEL_VAR_TABLE_HPP
3
+
4
+ #include "quark.hpp"
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+
11
+ namespace MELBOURNE {
12
+ struct var_table_t;
13
+ typedef struct var_table_t *var_table;
14
+
15
+ var_table var_table_create();
16
+ void var_table_destroy(var_table vt);
17
+ var_table var_table_push(var_table cur);
18
+ var_table var_table_pop(var_table cur);
19
+ int var_table_find(const var_table tbl, const quark needle);
20
+ int var_table_find_chained(const var_table tbl, const quark needle);
21
+
22
+ int var_table_add(var_table tbl, const quark item);
23
+ int var_table_size(const var_table tbl);
24
+ quark var_table_get(const var_table tbl, const int index);
25
+ };
26
+
27
+ #ifdef __cplusplus
28
+ } /* extern "C" { */
29
+ #endif
30
+
31
+ #endif
@@ -0,0 +1,962 @@
1
+ #include <sstream>
2
+
3
+ #include "namespace.h"
4
+ #include "melbourne.hpp"
5
+ #include "parser_state.hpp"
6
+ #include "visitor.hpp"
7
+ #include "symbols.hpp"
8
+
9
+ namespace MELBOURNE {
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(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
+ };