rubinius-melbourne 1.0.0.8
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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/ext/rubinius/melbourne/bstring-license.txt +29 -0
- data/ext/rubinius/melbourne/bstrlib.cpp +2687 -0
- data/ext/rubinius/melbourne/bstrlib.h +267 -0
- data/ext/rubinius/melbourne/extconf.rb +166 -0
- data/ext/rubinius/melbourne/grammar.cpp +11255 -0
- data/ext/rubinius/melbourne/grammar.hpp +11 -0
- data/ext/rubinius/melbourne/grammar.y +6063 -0
- data/ext/rubinius/melbourne/lex.c.tab +136 -0
- data/ext/rubinius/melbourne/local_state.hpp +41 -0
- data/ext/rubinius/melbourne/melbourne.cpp +60 -0
- data/ext/rubinius/melbourne/melbourne.hpp +19 -0
- data/ext/rubinius/melbourne/node.hpp +261 -0
- data/ext/rubinius/melbourne/node_types.cpp +254 -0
- data/ext/rubinius/melbourne/node_types.hpp +127 -0
- data/ext/rubinius/melbourne/node_types.rb +185 -0
- data/ext/rubinius/melbourne/parser_state.hpp +180 -0
- data/ext/rubinius/melbourne/quark.cpp +43 -0
- data/ext/rubinius/melbourne/quark.hpp +49 -0
- data/ext/rubinius/melbourne/symbols.cpp +225 -0
- data/ext/rubinius/melbourne/symbols.hpp +119 -0
- data/ext/rubinius/melbourne/var_table.cpp +81 -0
- data/ext/rubinius/melbourne/var_table.hpp +31 -0
- data/ext/rubinius/melbourne/visitor.cpp +962 -0
- data/ext/rubinius/melbourne/visitor.hpp +10 -0
- data/lib/rubinius/melbourne/version.rb +5 -0
- data/lib/rubinius/melbourne.rb +100 -0
- data/rubinius-melbourne.gemspec +25 -0
- metadata +119 -0
@@ -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
|
+
};
|