rubinius-melbourne 1.2.1.0 → 2.0.0.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,8 @@
4
4
  #include "namespace.h"
5
5
  #include "node.hpp"
6
6
  #include "node_types.hpp"
7
- #include "local_state.hpp"
7
+ #include "var_table.hpp"
8
+ #include "encoding_compat.hpp"
8
9
 
9
10
  #include <vector>
10
11
  #include <list>
@@ -13,14 +14,17 @@ namespace MELBOURNE {
13
14
 
14
15
  enum lex_state_e {
15
16
  EXPR_BEG, /* ignore newline, +/- is a sign. */
16
- EXPR_END, /* newline significant, +/- is a operator. */
17
- EXPR_ARG, /* newline significant, +/- is a operator. */
18
- EXPR_CMDARG, /* newline significant, +/- is a operator. */
19
- EXPR_ENDARG, /* newline significant, +/- is a operator. */
20
- EXPR_MID, /* newline significant, +/- is a operator. */
17
+ EXPR_END, /* newline significant, +/- is an operator. */
18
+ EXPR_ENDARG, /* ditto, and unbound braces. */
19
+ EXPR_ENDFN, /* ditto, and unbound braces. */
20
+ EXPR_ARG, /* newline significant, +/- is an operator. */
21
+ EXPR_CMDARG, /* newline significant, +/- is an operator. */
22
+ EXPR_MID, /* newline significant, +/- is an operator. */
21
23
  EXPR_FNAME, /* ignore newline, no reserved words. */
22
24
  EXPR_DOT, /* right after `.' or `::', no reserved words. */
23
25
  EXPR_CLASS, /* immediate after `class', no here document. */
26
+ EXPR_VALUE, /* like EXPR_BEG but label is disallowed. */
27
+ EXPR_MAX_STATE
24
28
  };
25
29
 
26
30
  typedef VALUE stack_type;
@@ -36,7 +40,7 @@ typedef VALUE stack_type;
36
40
  };
37
41
 
38
42
  typedef struct rb_parser_state {
39
- int end_seen;
43
+ int ruby__end__seen;
40
44
  int debug_lines;
41
45
  int heredoc_end;
42
46
  int command_start;
@@ -58,15 +62,20 @@ typedef VALUE stack_type;
58
62
  /* this function reads a line from lex_io and stores it in
59
63
  * line_buffer.
60
64
  */
61
- bool (*lex_gets)(rb_parser_state*);
62
- bstring line_buffer;
65
+ VALUE (*lex_gets)(rb_parser_state*, VALUE);
63
66
 
64
67
  /* If this is set, we use the io method. */
65
- FILE *lex_io;
68
+ int lex_io;
69
+ char* lex_io_buf;
70
+ ssize_t lex_io_index;
71
+ ssize_t lex_io_total;
72
+ long lex_io_count;
73
+
66
74
  /* Otherwise, we use this. */
67
- bstring lex_string;
68
- bstring lex_lastline;
69
- bstring lex_nextline;
75
+ long lex_gets_ptr;
76
+ VALUE lex_input;
77
+ VALUE lex_lastline;
78
+ VALUE lex_nextline;
70
79
 
71
80
  char *lex_pbeg;
72
81
  char *lex_p;
@@ -81,11 +90,10 @@ typedef VALUE stack_type;
81
90
  void *lval; /* the parser's yylval */
82
91
  bool eofp;
83
92
 
84
- std::vector<bstring>* magic_comments;
85
93
  int column;
86
94
  NODE *top_node;
87
95
 
88
- LocalState* variables;
96
+ struct local_vars* locals_table;
89
97
 
90
98
  int ternary_colon;
91
99
 
@@ -98,20 +106,26 @@ typedef VALUE stack_type;
98
106
  bool verbose;
99
107
 
100
108
  bool parse_error;
101
- VALUE processor;
102
109
 
103
- char *sourcefile;
104
- int sourceline;
110
+ // Reference to the object to call methods on to convert the
111
+ // C parse tree into a Ruby AST.
112
+ VALUE processor;
105
113
 
106
- const unsigned char* re_mbctab;
114
+ // Keep track of any object literals created in the parser.
115
+ VALUE references;
107
116
 
108
117
  // Keeps track of lines that 'end' starters are on, to enable
109
118
  // better error reporting.
110
119
  std::list<StartPosition>* start_lines;
111
120
 
112
- // Tracks quarks
113
- quark_map* quark_indexes;
114
- quark_vector* quarks;
121
+ int line_count;
122
+ bool has_shebang;
123
+
124
+ char *sourcefile;
125
+ int sourceline;
126
+
127
+ rb_encoding *enc;
128
+ rb_encoding *utf8;
115
129
  } rb_parser_state;
116
130
 
117
131
 
@@ -138,8 +152,12 @@ typedef VALUE stack_type;
138
152
  #define lex_gets PARSER_VAR(lex_gets)
139
153
  #define line_buffer PARSER_VAR(line_buffer)
140
154
  #define line_count PARSER_VAR(line_count)
155
+ #define has_shebang PARSER_VAR(has_shebang)
141
156
  #define lex_io PARSER_VAR(lex_io)
142
- #define lex_string PARSER_VAR(lex_string)
157
+ #define lex_io_buf PARSER_VAR(lex_io_buf)
158
+ #define lex_io_index PARSER_VAR(lex_io_index)
159
+ #define lex_io_total PARSER_VAR(lex_io_total)
160
+ #define lex_io_count PARSER_VAR(lex_io_count)
143
161
  #define lex_gets_ptr PARSER_VAR(lex_gets_ptr)
144
162
  #define lex_input PARSER_VAR(lex_input)
145
163
  #define lex_lastline PARSER_VAR(lex_lastline)
@@ -154,10 +172,9 @@ typedef VALUE stack_type;
154
172
  #define cmdarg_stack PARSER_VAR(cmdarg_stack)
155
173
  #define lval PARSER_VAR(lval)
156
174
  #define eofp PARSER_VAR(eofp)
157
- #define magic_comments PARSER_VAR(magic_comments)
158
175
  #define column PARSER_VAR(column)
159
176
  #define top_node PARSER_VAR(top_node)
160
- #define variables PARSER_VAR(variables)
177
+ #define locals_table PARSER_VAR(locals_table)
161
178
  #define ternary_colon PARSER_VAR(ternary_colon)
162
179
  #define memory_pools PARSER_VAR(memory_pools)
163
180
  #define pool_size PARSER_VAR(pool_size)
@@ -168,20 +185,63 @@ typedef VALUE stack_type;
168
185
  #define verbose PARSER_VAR(verbose)
169
186
  #define parse_error PARSER_VAR(parse_error)
170
187
  #define processor PARSER_VAR(processor)
188
+ #define references PARSER_VAR(references)
171
189
  #define start_lines PARSER_VAR(start_lines)
172
190
  #define sourcefile PARSER_VAR(sourcefile)
173
191
  #define sourceline PARSER_VAR(sourceline)
174
- #define re_mbctab PARSER_VAR(re_mbctab)
175
- #define quark_indexes PARSER_VAR(quark_indexes)
176
- #define quarks PARSER_VAR(quarks)
177
192
 
178
- #undef ismbchar
179
- #define ismbchar(c) re_mbctab[(unsigned char)(c)]
180
- #define mbclen(c) (re_mbctab[(unsigned char)(c)]+1)
193
+ #define node_newnode(t, a, b, c) \
194
+ parser_node_newnode((rb_parser_state*)parser_state, t, a, b, c)
195
+ #define node_add_reference(obj) \
196
+ parser_add_reference((rb_parser_state*)parser_state, obj)
197
+
198
+ NODE *parser_node_newnode(rb_parser_state*, enum node_type, VALUE, VALUE, VALUE);
199
+ VALUE parser_add_reference(rb_parser_state* parser_state, VALUE obj);
200
+
201
+ #undef ID_SCOPE_SHIFT
202
+ #undef ID_SCOPE_MASK
203
+ #undef ID_LOCAL
204
+ #undef ID_INSTANCE
205
+ #undef ID_GLOBAL
206
+ #undef ID_ATTRSET
207
+ #undef ID_CONST
208
+ #undef ID_CLASS
209
+ #undef ID_JUNK
210
+ #undef ID_INTERNAL
211
+
212
+ ID parser_intern(const char*);
213
+ ID parser_intern2(const char*, long);
214
+ ID parser_intern3(const char*, long, rb_encoding*);
215
+ ID parser_intern_str(VALUE);
216
+ char* parser_id2name(ID);
217
+
218
+ #undef ID2SYM
219
+
220
+ /* ID_SCOPE_SHIFT must be at least 4 because at 3 the values will overlap
221
+ * the values of the tokens, causing the parser to mistake the symbol for
222
+ * '*' with the token tAREF. Hilarity ensues when Fixnum * Fixnum ends up
223
+ * parsed as Fixnum[Fixnum].
224
+ */
225
+ #define ID_SCOPE_SHIFT 7
226
+ #define ID_SCOPE_MASK 0x0f
227
+ #define ID_LOCAL 0x00
228
+ #define ID_INSTANCE 0x01
229
+ #define ID_GLOBAL 0x03
230
+ #define ID_ATTRSET 0x04
231
+ #define ID_CONST 0x05
232
+ #define ID_CLASS 0x06
233
+ #define ID_JUNK 0x07
234
+ #define ID_INTERNAL ID_JUNK
235
+
236
+ #ifdef RUBINIUS
237
+ #undef SYMBOL_FLAG
238
+ #define ID2SYM(id) (VALUE)((long)(id >> ID_SCOPE_SHIFT))
239
+ #else
240
+ #define ID2SYM(id) ((VALUE)(((long)(id >> ID_SCOPE_SHIFT))<<8|SYMBOL_FLAG))
241
+ #endif
181
242
 
182
- #define node_newnode(t, a, b, c) parser_node_newnode((rb_parser_state*)parser_state, t, a, b, c)
243
+ #define INTERNAL_ID_P(a) ((a & ID_INTERNAL) == ID_INTERNAL)
183
244
 
184
- quark id_to_quark(rb_parser_state* parser_state, QUID id);
185
245
  };
186
246
 
187
247
  #endif
@@ -1,81 +1,76 @@
1
- #include <vector>
2
- #include <stdlib.h>
3
- #include <assert.h>
4
-
5
1
  #include "namespace.h"
6
2
  #include "melbourne.hpp"
7
3
  #include "var_table.hpp"
8
4
 
9
5
  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);
6
+ int vtable_size(const struct vtable* tbl) {
7
+ if(tbl) {
8
+ return tbl->pos;
9
+ } else {
10
+ return 0;
29
11
  }
30
12
  }
31
13
 
32
- var_table var_table_push(var_table cur) {
33
- var_table vt = var_table_create();
34
- vt->next = cur;
35
- return vt;
14
+ struct vtable* vtable_alloc(struct vtable *prev) {
15
+ struct vtable *tbl = ALLOC(struct vtable);
16
+ tbl->pos = 0;
17
+ tbl->capa = 8;
18
+ tbl->tbl = ALLOC_N(ID, tbl->capa);
19
+ tbl->prev = prev;
20
+ return tbl;
36
21
  }
37
22
 
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);
23
+ void vtable_free(struct vtable* tbl) {
24
+ if(tbl) {
25
+ if(tbl->tbl) {
26
+ xfree(tbl->tbl);
27
+ }
28
+ xfree(tbl);
45
29
  }
46
- return nw;
47
30
  }
48
31
 
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;
32
+ void vtable_free_all(struct vtable* tbl) {
33
+ if(tbl) {
34
+ if(tbl->tbl) {
35
+ xfree(tbl->tbl);
36
+ }
37
+ if(tbl->prev) {
38
+ vtable_free_all(tbl->prev);
39
+ }
40
+ xfree(tbl);
52
41
  }
53
- return -1;
54
42
  }
55
43
 
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;
44
+ void vtable_add(struct vtable* tbl, ID id) {
45
+ if(!tbl) {
46
+ rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
59
47
  }
60
48
 
61
- if(tbl->next) {
62
- return var_table_find_chained(tbl->next, needle);
49
+ if(tbl->pos == tbl->capa) {
50
+ tbl->capa = tbl->capa * 2;
51
+ REALLOC_N(tbl->tbl, ID, tbl->capa);
63
52
  }
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();
53
+ tbl->tbl[tbl->pos++] = id;
70
54
  }
71
55
 
72
- int var_table_size(const var_table tbl)
73
- {
74
- return (int)tbl->quarks->size();
56
+ bool vtable_included(const struct vtable* tbl, ID id) {
57
+ if(tbl) {
58
+ for(int i = 0; i < tbl->pos; i++) {
59
+ if(tbl->tbl[i] == id) {
60
+ return true;
61
+ }
62
+ }
63
+ }
64
+ return false;
75
65
  }
76
66
 
77
- quark var_table_get(const var_table tbl, const int index)
78
- {
79
- return tbl->quarks->at(index);
67
+ void local_vars_free(struct local_vars* vars) {
68
+ struct local_vars* prev;
69
+ for(struct local_vars* local = vars; local; local = prev) {
70
+ if(local->args) vtable_free_all(local->args);
71
+ if(local->vars) vtable_free_all(local->vars);
72
+ prev = local->prev;
73
+ xfree(local);
74
+ }
80
75
  }
81
76
  };
@@ -1,31 +1,34 @@
1
1
  #ifndef MEL_VAR_TABLE_HPP
2
2
  #define MEL_VAR_TABLE_HPP
3
3
 
4
- #include "quark.hpp"
5
-
6
- #ifdef __cplusplus
7
- extern "C" {
4
+ // We must use MRI's xfree for ALLOC'd memory.
5
+ #ifdef RUBINIUS
6
+ #undef xfree
7
+ #define xfree free
8
8
  #endif
9
9
 
10
-
11
10
  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);
11
+ struct vtable {
12
+ ID *tbl;
13
+ int pos;
14
+ int capa;
15
+ struct vtable *prev;
16
+ };
17
+
18
+ struct local_vars {
19
+ struct vtable *args;
20
+ struct vtable *vars;
21
+ struct local_vars *prev;
22
+ };
23
+
24
+ int vtable_size(const struct vtable* tbl);
25
+ struct vtable* vtable_alloc(struct vtable *prev);
26
+ void vtable_free(struct vtable* tbl);
27
+ void vtable_free_all(struct vtable* tbl);
28
+ void vtable_add(struct vtable* tbl, ID id);
29
+ bool vtable_included(const struct vtable* tbl, ID id);
30
+
31
+ void local_vars_free(struct local_vars* vars);
25
32
  };
26
33
 
27
- #ifdef __cplusplus
28
- } /* extern "C" { */
29
- #endif
30
-
31
34
  #endif
@@ -8,15 +8,6 @@
8
8
 
9
9
  namespace MELBOURNE {
10
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
11
  void create_error(rb_parser_state *parser_state, char *msg) {
21
12
  VALUE err_msg;
22
13
 
@@ -62,34 +53,17 @@ namespace MELBOURNE {
62
53
  err_msg,
63
54
  INT2FIX(col),
64
55
  INT2FIX(sourceline),
65
- string_newfrombstr(lex_lastline));
56
+ lex_lastline);
66
57
 
67
58
  parse_error = true;
68
59
  }
69
60
 
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
61
  #define nd_3rd u3.node
87
- #define Q2SYM(v) quark_to_symbol(parser_state, v)
88
62
 
89
- VALUE process_parse_tree(rb_parser_state*, VALUE, NODE*, QUID*);
63
+ VALUE process_parse_tree(rb_parser_state*, VALUE, NODE*, ID*);
90
64
 
91
65
  static VALUE process_dynamic(rb_parser_state *parser_state,
92
- VALUE ptp, NODE *node, QUID *locals)
66
+ VALUE ptp, NODE *node, ID *locals)
93
67
  {
94
68
  VALUE array = rb_ary_new();
95
69
 
@@ -103,8 +77,8 @@ namespace MELBOURNE {
103
77
  return array;
104
78
  }
105
79
 
106
- static VALUE process_iter(rb_parser_state *parser_state, VALUE ptp, NODE *node,
107
- QUID *locals, int *level, ID method, VALUE line)
80
+ static VALUE process_iter(rb_parser_state *parser_state,
81
+ VALUE ptp, NODE *node, ID *locals, int *level, ID method, VALUE line)
108
82
  {
109
83
  VALUE iter, body, args;
110
84
 
@@ -132,7 +106,7 @@ namespace MELBOURNE {
132
106
  * Adapted from ParseTree by Ryan Davis and Eric Hodel.
133
107
  */
134
108
  VALUE process_parse_tree(rb_parser_state *parser_state,
135
- VALUE ptp, NODE *n, QUID *locals)
109
+ VALUE ptp, NODE *n, ID *locals)
136
110
  {
137
111
  NODE * volatile node = n;
138
112
 
@@ -153,6 +127,8 @@ namespace MELBOURNE {
153
127
  return rb_funcall(ptp, rb_intern("process_dangling_node"), 0);
154
128
  }
155
129
 
130
+ // fprintf(stderr, "%s\n", get_node_type_string((enum node_type)nd_type(node)));
131
+
156
132
  switch(nd_type(node)) {
157
133
 
158
134
  case NODE_BLOCK: {
@@ -173,7 +149,7 @@ namespace MELBOURNE {
173
149
  case NODE_COLON2: {
174
150
  VALUE container = process_parse_tree(parser_state, ptp, node->nd_head, locals);
175
151
  tree = rb_funcall(ptp, rb_sColon2, 3, line,
176
- container, Q2SYM(node->nd_mid));
152
+ container, ID2SYM(node->nd_mid));
177
153
  break;
178
154
  }
179
155
  case NODE_MATCH2: {
@@ -193,11 +169,6 @@ namespace MELBOURNE {
193
169
  tree = rb_funcall(ptp, rb_sBegin, 2, line, body);
194
170
  break;
195
171
  }
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
172
  case NODE_IF: {
202
173
  VALUE cond, body = Qnil, else_body = Qnil;
203
174
 
@@ -289,23 +260,32 @@ namespace MELBOURNE {
289
260
  break;
290
261
  }
291
262
  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);
263
+ VALUE args = Qnil;
264
+
265
+ if(node->nd_1st) {
266
+ args = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
296
267
  }
297
268
 
298
- tree = rb_funcall(ptp, rb_sBlockPass, 3, line, iter, body);
269
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
270
+
271
+ tree = rb_funcall(ptp, rb_sBlockPass, 3, line, args, body);
299
272
  break;
300
273
  }
301
274
  case NODE_FOR:
302
275
  tree = process_iter(parser_state, ptp, node, locals, &masgn_level, rb_sFor, line);
303
276
  break;
304
277
 
305
- case NODE_ITER:
306
- tree = process_iter(parser_state, ptp, node, locals, &masgn_level, rb_sIter, line);
278
+ case NODE_ITER: {
279
+ VALUE iter = process_parse_tree(parser_state, ptp, node->nd_iter, locals);
280
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, locals);
281
+ tree = rb_funcall(ptp, rb_sIter, 3, line, iter, body);
307
282
  break;
308
-
283
+ }
284
+ case NODE_LAMBDA: {
285
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_body, locals);
286
+ tree = rb_funcall(ptp, rb_sLambda, 2, line, scope);
287
+ break;
288
+ }
309
289
  case NODE_BREAK: {
310
290
  VALUE expr = Qnil;
311
291
 
@@ -431,8 +411,7 @@ namespace MELBOURNE {
431
411
  if (node->nd_args) {
432
412
  args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
433
413
  }
434
- tree = rb_funcall(ptp, rb_sCall, 4, line,
435
- recv, Q2SYM(node->nd_mid), args);
414
+ tree = rb_funcall(ptp, rb_sCall, 4, line, recv, ID2SYM(node->nd_mid), args);
436
415
  break;
437
416
  }
438
417
  case NODE_FCALL: {
@@ -441,11 +420,11 @@ namespace MELBOURNE {
441
420
  if (node->nd_args) {
442
421
  args = process_parse_tree(parser_state, ptp, node->nd_args, locals);
443
422
  }
444
- tree = rb_funcall(ptp, rb_sFCall, 3, line, Q2SYM(node->nd_mid), args);
423
+ tree = rb_funcall(ptp, rb_sFCall, 3, line, ID2SYM(node->nd_mid), args);
445
424
  break;
446
425
  }
447
426
  case NODE_VCALL:
448
- tree = rb_funcall(ptp, rb_sVCall, 2, line, Q2SYM(node->nd_mid));
427
+ tree = rb_funcall(ptp, rb_sVCall, 2, line, ID2SYM(node->nd_mid));
449
428
  break;
450
429
 
451
430
  case NODE_SUPER: {
@@ -454,8 +433,19 @@ namespace MELBOURNE {
454
433
  break;
455
434
  }
456
435
  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);
436
+ VALUE args = Qnil;
437
+ VALUE bv_locals = Qnil;
438
+
439
+ if(node->nd_args) {
440
+ if(nd_type(node->nd_args) == NODE_ARGS_AUX) {
441
+ args = process_parse_tree(parser_state, ptp, node->nd_args->nd_1st, node->nd_tbl);
442
+ bv_locals = process_parse_tree(parser_state, ptp, node->nd_args->nd_2nd, node->nd_tbl);
443
+ } else {
444
+ args = process_parse_tree(parser_state, ptp, node->nd_args, node->nd_tbl);
445
+ }
446
+ }
447
+ VALUE body = process_parse_tree(parser_state, ptp, node->nd_body, node->nd_tbl);
448
+ tree = rb_funcall(ptp, rb_sScope, 4, line, args, body, bv_locals);
459
449
  break;
460
450
  }
461
451
  case NODE_OP_ASGN1: {
@@ -465,16 +455,16 @@ namespace MELBOURNE {
465
455
  VALUE args = process_parse_tree(parser_state, ptp, node->nd_args->nd_2nd, locals);
466
456
  switch(node->nd_mid) {
467
457
  case 0:
468
- op = ID2SYM(rb_intern("or"));
458
+ op = ID2SYM(parser_intern("or"));
469
459
  break;
470
460
  case 1:
471
- op = ID2SYM(rb_intern("and"));
461
+ op = ID2SYM(parser_intern("and"));
472
462
  break;
473
463
  default:
474
- op = Q2SYM(node->nd_mid);
464
+ op = ID2SYM(node->nd_mid);
475
465
  }
476
466
  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);
467
+ tree = rb_funcall(ptp, rb_sOpAsgn1, 5, line, recv, value, op, args);
478
468
  break;
479
469
  }
480
470
  case NODE_OP_ASGN2: {
@@ -483,17 +473,17 @@ namespace MELBOURNE {
483
473
  VALUE recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
484
474
  switch(node->nd_next->nd_mid) {
485
475
  case 0:
486
- op = ID2SYM(rb_intern("or"));
476
+ op = ID2SYM(parser_intern("or"));
487
477
  break;
488
478
  case 1:
489
- op = ID2SYM(rb_intern("and"));
479
+ op = ID2SYM(parser_intern("and"));
490
480
  break;
491
481
  default:
492
- op = Q2SYM(node->nd_next->nd_mid);
482
+ op = ID2SYM(node->nd_next->nd_mid);
493
483
  }
494
484
  VALUE value = process_parse_tree(parser_state, ptp, node->nd_value, locals);
495
485
  tree = rb_funcall(ptp, rb_sOpAsgn2, 5, line,
496
- recv, Q2SYM(node->nd_next->nd_aid), op, value);
486
+ recv, ID2SYM(node->nd_next->nd_aid), op, value);
497
487
  break;
498
488
  }
499
489
  case NODE_OP_ASGN_AND: {
@@ -527,34 +517,34 @@ namespace MELBOURNE {
527
517
  }
528
518
  case NODE_LASGN: {
529
519
  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);
520
+ tree = rb_funcall(ptp, rb_sLAsgn, 3, line, ID2SYM(node->nd_vid), expr);
531
521
  break;
532
522
  }
533
523
  case NODE_IASGN: {
534
524
  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);
525
+ tree = rb_funcall(ptp, rb_sIAsgn, 3, line, ID2SYM(node->nd_vid), expr);
536
526
  break;
537
527
  }
538
528
  case NODE_CVASGN: {
539
529
  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);
530
+ tree = rb_funcall(ptp, rb_sCVAsgn, 3, line, ID2SYM(node->nd_vid), expr);
541
531
  break;
542
532
  }
543
533
  case NODE_CVDECL: {
544
534
  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);
535
+ tree = rb_funcall(ptp, rb_sCVDecl, 3, line, ID2SYM(node->nd_vid), expr);
546
536
  break;
547
537
  }
548
538
  case NODE_GASGN: {
549
539
  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);
540
+ tree = rb_funcall(ptp, rb_sGAsgn, 3, line, ID2SYM(node->nd_vid), expr);
551
541
  break;
552
542
  }
553
543
  case NODE_CDECL: {
554
544
  VALUE expr;
555
545
 
556
546
  if(node->nd_vid) {
557
- expr = Q2SYM(node->nd_vid);
547
+ expr = ID2SYM(node->nd_vid);
558
548
  } else {
559
549
  expr = process_parse_tree(parser_state, ptp, node->nd_else, locals);
560
550
  }
@@ -564,12 +554,12 @@ namespace MELBOURNE {
564
554
  }
565
555
  case NODE_VALIAS: /* u1 u2 (alias $global $global2) */
566
556
  tree = rb_funcall(ptp, rb_sVAlias, 3, line,
567
- Q2SYM(node->u2.id), Q2SYM(node->u1.id));
557
+ ID2SYM(node->u1.id), ID2SYM(node->u2.id));
568
558
  break;
569
559
 
570
560
  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);
561
+ VALUE to = process_parse_tree(parser_state, ptp, node->u1.node, locals);
562
+ VALUE from = process_parse_tree(parser_state, ptp, node->u2.node, locals);
573
563
  tree = rb_funcall(ptp, rb_sAlias, 3, line, to, from);
574
564
  break;
575
565
  }
@@ -579,7 +569,7 @@ namespace MELBOURNE {
579
569
  break;
580
570
  }
581
571
  case NODE_COLON3: /* u2 (::OUTER_CONST) */
582
- tree = rb_funcall(ptp, rb_sColon3, 2, line, Q2SYM(node->u2.id));
572
+ tree = rb_funcall(ptp, rb_sColon3, 2, line, ID2SYM(node->u2.id));
583
573
  break;
584
574
 
585
575
  case NODE_HASH: {
@@ -611,43 +601,33 @@ namespace MELBOURNE {
611
601
  }
612
602
  case NODE_DSTR: {
613
603
  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);
604
+ tree = rb_funcall(ptp, rb_sDStr, 3, line, node->nd_lit, array);
617
605
  break;
618
606
  }
619
607
  case NODE_DSYM: {
620
608
  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);
609
+ tree = rb_funcall(ptp, rb_sDSym, 3, line, node->nd_lit, array);
624
610
  break;
625
611
  }
626
612
  case NODE_DXSTR: {
627
613
  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);
614
+ tree = rb_funcall(ptp, rb_sDXStr, 3, line, node->nd_lit, array);
631
615
  break;
632
616
  }
633
617
  case NODE_DREGX: {
634
618
  VALUE flags = Qnil;
635
619
 
636
620
  VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
637
- VALUE str = string_newfrombstr(node->nd_str);
638
621
  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);
622
+ tree = rb_funcall(ptp, rb_sDRegx, 4, line, node->nd_lit, array, flags);
641
623
  break;
642
624
  }
643
625
  case NODE_DREGX_ONCE: {
644
626
  VALUE flags = Qnil;
645
627
 
646
628
  VALUE array = process_dynamic(parser_state, ptp, node->nd_next, locals);
647
- VALUE str = string_newfrombstr(node->nd_str);
648
629
  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);
630
+ tree = rb_funcall(ptp, rb_sDRegxOnce, 4, line, node->nd_lit, array, flags);
651
631
  break;
652
632
  }
653
633
  case NODE_DEFN: {
@@ -656,7 +636,7 @@ namespace MELBOURNE {
656
636
  if (node->nd_defn) {
657
637
  body = process_parse_tree(parser_state, ptp, node->nd_defn, locals);
658
638
  }
659
- tree = rb_funcall(ptp, rb_sDefn, 3, line, Q2SYM(node->nd_mid), body);
639
+ tree = rb_funcall(ptp, rb_sDefn, 3, line, ID2SYM(node->nd_mid), body);
660
640
  break;
661
641
  }
662
642
  case NODE_DEFS: {
@@ -666,14 +646,14 @@ namespace MELBOURNE {
666
646
  recv = process_parse_tree(parser_state, ptp, node->nd_recv, locals);
667
647
  body = process_parse_tree(parser_state, ptp, node->nd_defn, locals);
668
648
  }
669
- tree = rb_funcall(ptp, rb_sDefs, 4, line, recv, Q2SYM(node->nd_mid), body);
649
+ tree = rb_funcall(ptp, rb_sDefs, 4, line, recv, ID2SYM(node->nd_mid), body);
670
650
  break;
671
651
  }
672
652
  case NODE_CLASS: {
673
653
  VALUE name, super = Qnil;
674
654
 
675
655
  if (nd_type(node->nd_cpath) == NODE_COLON2 && !node->nd_cpath->nd_vid) {
676
- name = Q2SYM((QUID)node->nd_cpath->nd_mid);
656
+ name = ID2SYM((ID)node->nd_cpath->nd_mid);
677
657
  } else {
678
658
  name = process_parse_tree(parser_state, ptp, node->nd_cpath, locals);
679
659
  }
@@ -688,7 +668,7 @@ namespace MELBOURNE {
688
668
  VALUE name;
689
669
 
690
670
  if (nd_type(node->nd_cpath) == NODE_COLON2 && !node->nd_cpath->nd_vid) {
691
- name = Q2SYM((QUID)node->nd_cpath->nd_mid);
671
+ name = ID2SYM((ID)node->nd_cpath->nd_mid);
692
672
  } else {
693
673
  name = process_parse_tree(parser_state, ptp, node->nd_cpath, locals);
694
674
  }
@@ -702,151 +682,185 @@ namespace MELBOURNE {
702
682
  tree = rb_funcall(ptp, rb_sSClass, 3, line, recv, body);
703
683
  break;
704
684
  }
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;
685
+ case NODE_OPT_ARG: {
686
+ VALUE args = rb_ary_new();
687
+
688
+ do {
689
+ rb_ary_push(args, process_parse_tree(parser_state, ptp, node->nd_body, locals));
690
+ node = node->nd_next;
691
+ } while(node);
709
692
 
710
- /* push regular argument names */
711
- for (; i < max_args; i++) {
712
- rb_ary_push(args, Q2SYM(locals[i + 3]));
693
+ tree = rb_funcall(ptp, rb_sOptArg, 2, line, args);
694
+ break;
695
+ }
696
+ case NODE_ARGS: {
697
+ VALUE args = Qnil;
698
+ VALUE opts = Qnil;
699
+ VALUE splat = Qnil;
700
+ VALUE post = Qnil;
701
+ VALUE block = Qnil;
702
+
703
+ int total_args = 0;
704
+ ID* args_ary = 0;
705
+
706
+ NODE* aux = node->nd_args;
707
+ NODE* post_args = aux->nd_next;
708
+ NODE* masgn = 0;
709
+ NODE* next = 0;
710
+
711
+ if(post_args && post_args->nd_next && nd_type(post_args->nd_next) == NODE_AND) {
712
+ if(post_args->nd_next->nd_head) {
713
+ if (nd_type(post_args->nd_next->nd_head) == NODE_BLOCK) {
714
+ masgn = post_args->nd_next->nd_head->nd_head;
715
+ next = post_args->nd_next->nd_head->nd_next;
716
+ } else {
717
+ masgn = post_args->nd_next->nd_head;
718
+ next = masgn->nd_next;
719
+ // -1 comes from: mlhs_head tSTAR
720
+ if(masgn->nd_cnt == -1) next = 0;
721
+ }
722
+ } else {
723
+ masgn = post_args->nd_next->nd_2nd;
724
+ if(masgn) {
725
+ next = masgn->nd_next;
726
+ if (nd_type(masgn) == NODE_BLOCK) {
727
+ masgn = masgn->nd_head;
728
+ }
729
+ }
730
+ }
713
731
  }
714
732
 
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));
733
+ if(node->nd_argc > 0) {
734
+ total_args = (int)locals[0];
735
+ args_ary = locals + 1;
736
+
737
+ args = rb_ary_new();
738
+ for(int i = 0; i < node->nd_argc && i < total_args; i++) {
739
+ VALUE arg = Qnil;
740
+
741
+ if(!INTERNAL_ID_P(args_ary[i])) {
742
+ arg = ID2SYM(args_ary[i]);
743
+ } else if(masgn) {
744
+ arg = process_parse_tree(parser_state, ptp, masgn, locals);
745
+ if(next && nd_type(next) == NODE_BLOCK) {
746
+ masgn = next->nd_head;
747
+ next = next->nd_next;
748
+ } else {
749
+ masgn = next;
750
+ if(masgn) next = masgn->nd_next;
751
+ }
752
+ }
753
+
754
+ rb_ary_push(args, arg);
729
755
  }
730
- i++; // do not use here but keep track for '*args' name below
731
- optnode = optnode->nd_next;
732
756
  }
733
757
 
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]);
758
+ if(node->nd_opt) {
759
+ opts = process_parse_tree(parser_state, ptp, node->nd_opt, locals);
760
+ }
761
+
762
+ if(INTERNAL_ID_P(aux->nd_rest)) {
763
+ splat = Qtrue;
764
+ } else if(aux->nd_rest) {
765
+ if(aux->nd_rest == 1) {
766
+ // m { |a,| ... }
767
+ splat = Qfalse;
740
768
  } else {
741
- splat = Qtrue;
769
+ splat = ID2SYM(aux->nd_rest);
742
770
  }
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
771
  }
772
+ if(aux->nd_mid) block = ID2SYM(aux->nd_mid);
773
+
774
+ if(post_args && post_args->nd_pid) {
775
+ total_args = (int)locals[0];
776
+ args_ary = locals + 1;
777
+
778
+ int start;
779
+ for(start = 0; start < total_args; start++) {
780
+ if(args_ary[start] == post_args->nd_pid)
781
+ break;
782
+ }
754
783
 
755
- VALUE opt = Qnil;
756
- optnode = node->nd_opt;
757
- if (optnode) {
758
- opt = process_parse_tree(parser_state, ptp, node->nd_opt, locals);
784
+ post = rb_ary_new();
785
+ for(int i = 0; i < post_args->nd_argc && start + i < total_args; i++) {
786
+ VALUE arg = Qnil;
787
+
788
+ if(!INTERNAL_ID_P(args_ary[start + i])) {
789
+ arg = ID2SYM(args_ary[start + i]);
790
+ } else if(masgn) {
791
+ arg = process_parse_tree(parser_state, ptp, masgn, locals);
792
+ if(next && nd_type(next) == NODE_BLOCK) {
793
+ masgn = next->nd_head;
794
+ next = next->nd_next;
795
+ } else {
796
+ masgn = next;
797
+ if(masgn) next = masgn->nd_next;
798
+ }
799
+ }
800
+ rb_ary_push(post, arg);
801
+ }
759
802
  }
760
- masgn_level--;
761
803
 
762
- tree = rb_funcall(ptp, rb_sArgs, 4, line, args, opt, splat);
804
+ tree = rb_funcall(ptp, rb_sArgs, 6, line, args, opts, splat, post, block);
763
805
  break;
764
806
  }
765
807
  case NODE_LVAR:
766
- tree = rb_funcall(ptp, rb_sLVar, 2, line, Q2SYM(node->nd_vid));
808
+ if(!INTERNAL_ID_P(node->nd_vid)) {
809
+ tree = rb_funcall(ptp, rb_sLVar, 2, line, ID2SYM(node->nd_vid));
810
+ }
767
811
  break;
768
812
 
769
813
  case NODE_IVAR:
770
- tree = rb_funcall(ptp, rb_sIVar, 2, line, Q2SYM(node->nd_vid));
814
+ tree = rb_funcall(ptp, rb_sIVar, 2, line, ID2SYM(node->nd_vid));
771
815
  break;
772
816
 
773
817
  case NODE_CVAR:
774
- tree = rb_funcall(ptp, rb_sCVar, 2, line, Q2SYM(node->nd_vid));
818
+ tree = rb_funcall(ptp, rb_sCVar, 2, line, ID2SYM(node->nd_vid));
775
819
  break;
776
820
 
777
821
  case NODE_GVAR:
778
- tree = rb_funcall(ptp, rb_sGVar, 2, line, Q2SYM(node->nd_vid));
822
+ tree = rb_funcall(ptp, rb_sGVar, 2, line, ID2SYM(node->nd_vid));
779
823
  break;
780
824
 
781
825
  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));
826
+ tree = rb_funcall(ptp, rb_sConst, 2, line, ID2SYM(node->nd_vid));
787
827
  break;
788
828
 
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
829
  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);
830
+ tree = rb_funcall(ptp, rb_sXStr, 2, line, node->nd_lit);
823
831
  break;
824
832
 
825
833
  case NODE_STR: /* u1 */
826
- tree = rb_funcall(ptp, rb_sStr, 2, line,
827
- string_newfrombstr(node->nd_str));
828
- bdestroy(node->nd_str);
834
+ tree = rb_funcall(ptp, rb_sStr, 2, line, node->nd_lit);
829
835
  break;
830
836
 
831
837
  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);
838
+ tree = rb_funcall(ptp, rb_sRegex, 3, line, node->nd_lit,
839
+ INT2FIX(node->nd_cnt));
835
840
  break;
836
841
 
837
842
  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);
843
+ tree = rb_funcall(ptp, rb_sMatch, 3, line, node->nd_lit,
844
+ INT2FIX(node->nd_cnt));
841
845
  break;
842
846
 
843
847
  case NODE_LIT:
844
- tree = rb_funcall(ptp, rb_sLit, 2, line, Q2SYM((uintptr_t)node->nd_lit));
848
+ tree = rb_funcall(ptp, rb_sLit, 2, line, node->nd_lit);
845
849
  break;
846
850
 
847
- case NODE_NEWLINE:
848
- node = node->nd_next;
849
- goto again;
851
+ case NODE_VALUES: {
852
+ VALUE first = process_parse_tree(parser_state, ptp, node->nd_head, locals);
853
+ VALUE rest = process_parse_tree(parser_state, ptp, node->nd_args, locals);
854
+ tree = rb_funcall(ptp, rb_sValues, 3, line, first, rest);
855
+ break;
856
+ }
857
+
858
+ case NODE_NUMBER:
859
+ tree = rb_funcall(ptp, rb_sNumber, 2, line, node->nd_lit);
860
+ break;
861
+
862
+ case NODE_FLOAT:
863
+ tree = rb_funcall(ptp, rb_sFloat, 2, line, node->nd_lit);
850
864
  break;
851
865
 
852
866
  case NODE_NTH_REF: /* u2 u3 ($1) - u3 is local_cnt('~') ignorable? */
@@ -857,12 +871,12 @@ namespace MELBOURNE {
857
871
  char str[2];
858
872
  str[0] = node->nd_nth;
859
873
  str[1] = 0;
860
- tree = rb_funcall(ptp, rb_sBackRef, 2, line, ID2SYM(rb_intern(str)));
874
+ tree = rb_funcall(ptp, rb_sBackRef, 2, line, ID2SYM(parser_intern(str)));
861
875
  break;
862
876
  }
863
877
 
864
878
  case NODE_BLOCK_ARG: /* u1 u3 (def x(&b) */
865
- tree = rb_funcall(ptp, rb_sBlockArg, 2, line, Q2SYM(node->u1.id));
879
+ tree = rb_funcall(ptp, rb_sBlockArg, 2, line, ID2SYM(node->u1.id));
866
880
  break;
867
881
 
868
882
  case NODE_RETRY:
@@ -901,6 +915,10 @@ namespace MELBOURNE {
901
915
  tree = rb_funcall(ptp, rb_sFile, 1, line);
902
916
  break;
903
917
 
918
+ case NODE_ENCODING:
919
+ tree = rb_funcall(ptp, rb_sEncoding, 2, line, node->nd_lit);
920
+ break;
921
+
904
922
  case NODE_SPLAT: {
905
923
  VALUE expr = process_parse_tree(parser_state, ptp, node->nd_head, locals);
906
924
  tree = rb_funcall(ptp, rb_sSplat, 2, line, expr);
@@ -911,11 +929,6 @@ namespace MELBOURNE {
911
929
  tree = rb_funcall(ptp, rb_sToAry, 2, line, expr);
912
930
  break;
913
931
  }
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
932
  case NODE_ATTRASGN: { /* literal.meth = y u1 u2 u3 */
920
933
  VALUE recv;
921
934
 
@@ -927,7 +940,7 @@ namespace MELBOURNE {
927
940
  }
928
941
  VALUE value = process_parse_tree(parser_state, ptp, node->nd_3rd, locals);
929
942
  tree = rb_funcall(ptp, rb_sAttrAsgn, 4, line,
930
- recv, Q2SYM(node->u2.id), value);
943
+ recv, ID2SYM(node->u2.id), value);
931
944
  break;
932
945
  }
933
946
  case NODE_EVSTR: {
@@ -935,19 +948,27 @@ namespace MELBOURNE {
935
948
  tree = rb_funcall(ptp, rb_sEvStr, 2, line, value);
936
949
  break;
937
950
  }
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
951
  case NODE_PREEXE: { /* BEGIN { ... } */
944
- tree = rb_funcall(ptp, rb_sPreExe, 1, line);
952
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
953
+ tree = rb_funcall(ptp, rb_sPreExe, 2, line, scope);
945
954
  break;
946
955
  }
947
- case NODE_POSTEXE: /* END { ... } */
948
- tree = rb_funcall(ptp, rb_sPostExe, 1, line);
956
+ case NODE_POSTEXE: { /* END { ... } */
957
+ VALUE scope = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
958
+ tree = rb_funcall(ptp, rb_sPostExe, 2, line, scope);
949
959
  break;
960
+ }
961
+ case NODE_POSTARG: {
962
+ VALUE into = Qnil;
963
+ if(node->nd_1st != RNODE(-1)) {
964
+ into = process_parse_tree(parser_state, ptp, node->nd_1st, locals);
965
+ }
966
+
967
+ VALUE rest = process_parse_tree(parser_state, ptp, node->nd_2nd, locals);
950
968
 
969
+ tree = rb_funcall(ptp, rb_sPostArg, 3, line, into, rest);
970
+ break;
971
+ }
951
972
  default: {
952
973
  VALUE node_name = rb_str_new2(get_node_type_string((enum node_type)nd_type(node)));
953
974
  VALUE node_type = INT2FIX(nd_type(node));