Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ripper.y
Go to the documentation of this file.
1 /**********************************************************************
2
3 parse.y -
4
5 $Author: nagachika $
6 created at: Fri May 28 18:02:42 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10 **********************************************************************/
11
12 %{
13
14 #ifndef PARSER_DEBUG
15 #define PARSER_DEBUG 0
16 #endif
17 #define YYDEBUG 1
18 #define YYERROR_VERBOSE 1
19 #define YYSTACK_USE_ALLOCA 0
20
21 #include "ruby/ruby.h"
22 #include "ruby/st.h"
23 #include "ruby/encoding.h"
24 #include "internal.h"
25 #include "node.h"
26 #include "parse.h"
27 #include "id.h"
28 #include "regenc.h"
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include "probes.h"
33
34 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
35
36 #define YYMALLOC(size) rb_parser_malloc(parser, (size))
37 #define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
38 #define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
39 #define YYFREE(ptr) rb_parser_free(parser, (ptr))
40 #define malloc YYMALLOC
41 #define realloc YYREALLOC
42 #define calloc YYCALLOC
43 #define free YYFREE
44
45 #ifndef RIPPER
46 static ID register_symid(ID, const char *, long, rb_encoding *);
47 static ID register_symid_str(ID, VALUE);
48 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
49 #include "id.c"
50 #endif
51
52 #define is_notop_id(id) ((id)>tLAST_OP_ID)
53 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
54 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
55 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
56 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
57 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
58 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
59 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
60 #define id_type(id) (is_notop_id(id) ? (int)((id)&ID_SCOPE_MASK) : -1)
61
62 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
63 (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
64 ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
65 ((id)&ID_SCOPE_MASK) == ID_CLASS))
66
67 enum lex_state_bits {
68 EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
69 EXPR_END_bit, /* newline significant, +/- is an operator. */
70 EXPR_ENDARG_bit, /* ditto, and unbound braces. */
71 EXPR_ENDFN_bit, /* ditto, and unbound braces. */
72 EXPR_ARG_bit, /* newline significant, +/- is an operator. */
73 EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
74 EXPR_MID_bit, /* newline significant, +/- is an operator. */
75 EXPR_FNAME_bit, /* ignore newline, no reserved words. */
76 EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
77 EXPR_CLASS_bit, /* immediate after `class', no here document. */
78 EXPR_VALUE_bit, /* alike EXPR_BEG but label is disallowed. */
79 EXPR_MAX_STATE
80 };
81 /* examine combinations */
82 enum lex_state_e {
83 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
84 DEF_EXPR(BEG),
85 DEF_EXPR(END),
86 DEF_EXPR(ENDARG),
87 DEF_EXPR(ENDFN),
88 DEF_EXPR(ARG),
89 DEF_EXPR(CMDARG),
90 DEF_EXPR(MID),
91 DEF_EXPR(FNAME),
92 DEF_EXPR(DOT),
93 DEF_EXPR(CLASS),
94 DEF_EXPR(VALUE),
95 EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
96 EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
97 EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
98 };
99 #define IS_lex_state_for(x, ls) ((x) & (ls))
100 #define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
101
102 #if PARSER_DEBUG
103 static const char *lex_state_name(enum lex_state_e state);
104 #endif
105
106 typedef VALUE stack_type;
107
108 # define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
109 # define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
110 # define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
111 # define BITSTACK_SET_P(stack) ((stack)&1)
112
113 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
114 #define COND_POP() BITSTACK_POP(cond_stack)
115 #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
116 #define COND_P() BITSTACK_SET_P(cond_stack)
117
118 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
119 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
120 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
121 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
122
123 struct vtable {
124 ID *tbl;
125 int pos;
126 int capa;
127 struct vtable *prev;
128 };
129
130 struct local_vars {
131 struct vtable *args;
132 struct vtable *vars;
133 struct vtable *used;
134 struct local_vars *prev;
135 };
136
137 #define DVARS_INHERIT ((void*)1)
138 #define DVARS_TOPSCOPE NULL
139 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
140 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
141
142 static int
143 vtable_size(const struct vtable *tbl)
144 {
145 if (POINTER_P(tbl)) {
146 return tbl->pos;
147 }
148 else {
149 return 0;
150 }
151 }
152
153 #define VTBL_DEBUG 0
154
155 static struct vtable *
156 vtable_alloc(struct vtable *prev)
157 {
158 struct vtable *tbl = ALLOC(struct vtable);
159 tbl->pos = 0;
160 tbl->capa = 8;
161 tbl->tbl = ALLOC_N(ID, tbl->capa);
162 tbl->prev = prev;
163 if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
164 return tbl;
165 }
166
167 static void
168 vtable_free(struct vtable *tbl)
169 {
170 if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
171 if (POINTER_P(tbl)) {
172 if (tbl->tbl) {
173 xfree(tbl->tbl);
174 }
175 xfree(tbl);
176 }
177 }
178
179 static void
180 vtable_add(struct vtable *tbl, ID id)
181 {
182 if (!POINTER_P(tbl)) {
183 rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
184 }
185 if (VTBL_DEBUG) printf("vtable_add: %p, %s\n", (void *)tbl, rb_id2name(id));
186
187 if (tbl->pos == tbl->capa) {
188 tbl->capa = tbl->capa * 2;
189 REALLOC_N(tbl->tbl, ID, tbl->capa);
190 }
191 tbl->tbl[tbl->pos++] = id;
192 }
193
194 static int
195 vtable_included(const struct vtable * tbl, ID id)
196 {
197 int i;
198
199 if (POINTER_P(tbl)) {
200 for (i = 0; i < tbl->pos; i++) {
201 if (tbl->tbl[i] == id) {
202 return i+1;
203 }
204 }
205 }
206 return 0;
207 }
208
209
210 #ifndef RIPPER
211 typedef struct token_info {
212 const char *token;
213 int linenum;
214 int column;
215 int nonspc;
216 struct token_info *next;
217 } token_info;
218 #endif
219
220 /*
221 Structure of Lexer Buffer:
222
223 lex_pbeg tokp lex_p lex_pend
224 | | | |
225 |-----------+--------------+------------|
226 |<------------>|
227 token
228 */
229 struct parser_params {
230 int is_ripper;
231 NODE *heap;
232
233 YYSTYPE *parser_yylval;
234 VALUE eofp;
235
236 NODE *parser_lex_strterm;
237 enum lex_state_e parser_lex_state;
238 stack_type parser_cond_stack;
239 stack_type parser_cmdarg_stack;
240 int parser_class_nest;
241 int parser_paren_nest;
242 int parser_lpar_beg;
243 int parser_in_single;
244 int parser_in_def;
245 int parser_brace_nest;
246 int parser_compile_for_eval;
247 VALUE parser_cur_mid;
248 int parser_in_defined;
249 char *parser_tokenbuf;
250 int parser_tokidx;
251 int parser_toksiz;
252 int parser_tokline;
253 VALUE parser_lex_input;
254 VALUE parser_lex_lastline;
255 VALUE parser_lex_nextline;
256 const char *parser_lex_pbeg;
257 const char *parser_lex_p;
258 const char *parser_lex_pend;
259 int parser_heredoc_end;
260 int parser_command_start;
261 NODE *parser_deferred_nodes;
262 long parser_lex_gets_ptr;
263 VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
264 struct local_vars *parser_lvtbl;
265 int parser_ruby__end__seen;
266 int line_count;
267 int has_shebang;
268 char *parser_ruby_sourcefile; /* current source file */
269 int parser_ruby_sourceline; /* current line no. */
270 rb_encoding *enc;
271
272 int parser_yydebug;
273
274 #ifndef RIPPER
275 /* Ruby core only */
276 NODE *parser_eval_tree_begin;
277 NODE *parser_eval_tree;
278 VALUE debug_lines;
279 VALUE coverage;
280 int nerr;
281
282 int parser_token_info_enabled;
283 token_info *parser_token_info;
284 #else
285 /* Ripper only */
286 VALUE parser_ruby_sourcefile_string;
287 const char *tokp;
288 VALUE delayed;
289 int delayed_line;
290 int delayed_col;
291
292 VALUE value;
293 VALUE result;
294 VALUE parsing_thread;
295 int toplevel_p;
296 #endif
297 };
298
299 #define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
300 #define STR_NEW0() rb_enc_str_new(0,0,current_enc)
301 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
302 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
303 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
304 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), current_enc)
305
306 static int parser_yyerror(struct parser_params*, const char*);
307 #define yyerror(msg) parser_yyerror(parser, (msg))
308
309 #define YYLEX_PARAM parser
310
311 #define lex_strterm (parser->parser_lex_strterm)
312 #define lex_state (parser->parser_lex_state)
313 #define cond_stack (parser->parser_cond_stack)
314 #define cmdarg_stack (parser->parser_cmdarg_stack)
315 #define class_nest (parser->parser_class_nest)
316 #define paren_nest (parser->parser_paren_nest)
317 #define lpar_beg (parser->parser_lpar_beg)
318 #define brace_nest (parser->parser_brace_nest)
319 #define in_single (parser->parser_in_single)
320 #define in_def (parser->parser_in_def)
321 #define compile_for_eval (parser->parser_compile_for_eval)
322 #define cur_mid (parser->parser_cur_mid)
323 #define in_defined (parser->parser_in_defined)
324 #define tokenbuf (parser->parser_tokenbuf)
325 #define tokidx (parser->parser_tokidx)
326 #define toksiz (parser->parser_toksiz)
327 #define tokline (parser->parser_tokline)
328 #define lex_input (parser->parser_lex_input)
329 #define lex_lastline (parser->parser_lex_lastline)
330 #define lex_nextline (parser->parser_lex_nextline)
331 #define lex_pbeg (parser->parser_lex_pbeg)
332 #define lex_p (parser->parser_lex_p)
333 #define lex_pend (parser->parser_lex_pend)
334 #define heredoc_end (parser->parser_heredoc_end)
335 #define command_start (parser->parser_command_start)
336 #define deferred_nodes (parser->parser_deferred_nodes)
337 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
338 #define lex_gets (parser->parser_lex_gets)
339 #define lvtbl (parser->parser_lvtbl)
340 #define ruby__end__seen (parser->parser_ruby__end__seen)
341 #define ruby_sourceline (parser->parser_ruby_sourceline)
342 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
343 #define current_enc (parser->enc)
344 #define yydebug (parser->parser_yydebug)
345 #ifdef RIPPER
346 #else
347 #define ruby_eval_tree (parser->parser_eval_tree)
348 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
349 #define ruby_debug_lines (parser->debug_lines)
350 #define ruby_coverage (parser->coverage)
351 #endif
352
353 static int yylex(void*, void*);
354
355 #ifndef RIPPER
356 #define yyparse ruby_yyparse
357
358 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
359 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
360
361 static NODE *cond_gen(struct parser_params*,NODE*);
362 #define cond(node) cond_gen(parser, (node))
363 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
364 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
365
366 static NODE *newline_node(NODE*);
367 static void fixpos(NODE*,NODE*);
368
369 static int value_expr_gen(struct parser_params*,NODE*);
370 static void void_expr_gen(struct parser_params*,NODE*);
371 static NODE *remove_begin(NODE*);
372 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
373 #define void_expr0(node) void_expr_gen(parser, (node))
374 #define void_expr(node) void_expr0((node) = remove_begin(node))
375 static void void_stmts_gen(struct parser_params*,NODE*);
376 #define void_stmts(node) void_stmts_gen(parser, (node))
377 static void reduce_nodes_gen(struct parser_params*,NODE**);
378 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
379 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
380 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
381
382 static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
383 #define block_append(h,t) block_append_gen(parser,(h),(t))
384 static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
385 #define list_append(l,i) list_append_gen(parser,(l),(i))
386 static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
387 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
388 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
389 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
390 static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
391 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
392 static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
393 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
394 static int literal_concat0(struct parser_params *, VALUE, VALUE);
395 static NODE *new_evstr_gen(struct parser_params*,NODE*);
396 #define new_evstr(n) new_evstr_gen(parser,(n))
397 static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
398 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
399 static NODE *splat_array(NODE*);
400
401 static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
402 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
403 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
404 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
405
406 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
407 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
408 static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
409 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
410
411 static NODE *negate_lit(NODE*);
412 static NODE *ret_args_gen(struct parser_params*,NODE*);
413 #define ret_args(node) ret_args_gen(parser, (node))
414 static NODE *arg_blk_pass(NODE*,NODE*);
415 static NODE *new_yield_gen(struct parser_params*,NODE*);
416 #define new_yield(node) new_yield_gen(parser, (node))
417 static NODE *dsym_node_gen(struct parser_params*,NODE*);
418 #define dsym_node(node) dsym_node_gen(parser, (node))
419
420 static NODE *gettable_gen(struct parser_params*,ID);
421 #define gettable(id) gettable_gen(parser,(id))
422 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
423 #define assignable(id,node) assignable_gen(parser, (id), (node))
424
425 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
426 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
427 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
428 #define attrset(node,id) attrset_gen(parser, (node), (id))
429
430 static void rb_backref_error_gen(struct parser_params*,NODE*);
431 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
432 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
433 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
434
435 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
436 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
437 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
438 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
439 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
440
441 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
442 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
443
444 static ID *local_tbl_gen(struct parser_params*);
445 #define local_tbl() local_tbl_gen(parser)
446
447 static void fixup_nodes(NODE **);
448
449 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
450 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
451 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
452 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
453 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
454 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
455 static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
456 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
457
458 #define get_id(id) (id)
459 #define get_value(val) (val)
460 #else
461 #define value_expr(node) ((void)(node))
462 #define remove_begin(node) (node)
463 #define rb_dvar_defined(id) 0
464 #define rb_local_defined(id) 0
465 static ID ripper_get_id(VALUE);
466 #define get_id(id) ripper_get_id(id)
467 static VALUE ripper_get_value(VALUE);
468 #define get_value(val) ripper_get_value(val)
469 static VALUE assignable_gen(struct parser_params*,VALUE);
470 #define assignable(lhs,node) assignable_gen(parser, (lhs))
471 static int id_is_var_gen(struct parser_params *parser, ID id);
472 #define id_is_var(id) id_is_var_gen(parser, (id))
473
474 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
475
476 static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
477 static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
478 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
479
480 #endif /* !RIPPER */
481
482 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
483
484 static ID formal_argument_gen(struct parser_params*, ID);
485 #define formal_argument(id) formal_argument_gen(parser, (id))
486 static ID shadowing_lvar_gen(struct parser_params*,ID);
487 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
488 static void new_bv_gen(struct parser_params*,ID);
489 #define new_bv(id) new_bv_gen(parser, (id))
490
491 static void local_push_gen(struct parser_params*,int);
492 #define local_push(top) local_push_gen(parser,(top))
493 static void local_pop_gen(struct parser_params*);
494 #define local_pop() local_pop_gen(parser)
495 static int local_var_gen(struct parser_params*, ID);
496 #define local_var(id) local_var_gen(parser, (id))
497 static int arg_var_gen(struct parser_params*, ID);
498 #define arg_var(id) arg_var_gen(parser, (id))
499 static int local_id_gen(struct parser_params*, ID);
500 #define local_id(id) local_id_gen(parser, (id))
501 static ID internal_id_gen(struct parser_params*);
502 #define internal_id() internal_id_gen(parser)
503
504 static const struct vtable *dyna_push_gen(struct parser_params *);
505 #define dyna_push() dyna_push_gen(parser)
506 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
507 #define dyna_pop(node) dyna_pop_gen(parser, (node))
508 static int dyna_in_block_gen(struct parser_params*);
509 #define dyna_in_block() dyna_in_block_gen(parser)
510 #define dyna_var(id) local_var(id)
511 static int dvar_defined_gen(struct parser_params*,ID,int);
512 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
513 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
514 static int dvar_curr_gen(struct parser_params*,ID);
515 #define dvar_curr(id) dvar_curr_gen(parser, (id))
516
517 static int lvar_defined_gen(struct parser_params*, ID);
518 #define lvar_defined(id) lvar_defined_gen(parser, (id))
519
520 #define RE_OPTION_ONCE (1<<16)
521 #define RE_OPTION_ENCODING_SHIFT 8
522 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
523 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
524 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
525 #define RE_OPTION_MASK 0xff
526 #define RE_OPTION_ARG_ENCODING_NONE 32
527
528 #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
529 #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
530 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
531 #define nd_func u1.id
532 #if SIZEOF_SHORT == 2
533 #define nd_term(node) ((signed short)(node)->u2.id)
534 #else
535 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
536 #endif
537 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
538 #define nd_nest u3.cnt
539
540 /****** Ripper *******/
541
542 #ifdef RIPPER
543 #define RIPPER_VERSION "0.1.0"
544
545 #include "eventids1.c"
546 #include "eventids2.c"
547
548 static VALUE ripper_dispatch0(struct parser_params*,ID);
549 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
550 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
551 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
552 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
553 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
554 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
555
556 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
557 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
558 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
559 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
560 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
561 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
562 #define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
563
564 #define yyparse ripper_yyparse
565
566 #define ripper_intern(s) ID2SYM(rb_intern(s))
567 static VALUE ripper_id2sym(ID);
568 #ifdef __GNUC__
569 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
570 ID2SYM(id) : ripper_id2sym(id))
571 #endif
572
573 #define arg_new() dispatch0(args_new)
574 #define arg_add(l,a) dispatch2(args_add, (l), (a))
575 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
576 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
577 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
578 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
579 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
580
581 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
582 #define mrhs_new() dispatch0(mrhs_new)
583 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
584 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
585
586 #define mlhs_new() dispatch0(mlhs_new)
587 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
588 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
589
590 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
591 dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
592
593 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
594 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
595 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
596
597 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
598 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
599 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
600
601 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
602
603 static inline VALUE
604 new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
605 {
606 NODE *t = (NODE *)tail;
607 VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
608 return params_new(f, o, r, p, k, kr, escape_Qundef(b));
609 }
610 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
611
612 static inline VALUE
613 new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
614 {
615 return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
616 }
617 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
618
619 #define FIXME 0
620
621 #endif /* RIPPER */
622
623 #ifndef RIPPER
624 # define Qnone 0
625 # define ifndef_ripper(x) (x)
626 #else
627 # define Qnone Qnil
628 # define ifndef_ripper(x)
629 #endif
630
631 #ifndef RIPPER
632 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
633 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
634 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
635 # define rb_warn4S(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a))
636 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
637 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
638 #else
639 # define rb_warn0(fmt) ripper_warn0(parser, (fmt))
640 # define rb_warnI(fmt,a) ripper_warnI(parser, (fmt), (a))
641 # define rb_warnS(fmt,a) ripper_warnS(parser, (fmt), (a))
642 # define rb_warn4S(file,line,fmt,a) ripper_warnS(parser, (fmt), (a))
643 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
644 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
645 static void ripper_warn0(struct parser_params*, const char*);
646 static void ripper_warnI(struct parser_params*, const char*, int);
647 static void ripper_warnS(struct parser_params*, const char*, const char*);
648 static void ripper_warning0(struct parser_params*, const char*);
649 static void ripper_warningS(struct parser_params*, const char*, const char*);
650 #endif
651
652 #ifdef RIPPER
653 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
654 # define rb_compile_error ripper_compile_error
655 # define compile_error ripper_compile_error
656 # define PARSER_ARG parser,
657 #else
658 # define rb_compile_error rb_compile_error_with_enc
659 # define compile_error parser->nerr++,rb_compile_error_with_enc
660 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
661 #endif
662
663 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
664 for instance). This is too low for Ruby to parse some files, such as
665 date/format.rb, therefore bump the value up to at least Bison's default. */
666 #ifdef OLD_YACC
667 #ifndef YYMAXDEPTH
668 #define YYMAXDEPTH 10000
669 #endif
670 #endif
671
672 #ifndef RIPPER
673 static void token_info_push(struct parser_params*, const char *token);
674 static void token_info_pop(struct parser_params*, const char *token);
675 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
676 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
677 #else
678 #define token_info_push(token) /* nothing */
679 #define token_info_pop(token) /* nothing */
680 #endif
681 %}
682
683 %pure_parser
684 %parse-param {struct parser_params *parser}
685
686 %union {
687 VALUE val;
688 NODE *node;
689 ID id;
690 int num;
691 const struct vtable *vars;
692 }
693
694 /*
695 %token
696 */
697 %token <val>
698
699 keyword_class
700 keyword_module
701 keyword_def
702 keyword_undef
703 keyword_begin
704 keyword_rescue
705 keyword_ensure
706 keyword_end
707 keyword_if
708 keyword_unless
709 keyword_then
710 keyword_elsif
711 keyword_else
712 keyword_case
713 keyword_when
714 keyword_while
715 keyword_until
716 keyword_for
717 keyword_break
718 keyword_next
719 keyword_redo
720 keyword_retry
721 keyword_in
722 keyword_do
723 keyword_do_cond
724 keyword_do_block
725 keyword_do_LAMBDA
726 keyword_return
727 keyword_yield
728 keyword_super
729 keyword_self
730 keyword_nil
731 keyword_true
732 keyword_false
733 keyword_and
734 keyword_or
735 keyword_not
736 modifier_if
737 modifier_unless
738 modifier_while
739 modifier_until
740 modifier_rescue
741 keyword_alias
742 keyword_defined
743 keyword_BEGIN
744 keyword_END
745 keyword__LINE__
746 keyword__FILE__
747 keyword__ENCODING__
748
749 %token <val> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
750 %token <val> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
751 %token <val> tNTH_REF tBACK_REF
752 %token <val> tREGEXP_END
753
754 %type <val> singleton strings string string1 xstring regexp
755 %type <val> string_contents xstring_contents regexp_contents string_content
756 %type <val> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
757 %type <val> literal numeric dsym cpath
758 %type <val> top_compstmt top_stmts top_stmt
759 %type <val> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
760 %type <val> expr_value arg_value primary_value fcall
761 %type <val> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
762 %type <val> args call_args opt_call_args
763 %type <val> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
764 %type <val> command_args aref_args opt_block_arg block_arg var_ref var_lhs
765 %type <val> command_asgn mrhs superclass block_call block_command
766 %type <val> f_block_optarg f_block_opt
767 %type <val> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
768 %type <val> assoc_list assocs assoc undef_list backref string_dvar for_var
769 %type <val> block_param opt_block_param block_param_def f_opt
770 %type <val> f_kwarg f_kw f_block_kwarg f_block_kw
771 %type <val> bv_decls opt_bv_decl bvar
772 %type <val> lambda f_larglist lambda_body
773 %type <val> brace_block cmd_brace_block do_block lhs none fitem
774 %type <val> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
775 %type <val> fsym keyword_variable user_variable sym symbol operation operation2 operation3
776 %type <val> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
777 %type <val> f_kwrest
778 /*
779 */
780 %type <val> program reswords then do dot_or_colon
781
782 %token END_OF_INPUT 0 "end-of-input"
783 %token tUPLUS 130 "unary+"
784 %token tUMINUS 131 "unary-"
785 %token tPOW 132 "**"
786 %token tCMP 134 "<=>"
787 %token tEQ 139 "=="
788 %token tEQQ 140 "==="
789 %token tNEQ 141 "!="
790 %token tGEQ 138 ">="
791 %token tLEQ 137 "<="
792 %token tANDOP "&&"
793 %token tOROP "||"
794 %token tMATCH 142 "=~"
795 %token tNMATCH 143 "!~"
796 %token tDOT2 128 ".."
797 %token tDOT3 129 "..."
798 %token tAREF 144 "[]"
799 %token tASET 145 "[]="
800 %token tLSHFT 135 "<<"
801 %token tRSHFT 136 ">>"
802 %token tCOLON2 "::"
803 %token tCOLON3 ":: at EXPR_BEG"
804 %token <val> tOP_ASGN /* +=, -= etc. */
805 %token tASSOC "=>"
806 %token tLPAREN "("
807 %token tLPAREN_ARG "( arg"
808 %token tRPAREN ")"
809 %token tLBRACK "["
810 %token tLBRACE "{"
811 %token tLBRACE_ARG "{ arg"
812 %token tSTAR "*"
813 %token tDSTAR "**arg"
814 %token tAMPER "&"
815 %token tLAMBDA "->"
816 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
817 %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
818
819 /*
820 * precedence table
821 */
822
823 %nonassoc tLOWEST
824 %nonassoc tLBRACE_ARG
825
826 %nonassoc modifier_if modifier_unless modifier_while modifier_until
827 %left keyword_or keyword_and
828 %right keyword_not
829 %nonassoc keyword_defined
830 %right '=' tOP_ASGN
831 %left modifier_rescue
832 %right '?' ':'
833 %nonassoc tDOT2 tDOT3
834 %left tOROP
835 %left tANDOP
836 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
837 %left '>' tGEQ '<' tLEQ
838 %left '|' '^'
839 %left '&'
840 %left tLSHFT tRSHFT
841 %left '+' '-'
842 %left '*' '/' '%'
843 %right tUMINUS_NUM tUMINUS
844 %right tPOW
845 %right '!' '~' tUPLUS
846
847 %token tLAST_TOKEN
848
849 %%
850 program : {
851 lex_state = EXPR_BEG;
852 #if 0
853 local_push(compile_for_eval || rb_parse_in_main());
854 #endif
855 local_push(0);
856
857 }
858 top_compstmt
859 {
860 #if 0
861 if ($2 && !compile_for_eval) {
862 /* last expression should not be void */
863 if (nd_type($2) != NODE_BLOCK) void_expr($2);
864 else {
865 NODE *node = $2;
866 while (node->nd_next) {
867 node = node->nd_next;
868 }
869 void_expr(node->nd_head);
870 }
871 }
872 ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
873 #endif
874 $$ = $2;
875 parser->result = dispatch1(program, $$);
876
877 local_pop();
878 }
879 ;
880
881 top_compstmt : top_stmts opt_terms
882 {
883 #if 0
884 void_stmts($1);
885 fixup_nodes(&deferred_nodes);
886 #endif
887
888 $$ = $1;
889 }
890 ;
891
892 top_stmts : none
893 {
894 #if 0
895 $$ = NEW_BEGIN(0);
896 #endif
897 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
898 dispatch0(void_stmt));
899
900 }
901 | top_stmt
902 {
903 #if 0
904 $$ = newline_node($1);
905 #endif
906 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
907
908 }
909 | top_stmts terms top_stmt
910 {
911 #if 0
912 $$ = block_append($1, newline_node($3));
913 #endif
914 $$ = dispatch2(stmts_add, $1, $3);
915
916 }
917 | error top_stmt
918 {
919 $$ = remove_begin($2);
920 }
921 ;
922
923 top_stmt : stmt
924 | keyword_BEGIN
925 {
926 #if 0
927 /* local_push(0); */
928 #endif
929
930 }
931 '{' top_compstmt '}'
932 {
933 #if 0
934 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
935 $4);
936 /* NEW_PREEXE($4)); */
937 /* local_pop(); */
938 $$ = NEW_BEGIN(0);
939 #endif
940 $$ = dispatch1(BEGIN, $4);
941
942 }
943 ;
944
945 bodystmt : compstmt
946 opt_rescue
947 opt_else
948 opt_ensure
949 {
950 #if 0
951 $$ = $1;
952 if ($2) {
953 $$ = NEW_RESCUE($1, $2, $3);
954 }
955 else if ($3) {
956 rb_warn0("else without rescue is useless");
957 $$ = block_append($$, $3);
958 }
959 if ($4) {
960 if ($$) {
961 $$ = NEW_ENSURE($$, $4);
962 }
963 else {
964 $$ = block_append($4, NEW_NIL());
965 }
966 }
967 fixpos($$, $1);
968 #endif
969 $$ = dispatch4(bodystmt,
970 escape_Qundef($1),
971 escape_Qundef($2),
972 escape_Qundef($3),
973 escape_Qundef($4));
974
975 }
976 ;
977
978 compstmt : stmts opt_terms
979 {
980 #if 0
981 void_stmts($1);
982 fixup_nodes(&deferred_nodes);
983 #endif
984
985 $$ = $1;
986 }
987 ;
988
989 stmts : none
990 {
991 #if 0
992 $$ = NEW_BEGIN(0);
993 #endif
994 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
995 dispatch0(void_stmt));
996
997 }
998 | stmt_or_begin
999 {
1000 #if 0
1001 $$ = newline_node($1);
1002 #endif
1003 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
1004
1005 }
1006 | stmts terms stmt_or_begin
1007 {
1008 #if 0
1009 $$ = block_append($1, newline_node($3));
1010 #endif
1011 $$ = dispatch2(stmts_add, $1, $3);
1012
1013 }
1014 | error stmt
1015 {
1016 $$ = remove_begin($2);
1017 }
1018 ;
1019
1020 stmt_or_begin : stmt
1021 {
1022 $$ = $1;
1023 }
1024 | keyword_BEGIN
1025 {
1026 yyerror("BEGIN is permitted only at toplevel");
1027 #if 0
1028 /* local_push(0); */
1029 #endif
1030
1031 }
1032 '{' top_compstmt '}'
1033 {
1034 #if 0
1035 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
1036 $4);
1037 /* NEW_PREEXE($4)); */
1038 /* local_pop(); */
1039 $$ = NEW_BEGIN(0);
1040 #endif
1041 $$ = dispatch1(BEGIN, $4);
1042
1043 }
1044
1045 stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
1046 {
1047 #if 0
1048 $$ = NEW_ALIAS($2, $4);
1049 #endif
1050 $$ = dispatch2(alias, $2, $4);
1051
1052 }
1053 | keyword_alias tGVAR tGVAR
1054 {
1055 #if 0
1056 $$ = NEW_VALIAS($2, $3);
1057 #endif
1058 $$ = dispatch2(var_alias, $2, $3);
1059
1060 }
1061 | keyword_alias tGVAR tBACK_REF
1062 {
1063 #if 0
1064 char buf[2];
1065 buf[0] = '$';
1066 buf[1] = (char)$3->nd_nth;
1067 $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
1068 #endif
1069 $$ = dispatch2(var_alias, $2, $3);
1070
1071 }
1072 | keyword_alias tGVAR tNTH_REF
1073 {
1074 #if 0
1075 yyerror("can't make alias for the number variables");
1076 $$ = NEW_BEGIN(0);
1077 #endif
1078 $$ = dispatch2(var_alias, $2, $3);
1079 $$ = dispatch1(alias_error, $$);
1080
1081 }
1082 | keyword_undef undef_list
1083 {
1084 #if 0
1085 $$ = $2;
1086 #endif
1087 $$ = dispatch1(undef, $2);
1088
1089 }
1090 | stmt modifier_if expr_value
1091 {
1092 #if 0
1093 $$ = NEW_IF(cond($3), remove_begin($1), 0);
1094 fixpos($$, $3);
1095 #endif
1096 $$ = dispatch2(if_mod, $3, $1);
1097
1098 }
1099 | stmt modifier_unless expr_value
1100 {
1101 #if 0
1102 $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
1103 fixpos($$, $3);
1104 #endif
1105 $$ = dispatch2(unless_mod, $3, $1);
1106
1107 }
1108 | stmt modifier_while expr_value
1109 {
1110 #if 0
1111 if ($1 && nd_type($1) == NODE_BEGIN) {
1112 $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
1113 }
1114 else {
1115 $$ = NEW_WHILE(cond($3), $1, 1);
1116 }
1117 #endif
1118 $$ = dispatch2(while_mod, $3, $1);
1119
1120 }
1121 | stmt modifier_until expr_value
1122 {
1123 #if 0
1124 if ($1 && nd_type($1) == NODE_BEGIN) {
1125 $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
1126 }
1127 else {
1128 $$ = NEW_UNTIL(cond($3), $1, 1);
1129 }
1130 #endif
1131 $$ = dispatch2(until_mod, $3, $1);
1132
1133 }
1134 | stmt modifier_rescue stmt
1135 {
1136 #if 0
1137 NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
1138 $$ = NEW_RESCUE(remove_begin($1), resq, 0);
1139 #endif
1140 $$ = dispatch2(rescue_mod, $1, $3);
1141
1142 }
1143 | keyword_END '{' compstmt '}'
1144 {
1145 if (in_def || in_single) {
1146 rb_warn0("END in method; use at_exit");
1147 }
1148 #if 0
1149 $$ = NEW_POSTEXE(NEW_NODE(
1150 NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
1151 #endif
1152 $$ = dispatch1(END, $3);
1153
1154 }
1155 | command_asgn
1156 | mlhs '=' command_call
1157 {
1158 #if 0
1159 value_expr($3);
1160 $1->nd_value = $3;
1161 $$ = $1;
1162 #endif
1163 $$ = dispatch2(massign, $1, $3);
1164
1165 }
1166 | var_lhs tOP_ASGN command_call
1167 {
1168 value_expr($3);
1169 $$ = new_op_assign($1, $2, $3);
1170 }
1171 | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
1172 {
1173 #if 0
1174 NODE *args;
1175
1176 value_expr($6);
1177 if (!$3) $3 = NEW_ZARRAY();
1178 args = arg_concat($3, $6);
1179 if ($5 == tOROP) {
1180 $5 = 0;
1181 }
1182 else if ($5 == tANDOP) {
1183 $5 = 1;
1184 }
1185 $$ = NEW_OP_ASGN1($1, $5, args);
1186 fixpos($$, $1);
1187 #endif
1188 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1189 $$ = dispatch3(opassign, $$, $5, $6);
1190
1191 }
1192 | primary_value '.' tIDENTIFIER tOP_ASGN command_call
1193 {
1194 value_expr($5);
1195 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1196 }
1197 | primary_value '.' tCONSTANT tOP_ASGN command_call
1198 {
1199 value_expr($5);
1200 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1201 }
1202 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1203 {
1204 #if 0
1205 $$ = NEW_COLON2($1, $3);
1206 $$ = new_const_op_assign($$, $4, $5);
1207 #endif
1208 $$ = dispatch2(const_path_field, $1, $3);
1209 $$ = dispatch3(opassign, $$, $4, $5);
1210
1211 }
1212 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1213 {
1214 value_expr($5);
1215 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
1216 }
1217 | backref tOP_ASGN command_call
1218 {
1219 #if 0
1220 rb_backref_error($1);
1221 $$ = NEW_BEGIN(0);
1222 #endif
1223 $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1224 $$ = dispatch1(assign_error, $$);
1225
1226 }
1227 | lhs '=' mrhs
1228 {
1229 #if 0
1230 value_expr($3);
1231 $$ = node_assign($1, $3);
1232 #endif
1233 $$ = dispatch2(assign, $1, $3);
1234
1235 }
1236 | mlhs '=' arg_value
1237 {
1238 #if 0
1239 $1->nd_value = $3;
1240 $$ = $1;
1241 #endif
1242 $$ = dispatch2(massign, $1, $3);
1243
1244 }
1245 | mlhs '=' mrhs
1246 {
1247 #if 0
1248 $1->nd_value = $3;
1249 $$ = $1;
1250 #endif
1251 $$ = dispatch2(massign, $1, $3);
1252
1253 }
1254 | expr
1255 ;
1256
1257 command_asgn : lhs '=' command_call
1258 {
1259 #if 0
1260 value_expr($3);
1261 $$ = node_assign($1, $3);
1262 #endif
1263 $$ = dispatch2(assign, $1, $3);
1264
1265 }
1266 | lhs '=' command_asgn
1267 {
1268 #if 0
1269 value_expr($3);
1270 $$ = node_assign($1, $3);
1271 #endif
1272 $$ = dispatch2(assign, $1, $3);
1273
1274 }
1275 ;
1276
1277
1278 expr : command_call
1279 | expr keyword_and expr
1280 {
1281 #if 0
1282 $$ = logop(NODE_AND, $1, $3);
1283 #endif
1284 $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1285
1286 }
1287 | expr keyword_or expr
1288 {
1289 #if 0
1290 $$ = logop(NODE_OR, $1, $3);
1291 #endif
1292 $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1293
1294 }
1295 | keyword_not opt_nl expr
1296 {
1297 #if 0
1298 $$ = call_uni_op(cond($3), '!');
1299 #endif
1300 $$ = dispatch2(unary, ripper_intern("not"), $3);
1301
1302 }
1303 | '!' command_call
1304 {
1305 #if 0
1306 $$ = call_uni_op(cond($2), '!');
1307 #endif
1308 $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1309
1310 }
1311 | arg
1312 ;
1313
1314 expr_value : expr
1315 {
1316 #if 0
1317 value_expr($1);
1318 $$ = $1;
1319 if (!$$) $$ = NEW_NIL();
1320 #endif
1321 $$ = $1;
1322
1323 }
1324 ;
1325
1326 command_call : command
1327 | block_command
1328 ;
1329
1330 block_command : block_call
1331 | block_call dot_or_colon operation2 command_args
1332 {
1333 #if 0
1334 $$ = NEW_CALL($1, $3, $4);
1335 #endif
1336 $$ = dispatch3(call, $1, $2, $3);
1337 $$ = method_arg($$, $4);
1338
1339 }
1340 ;
1341
1342 cmd_brace_block : tLBRACE_ARG
1343 {
1344 $<vars>1 = dyna_push();
1345 #if 0
1346 $<num>$ = ruby_sourceline;
1347 #endif
1348
1349 }
1350 opt_block_param
1351 compstmt
1352 '}'
1353 {
1354 #if 0
1355 $$ = NEW_ITER($3,$4);
1356 nd_set_line($$, $<num>2);
1357 #endif
1358 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1359
1360 dyna_pop($<vars>1);
1361 }
1362 ;
1363
1364 fcall : operation
1365 {
1366 #if 0
1367 $$ = NEW_FCALL($1, 0);
1368 nd_set_line($$, tokline);
1369 #endif
1370
1371 }
1372 ;
1373
1374 command : fcall command_args %prec tLOWEST
1375 {
1376 #if 0
1377 $$ = $1;
1378 $$->nd_args = $2;
1379 #endif
1380 $$ = dispatch2(command, $1, $2);
1381
1382 }
1383 | fcall command_args cmd_brace_block
1384 {
1385 #if 0
1386 block_dup_check($2,$3);
1387 $1->nd_args = $2;
1388 $3->nd_iter = $1;
1389 $$ = $3;
1390 fixpos($$, $1);
1391 #endif
1392 $$ = dispatch2(command, $1, $2);
1393 $$ = method_add_block($$, $3);
1394
1395 }
1396 | primary_value '.' operation2 command_args %prec tLOWEST
1397 {
1398 #if 0
1399 $$ = NEW_CALL($1, $3, $4);
1400 fixpos($$, $1);
1401 #endif
1402 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1403
1404 }
1405 | primary_value '.' operation2 command_args cmd_brace_block
1406 {
1407 #if 0
1408 block_dup_check($4,$5);
1409 $5->nd_iter = NEW_CALL($1, $3, $4);
1410 $$ = $5;
1411 fixpos($$, $1);
1412 #endif
1413 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1414 $$ = method_add_block($$, $5);
1415
1416 }
1417 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1418 {
1419 #if 0
1420 $$ = NEW_CALL($1, $3, $4);
1421 fixpos($$, $1);
1422 #endif
1423 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1424
1425 }
1426 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1427 {
1428 #if 0
1429 block_dup_check($4,$5);
1430 $5->nd_iter = NEW_CALL($1, $3, $4);
1431 $$ = $5;
1432 fixpos($$, $1);
1433 #endif
1434 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1435 $$ = method_add_block($$, $5);
1436
1437 }
1438 | keyword_super command_args
1439 {
1440 #if 0
1441 $$ = NEW_SUPER($2);
1442 fixpos($$, $2);
1443 #endif
1444 $$ = dispatch1(super, $2);
1445
1446 }
1447 | keyword_yield command_args
1448 {
1449 #if 0
1450 $$ = new_yield($2);
1451 fixpos($$, $2);
1452 #endif
1453 $$ = dispatch1(yield, $2);
1454
1455 }
1456 | keyword_return call_args
1457 {
1458 #if 0
1459 $$ = NEW_RETURN(ret_args($2));
1460 #endif
1461 $$ = dispatch1(return, $2);
1462
1463 }
1464 | keyword_break call_args
1465 {
1466 #if 0
1467 $$ = NEW_BREAK(ret_args($2));
1468 #endif
1469 $$ = dispatch1(break, $2);
1470
1471 }
1472 | keyword_next call_args
1473 {
1474 #if 0
1475 $$ = NEW_NEXT(ret_args($2));
1476 #endif
1477 $$ = dispatch1(next, $2);
1478
1479 }
1480 ;
1481
1482 mlhs : mlhs_basic
1483 | tLPAREN mlhs_inner rparen
1484 {
1485 #if 0
1486 $$ = $2;
1487 #endif
1488 $$ = dispatch1(mlhs_paren, $2);
1489
1490 }
1491 ;
1492
1493 mlhs_inner : mlhs_basic
1494 | tLPAREN mlhs_inner rparen
1495 {
1496 #if 0
1497 $$ = NEW_MASGN(NEW_LIST($2), 0);
1498 #endif
1499 $$ = dispatch1(mlhs_paren, $2);
1500
1501 }
1502 ;
1503
1504 mlhs_basic : mlhs_head
1505 {
1506 #if 0
1507 $$ = NEW_MASGN($1, 0);
1508 #endif
1509 $$ = $1;
1510
1511 }
1512 | mlhs_head mlhs_item
1513 {
1514 #if 0
1515 $$ = NEW_MASGN(list_append($1,$2), 0);
1516 #endif
1517 $$ = mlhs_add($1, $2);
1518
1519 }
1520 | mlhs_head tSTAR mlhs_node
1521 {
1522 #if 0
1523 $$ = NEW_MASGN($1, $3);
1524 #endif
1525 $$ = mlhs_add_star($1, $3);
1526
1527 }
1528 | mlhs_head tSTAR mlhs_node ',' mlhs_post
1529 {
1530 #if 0
1531 $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
1532 #endif
1533 $1 = mlhs_add_star($1, $3);
1534 $$ = mlhs_add($1, $5);
1535
1536 }
1537 | mlhs_head tSTAR
1538 {
1539 #if 0
1540 $$ = NEW_MASGN($1, -1);
1541 #endif
1542 $$ = mlhs_add_star($1, Qnil);
1543
1544 }
1545 | mlhs_head tSTAR ',' mlhs_post
1546 {
1547 #if 0
1548 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
1549 #endif
1550 $1 = mlhs_add_star($1, Qnil);
1551 $$ = mlhs_add($1, $4);
1552
1553 }
1554 | tSTAR mlhs_node
1555 {
1556 #if 0
1557 $$ = NEW_MASGN(0, $2);
1558 #endif
1559 $$ = mlhs_add_star(mlhs_new(), $2);
1560
1561 }
1562 | tSTAR mlhs_node ',' mlhs_post
1563 {
1564 #if 0
1565 $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
1566 #endif
1567 $2 = mlhs_add_star(mlhs_new(), $2);
1568 $$ = mlhs_add($2, $4);
1569
1570 }
1571 | tSTAR
1572 {
1573 #if 0
1574 $$ = NEW_MASGN(0, -1);
1575 #endif
1576 $$ = mlhs_add_star(mlhs_new(), Qnil);
1577
1578 }
1579 | tSTAR ',' mlhs_post
1580 {
1581 #if 0
1582 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
1583 #endif
1584 $$ = mlhs_add_star(mlhs_new(), Qnil);
1585 $$ = mlhs_add($$, $3);
1586
1587 }
1588 ;
1589
1590 mlhs_item : mlhs_node
1591 | tLPAREN mlhs_inner rparen
1592 {
1593 #if 0
1594 $$ = $2;
1595 #endif
1596 $$ = dispatch1(mlhs_paren, $2);
1597
1598 }
1599 ;
1600
1601 mlhs_head : mlhs_item ','
1602 {
1603 #if 0
1604 $$ = NEW_LIST($1);
1605 #endif
1606 $$ = mlhs_add(mlhs_new(), $1);
1607
1608 }
1609 | mlhs_head mlhs_item ','
1610 {
1611 #if 0
1612 $$ = list_append($1, $2);
1613 #endif
1614 $$ = mlhs_add($1, $2);
1615
1616 }
1617 ;
1618
1619 mlhs_post : mlhs_item
1620 {
1621 #if 0
1622 $$ = NEW_LIST($1);
1623 #endif
1624 $$ = mlhs_add(mlhs_new(), $1);
1625
1626 }
1627 | mlhs_post ',' mlhs_item
1628 {
1629 #if 0
1630 $$ = list_append($1, $3);
1631 #endif
1632 $$ = mlhs_add($1, $3);
1633
1634 }
1635 ;
1636
1637 mlhs_node : user_variable
1638 {
1639 $$ = assignable($1, 0);
1640 }
1641 | keyword_variable
1642 {
1643 $$ = assignable($1, 0);
1644 }
1645 | primary_value '[' opt_call_args rbracket
1646 {
1647 #if 0
1648 $$ = aryset($1, $3);
1649 #endif
1650 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1651
1652 }
1653 | primary_value '.' tIDENTIFIER
1654 {
1655 #if 0
1656 $$ = attrset($1, $3);
1657 #endif
1658 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1659
1660 }
1661 | primary_value tCOLON2 tIDENTIFIER
1662 {
1663 #if 0
1664 $$ = attrset($1, $3);
1665 #endif
1666 $$ = dispatch2(const_path_field, $1, $3);
1667
1668 }
1669 | primary_value '.' tCONSTANT
1670 {
1671 #if 0
1672 $$ = attrset($1, $3);
1673 #endif
1674 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1675
1676 }
1677 | primary_value tCOLON2 tCONSTANT
1678 {
1679 #if 0
1680 if (in_def || in_single)
1681 yyerror("dynamic constant assignment");
1682 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1683 #endif
1684 if (in_def || in_single)
1685 yyerror("dynamic constant assignment");
1686 $$ = dispatch2(const_path_field, $1, $3);
1687
1688 }
1689 | tCOLON3 tCONSTANT
1690 {
1691 #if 0
1692 if (in_def || in_single)
1693 yyerror("dynamic constant assignment");
1694 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1695 #endif
1696 $$ = dispatch1(top_const_field, $2);
1697
1698 }
1699 | backref
1700 {
1701 #if 0
1702 rb_backref_error($1);
1703 $$ = NEW_BEGIN(0);
1704 #endif
1705 $$ = dispatch1(var_field, $1);
1706 $$ = dispatch1(assign_error, $$);
1707
1708 }
1709 ;
1710
1711 lhs : user_variable
1712 {
1713 $$ = assignable($1, 0);
1714 #if 0
1715 if (!$$) $$ = NEW_BEGIN(0);
1716 #endif
1717 $$ = dispatch1(var_field, $$);
1718
1719 }
1720 | keyword_variable
1721 {
1722 $$ = assignable($1, 0);
1723 #if 0
1724 if (!$$) $$ = NEW_BEGIN(0);
1725 #endif
1726 $$ = dispatch1(var_field, $$);
1727
1728 }
1729 | primary_value '[' opt_call_args rbracket
1730 {
1731 #if 0
1732 $$ = aryset($1, $3);
1733 #endif
1734 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1735
1736 }
1737 | primary_value '.' tIDENTIFIER
1738 {
1739 #if 0
1740 $$ = attrset($1, $3);
1741 #endif
1742 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1743
1744 }
1745 | primary_value tCOLON2 tIDENTIFIER
1746 {
1747 #if 0
1748 $$ = attrset($1, $3);
1749 #endif
1750 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1751
1752 }
1753 | primary_value '.' tCONSTANT
1754 {
1755 #if 0
1756 $$ = attrset($1, $3);
1757 #endif
1758 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1759
1760 }
1761 | primary_value tCOLON2 tCONSTANT
1762 {
1763 #if 0
1764 if (in_def || in_single)
1765 yyerror("dynamic constant assignment");
1766 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1767 #endif
1768 $$ = dispatch2(const_path_field, $1, $3);
1769 if (in_def || in_single) {
1770 $$ = dispatch1(assign_error, $$);
1771 }
1772
1773 }
1774 | tCOLON3 tCONSTANT
1775 {
1776 #if 0
1777 if (in_def || in_single)
1778 yyerror("dynamic constant assignment");
1779 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1780 #endif
1781 $$ = dispatch1(top_const_field, $2);
1782 if (in_def || in_single) {
1783 $$ = dispatch1(assign_error, $$);
1784 }
1785
1786 }
1787 | backref
1788 {
1789 #if 0
1790 rb_backref_error($1);
1791 $$ = NEW_BEGIN(0);
1792 #endif
1793 $$ = dispatch1(assign_error, $1);
1794
1795 }
1796 ;
1797
1798 cname : tIDENTIFIER
1799 {
1800 #if 0
1801 yyerror("class/module name must be CONSTANT");
1802 #endif
1803 $$ = dispatch1(class_name_error, $1);
1804
1805 }
1806 | tCONSTANT
1807 ;
1808
1809 cpath : tCOLON3 cname
1810 {
1811 #if 0
1812 $$ = NEW_COLON3($2);
1813 #endif
1814 $$ = dispatch1(top_const_ref, $2);
1815
1816 }
1817 | cname
1818 {
1819 #if 0
1820 $$ = NEW_COLON2(0, $$);
1821 #endif
1822 $$ = dispatch1(const_ref, $1);
1823
1824 }
1825 | primary_value tCOLON2 cname
1826 {
1827 #if 0
1828 $$ = NEW_COLON2($1, $3);
1829 #endif
1830 $$ = dispatch2(const_path_ref, $1, $3);
1831
1832 }
1833 ;
1834
1835 fname : tIDENTIFIER
1836 | tCONSTANT
1837 | tFID
1838 | op
1839 {
1840 lex_state = EXPR_ENDFN;
1841 $$ = $1;
1842 }
1843 | reswords
1844 {
1845 lex_state = EXPR_ENDFN;
1846 #if 0
1847 $$ = $<id>1;
1848 #endif
1849 $$ = $1;
1850
1851 }
1852 ;
1853
1854 fsym : fname
1855 | symbol
1856 ;
1857
1858 fitem : fsym
1859 {
1860 #if 0
1861 $$ = NEW_LIT(ID2SYM($1));
1862 #endif
1863 $$ = dispatch1(symbol_literal, $1);
1864
1865 }
1866 | dsym
1867 ;
1868
1869 undef_list : fitem
1870 {
1871 #if 0
1872 $$ = NEW_UNDEF($1);
1873 #endif
1874 $$ = rb_ary_new3(1, $1);
1875
1876 }
1877 | undef_list ',' {lex_state = EXPR_FNAME;} fitem
1878 {
1879 #if 0
1880 $$ = block_append($1, NEW_UNDEF($4));
1881 #endif
1882 rb_ary_push($1, $4);
1883
1884 }
1885 ;
1886
1887 op : '|' { ifndef_ripper($$ = '|'); }
1888 | '^' { ifndef_ripper($$ = '^'); }
1889 | '&' { ifndef_ripper($$ = '&'); }
1890 | tCMP { ifndef_ripper($$ = tCMP); }
1891 | tEQ { ifndef_ripper($$ = tEQ); }
1892 | tEQQ { ifndef_ripper($$ = tEQQ); }
1893 | tMATCH { ifndef_ripper($$ = tMATCH); }
1894 | tNMATCH { ifndef_ripper($$ = tNMATCH); }
1895 | '>' { ifndef_ripper($$ = '>'); }
1896 | tGEQ { ifndef_ripper($$ = tGEQ); }
1897 | '<' { ifndef_ripper($$ = '<'); }
1898 | tLEQ { ifndef_ripper($$ = tLEQ); }
1899 | tNEQ { ifndef_ripper($$ = tNEQ); }
1900 | tLSHFT { ifndef_ripper($$ = tLSHFT); }
1901 | tRSHFT { ifndef_ripper($$ = tRSHFT); }
1902 | '+' { ifndef_ripper($$ = '+'); }
1903 | '-' { ifndef_ripper($$ = '-'); }
1904 | '*' { ifndef_ripper($$ = '*'); }
1905 | tSTAR { ifndef_ripper($$ = '*'); }
1906 | '/' { ifndef_ripper($$ = '/'); }
1907 | '%' { ifndef_ripper($$ = '%'); }
1908 | tPOW { ifndef_ripper($$ = tPOW); }
1909 | tDSTAR { ifndef_ripper($$ = tDSTAR); }
1910 | '!' { ifndef_ripper($$ = '!'); }
1911 | '~' { ifndef_ripper($$ = '~'); }
1912 | tUPLUS { ifndef_ripper($$ = tUPLUS); }
1913 | tUMINUS { ifndef_ripper($$ = tUMINUS); }
1914 | tAREF { ifndef_ripper($$ = tAREF); }
1915 | tASET { ifndef_ripper($$ = tASET); }
1916 | '`' { ifndef_ripper($$ = '`'); }
1917 ;
1918
1919 reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1920 | keyword_BEGIN | keyword_END
1921 | keyword_alias | keyword_and | keyword_begin
1922 | keyword_break | keyword_case | keyword_class | keyword_def
1923 | keyword_defined | keyword_do | keyword_else | keyword_elsif
1924 | keyword_end | keyword_ensure | keyword_false
1925 | keyword_for | keyword_in | keyword_module | keyword_next
1926 | keyword_nil | keyword_not | keyword_or | keyword_redo
1927 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1928 | keyword_super | keyword_then | keyword_true | keyword_undef
1929 | keyword_when | keyword_yield | keyword_if | keyword_unless
1930 | keyword_while | keyword_until
1931 ;
1932
1933 arg : lhs '=' arg
1934 {
1935 #if 0
1936 value_expr($3);
1937 $$ = node_assign($1, $3);
1938 #endif
1939 $$ = dispatch2(assign, $1, $3);
1940
1941 }
1942 | lhs '=' arg modifier_rescue arg
1943 {
1944 #if 0
1945 value_expr($3);
1946 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1947 $$ = node_assign($1, $3);
1948 #endif
1949 $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1950
1951 }
1952 | var_lhs tOP_ASGN arg
1953 {
1954 value_expr($3);
1955 $$ = new_op_assign($1, $2, $3);
1956 }
1957 | var_lhs tOP_ASGN arg modifier_rescue arg
1958 {
1959 #if 0
1960 value_expr($3);
1961 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1962 #endif
1963 $3 = dispatch2(rescue_mod, $3, $5);
1964
1965 $$ = new_op_assign($1, $2, $3);
1966 }
1967 | primary_value '[' opt_call_args rbracket tOP_ASGN arg
1968 {
1969 #if 0
1970 NODE *args;
1971
1972 value_expr($6);
1973 if (!$3) $3 = NEW_ZARRAY();
1974 if (nd_type($3) == NODE_BLOCK_PASS) {
1975 args = NEW_ARGSCAT($3, $6);
1976 }
1977 else {
1978 args = arg_concat($3, $6);
1979 }
1980 if ($5 == tOROP) {
1981 $5 = 0;
1982 }
1983 else if ($5 == tANDOP) {
1984 $5 = 1;
1985 }
1986 $$ = NEW_OP_ASGN1($1, $5, args);
1987 fixpos($$, $1);
1988 #endif
1989 $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1990 $$ = dispatch3(opassign, $1, $5, $6);
1991
1992 }
1993 | primary_value '.' tIDENTIFIER tOP_ASGN arg
1994 {
1995 value_expr($5);
1996 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1997 }
1998 | primary_value '.' tCONSTANT tOP_ASGN arg
1999 {
2000 value_expr($5);
2001 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
2002 }
2003 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
2004 {
2005 value_expr($5);
2006 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
2007 }
2008 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
2009 {
2010 #if 0
2011 $$ = NEW_COLON2($1, $3);
2012 $$ = new_const_op_assign($$, $4, $5);
2013 #endif
2014 $$ = dispatch2(const_path_field, $1, $3);
2015 $$ = dispatch3(opassign, $$, $4, $5);
2016
2017 }
2018 | tCOLON3 tCONSTANT tOP_ASGN arg
2019 {
2020 #if 0
2021 $$ = NEW_COLON3($2);
2022 $$ = new_const_op_assign($$, $3, $4);
2023 #endif
2024 $$ = dispatch1(top_const_field, $2);
2025 $$ = dispatch3(opassign, $$, $3, $4);
2026
2027 }
2028 | backref tOP_ASGN arg
2029 {
2030 #if 0
2031 rb_backref_error($1);
2032 $$ = NEW_BEGIN(0);
2033 #endif
2034 $$ = dispatch1(var_field, $1);
2035 $$ = dispatch3(opassign, $$, $2, $3);
2036 $$ = dispatch1(assign_error, $$);
2037
2038 }
2039 | arg tDOT2 arg
2040 {
2041 #if 0
2042 value_expr($1);
2043 value_expr($3);
2044 $$ = NEW_DOT2($1, $3);
2045 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2046 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2047 deferred_nodes = list_append(deferred_nodes, $$);
2048 }
2049 #endif
2050 $$ = dispatch2(dot2, $1, $3);
2051
2052 }
2053 | arg tDOT3 arg
2054 {
2055 #if 0
2056 value_expr($1);
2057 value_expr($3);
2058 $$ = NEW_DOT3($1, $3);
2059 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2060 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2061 deferred_nodes = list_append(deferred_nodes, $$);
2062 }
2063 #endif
2064 $$ = dispatch2(dot3, $1, $3);
2065
2066 }
2067 | arg '+' arg
2068 {
2069 #if 0
2070 $$ = call_bin_op($1, '+', $3);
2071 #endif
2072 $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2073
2074 }
2075 | arg '-' arg
2076 {
2077 #if 0
2078 $$ = call_bin_op($1, '-', $3);
2079 #endif
2080 $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2081
2082 }
2083 | arg '*' arg
2084 {
2085 #if 0
2086 $$ = call_bin_op($1, '*', $3);
2087 #endif
2088 $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2089
2090 }
2091 | arg '/' arg
2092 {
2093 #if 0
2094 $$ = call_bin_op($1, '/', $3);
2095 #endif
2096 $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2097
2098 }
2099 | arg '%' arg
2100 {
2101 #if 0
2102 $$ = call_bin_op($1, '%', $3);
2103 #endif
2104 $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2105
2106 }
2107 | arg tPOW arg
2108 {
2109 #if 0
2110 $$ = call_bin_op($1, tPOW, $3);
2111 #endif
2112 $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2113
2114 }
2115 | tUMINUS_NUM tINTEGER tPOW arg
2116 {
2117 #if 0
2118 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2119 #endif
2120 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2121 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2122
2123 }
2124 | tUMINUS_NUM tFLOAT tPOW arg
2125 {
2126 #if 0
2127 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2128 #endif
2129 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2130 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2131
2132 }
2133 | tUPLUS arg
2134 {
2135 #if 0
2136 $$ = call_uni_op($2, tUPLUS);
2137 #endif
2138 $$ = dispatch2(unary, ripper_intern("+@"), $2);
2139
2140 }
2141 | tUMINUS arg
2142 {
2143 #if 0
2144 $$ = call_uni_op($2, tUMINUS);
2145 #endif
2146 $$ = dispatch2(unary, ripper_intern("-@"), $2);
2147
2148 }
2149 | arg '|' arg
2150 {
2151 #if 0
2152 $$ = call_bin_op($1, '|', $3);
2153 #endif
2154 $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2155
2156 }
2157 | arg '^' arg
2158 {
2159 #if 0
2160 $$ = call_bin_op($1, '^', $3);
2161 #endif
2162 $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2163
2164 }
2165 | arg '&' arg
2166 {
2167 #if 0
2168 $$ = call_bin_op($1, '&', $3);
2169 #endif
2170 $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2171
2172 }
2173 | arg tCMP arg
2174 {
2175 #if 0
2176 $$ = call_bin_op($1, tCMP, $3);
2177 #endif
2178 $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2179
2180 }
2181 | arg '>' arg
2182 {
2183 #if 0
2184 $$ = call_bin_op($1, '>', $3);
2185 #endif
2186 $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2187
2188 }
2189 | arg tGEQ arg
2190 {
2191 #if 0
2192 $$ = call_bin_op($1, tGEQ, $3);
2193 #endif
2194 $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2195
2196 }
2197 | arg '<' arg
2198 {
2199 #if 0
2200 $$ = call_bin_op($1, '<', $3);
2201 #endif
2202 $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2203
2204 }
2205 | arg tLEQ arg
2206 {
2207 #if 0
2208 $$ = call_bin_op($1, tLEQ, $3);
2209 #endif
2210 $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2211
2212 }
2213 | arg tEQ arg
2214 {
2215 #if 0
2216 $$ = call_bin_op($1, tEQ, $3);
2217 #endif
2218 $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2219
2220 }
2221 | arg tEQQ arg
2222 {
2223 #if 0
2224 $$ = call_bin_op($1, tEQQ, $3);
2225 #endif
2226 $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2227
2228 }
2229 | arg tNEQ arg
2230 {
2231 #if 0
2232 $$ = call_bin_op($1, tNEQ, $3);
2233 #endif
2234 $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2235
2236 }
2237 | arg tMATCH arg
2238 {
2239 #if 0
2240 $$ = match_op($1, $3);
2241 if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
2242 $$ = reg_named_capture_assign($1->nd_lit, $$);
2243 }
2244 #endif
2245 $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2246
2247 }
2248 | arg tNMATCH arg
2249 {
2250 #if 0
2251 $$ = call_bin_op($1, tNMATCH, $3);
2252 #endif
2253 $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2254
2255 }
2256 | '!' arg
2257 {
2258 #if 0
2259 $$ = call_uni_op(cond($2), '!');
2260 #endif
2261 $$ = dispatch2(unary, ID2SYM('!'), $2);
2262
2263 }
2264 | '~' arg
2265 {
2266 #if 0
2267 $$ = call_uni_op($2, '~');
2268 #endif
2269 $$ = dispatch2(unary, ID2SYM('~'), $2);
2270
2271 }
2272 | arg tLSHFT arg
2273 {
2274 #if 0
2275 $$ = call_bin_op($1, tLSHFT, $3);
2276 #endif
2277 $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2278
2279 }
2280 | arg tRSHFT arg
2281 {
2282 #if 0
2283 $$ = call_bin_op($1, tRSHFT, $3);
2284 #endif
2285 $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2286
2287 }
2288 | arg tANDOP arg
2289 {
2290 #if 0
2291 $$ = logop(NODE_AND, $1, $3);
2292 #endif
2293 $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2294
2295 }
2296 | arg tOROP arg
2297 {
2298 #if 0
2299 $$ = logop(NODE_OR, $1, $3);
2300 #endif
2301 $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2302
2303 }
2304 | keyword_defined opt_nl {in_defined = 1;} arg
2305 {
2306 #if 0
2307 in_defined = 0;
2308 $$ = NEW_DEFINED($4);
2309 #endif
2310 in_defined = 0;
2311 $$ = dispatch1(defined, $4);
2312
2313 }
2314 | arg '?' arg opt_nl ':' arg
2315 {
2316 #if 0
2317 value_expr($1);
2318 $$ = NEW_IF(cond($1), $3, $6);
2319 fixpos($$, $1);
2320 #endif
2321 $$ = dispatch3(ifop, $1, $3, $6);
2322
2323 }
2324 | primary
2325 {
2326 $$ = $1;
2327 }
2328 ;
2329
2330 arg_value : arg
2331 {
2332 #if 0
2333 value_expr($1);
2334 $$ = $1;
2335 if (!$$) $$ = NEW_NIL();
2336 #endif
2337 $$ = $1;
2338
2339 }
2340 ;
2341
2342 aref_args : none
2343 | args trailer
2344 {
2345 $$ = $1;
2346 }
2347 | args ',' assocs trailer
2348 {
2349 #if 0
2350 $$ = arg_append($1, NEW_HASH($3));
2351 #endif
2352 $$ = arg_add_assocs($1, $3);
2353
2354 }
2355 | assocs trailer
2356 {
2357 #if 0
2358 $$ = NEW_LIST(NEW_HASH($1));
2359 #endif
2360 $$ = arg_add_assocs(arg_new(), $1);
2361
2362 }
2363 ;
2364
2365 paren_args : '(' opt_call_args rparen
2366 {
2367 #if 0
2368 $$ = $2;
2369 #endif
2370 $$ = dispatch1(arg_paren, escape_Qundef($2));
2371
2372 }
2373 ;
2374
2375 opt_paren_args : none
2376 | paren_args
2377 ;
2378
2379 opt_call_args : none
2380 | call_args
2381 | args ','
2382 {
2383 $$ = $1;
2384 }
2385 | args ',' assocs ','
2386 {
2387 #if 0
2388 $$ = arg_append($1, NEW_HASH($3));
2389 #endif
2390 $$ = arg_add_assocs($1, $3);
2391
2392 }
2393 | assocs ','
2394 {
2395 #if 0
2396 $$ = NEW_LIST(NEW_HASH($1));
2397 #endif
2398 $$ = arg_add_assocs(arg_new(), $1);
2399
2400 }
2401 ;
2402
2403 call_args : command
2404 {
2405 #if 0
2406 value_expr($1);
2407 $$ = NEW_LIST($1);
2408 #endif
2409 $$ = arg_add(arg_new(), $1);
2410
2411 }
2412 | args opt_block_arg
2413 {
2414 #if 0
2415 $$ = arg_blk_pass($1, $2);
2416 #endif
2417 $$ = arg_add_optblock($1, $2);
2418
2419 }
2420 | assocs opt_block_arg
2421 {
2422 #if 0
2423 $$ = NEW_LIST(NEW_HASH($1));
2424 $$ = arg_blk_pass($$, $2);
2425 #endif
2426 $$ = arg_add_assocs(arg_new(), $1);
2427 $$ = arg_add_optblock($$, $2);
2428
2429 }
2430 | args ',' assocs opt_block_arg
2431 {
2432 #if 0
2433 $$ = arg_append($1, NEW_HASH($3));
2434 $$ = arg_blk_pass($$, $4);
2435 #endif
2436 $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2437
2438 }
2439 | block_arg
2440 /*
2441 */
2442 {
2443 $$ = arg_add_block(arg_new(), $1);
2444 }
2445
2446 ;
2447
2448 command_args : {
2449 $<val>$ = cmdarg_stack;
2450 CMDARG_PUSH(1);
2451 }
2452 call_args
2453 {
2454 /* CMDARG_POP() */
2455 cmdarg_stack = $<val>1;
2456 $$ = $2;
2457 }
2458 ;
2459
2460 block_arg : tAMPER arg_value
2461 {
2462 #if 0
2463 $$ = NEW_BLOCK_PASS($2);
2464 #endif
2465 $$ = $2;
2466
2467 }
2468 ;
2469
2470 opt_block_arg : ',' block_arg
2471 {
2472 $$ = $2;
2473 }
2474 | none
2475 {
2476 $$ = 0;
2477 }
2478 ;
2479
2480 args : arg_value
2481 {
2482 #if 0
2483 $$ = NEW_LIST($1);
2484 #endif
2485 $$ = arg_add(arg_new(), $1);
2486
2487 }
2488 | tSTAR arg_value
2489 {
2490 #if 0
2491 $$ = NEW_SPLAT($2);
2492 #endif
2493 $$ = arg_add_star(arg_new(), $2);
2494
2495 }
2496 | args ',' arg_value
2497 {
2498 #if 0
2499 NODE *n1;
2500 if ((n1 = splat_array($1)) != 0) {
2501 $$ = list_append(n1, $3);
2502 }
2503 else {
2504 $$ = arg_append($1, $3);
2505 }
2506 #endif
2507 $$ = arg_add($1, $3);
2508
2509 }
2510 | args ',' tSTAR arg_value
2511 {
2512 #if 0
2513 NODE *n1;
2514 if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
2515 $$ = list_concat(n1, $4);
2516 }
2517 else {
2518 $$ = arg_concat($1, $4);
2519 }
2520 #endif
2521 $$ = arg_add_star($1, $4);
2522
2523 }
2524 ;
2525
2526 mrhs : args ',' arg_value
2527 {
2528 #if 0
2529 NODE *n1;
2530 if ((n1 = splat_array($1)) != 0) {
2531 $$ = list_append(n1, $3);
2532 }
2533 else {
2534 $$ = arg_append($1, $3);
2535 }
2536 #endif
2537 $$ = mrhs_add(args2mrhs($1), $3);
2538
2539 }
2540 | args ',' tSTAR arg_value
2541 {
2542 #if 0
2543 NODE *n1;
2544 if (nd_type($4) == NODE_ARRAY &&
2545 (n1 = splat_array($1)) != 0) {
2546 $$ = list_concat(n1, $4);
2547 }
2548 else {
2549 $$ = arg_concat($1, $4);
2550 }
2551 #endif
2552 $$ = mrhs_add_star(args2mrhs($1), $4);
2553
2554 }
2555 | tSTAR arg_value
2556 {
2557 #if 0
2558 $$ = NEW_SPLAT($2);
2559 #endif
2560 $$ = mrhs_add_star(mrhs_new(), $2);
2561
2562 }
2563 ;
2564
2565 primary : literal
2566 | strings
2567 | xstring
2568 | regexp
2569 | words
2570 | qwords
2571 | symbols
2572 | qsymbols
2573 | var_ref
2574 | backref
2575 | tFID
2576 {
2577 #if 0
2578 $$ = NEW_FCALL($1, 0);
2579 #endif
2580 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2581
2582 }
2583 | k_begin
2584 {
2585 $<val>1 = cmdarg_stack;
2586 cmdarg_stack = 0;
2587 #if 0
2588 $<num>$ = ruby_sourceline;
2589 #endif
2590
2591 }
2592 bodystmt
2593 k_end
2594 {
2595 cmdarg_stack = $<val>1;
2596 #if 0
2597 if ($3 == NULL) {
2598 $$ = NEW_NIL();
2599 }
2600 else {
2601 if (nd_type($3) == NODE_RESCUE ||
2602 nd_type($3) == NODE_ENSURE)
2603 nd_set_line($3, $<num>2);
2604 $$ = NEW_BEGIN($3);
2605 }
2606 nd_set_line($$, $<num>2);
2607 #endif
2608 $$ = dispatch1(begin, $3);
2609
2610 }
2611 | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
2612 {
2613 #if 0
2614 $$ = 0;
2615 #endif
2616 $$ = dispatch1(paren, 0);
2617
2618 }
2619 | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
2620 {
2621 #if 0
2622 $$ = $2;
2623 #endif
2624 $$ = dispatch1(paren, $2);
2625
2626 }
2627 | tLPAREN compstmt ')'
2628 {
2629 #if 0
2630 $$ = $2;
2631 #endif
2632 $$ = dispatch1(paren, $2);
2633
2634 }
2635 | primary_value tCOLON2 tCONSTANT
2636 {
2637 #if 0
2638 $$ = NEW_COLON2($1, $3);
2639 #endif
2640 $$ = dispatch2(const_path_ref, $1, $3);
2641
2642 }
2643 | tCOLON3 tCONSTANT
2644 {
2645 #if 0
2646 $$ = NEW_COLON3($2);
2647 #endif
2648 $$ = dispatch1(top_const_ref, $2);
2649
2650 }
2651 | tLBRACK aref_args ']'
2652 {
2653 #if 0
2654 if ($2 == 0) {
2655 $$ = NEW_ZARRAY(); /* zero length array*/
2656 }
2657 else {
2658 $$ = $2;
2659 }
2660 #endif
2661 $$ = dispatch1(array, escape_Qundef($2));
2662
2663 }
2664 | tLBRACE assoc_list '}'
2665 {
2666 #if 0
2667 $$ = NEW_HASH($2);
2668 #endif
2669 $$ = dispatch1(hash, escape_Qundef($2));
2670
2671 }
2672 | keyword_return
2673 {
2674 #if 0
2675 $$ = NEW_RETURN(0);
2676 #endif
2677 $$ = dispatch0(return0);
2678
2679 }
2680 | keyword_yield '(' call_args rparen
2681 {
2682 #if 0
2683 $$ = new_yield($3);
2684 #endif
2685 $$ = dispatch1(yield, dispatch1(paren, $3));
2686
2687 }
2688 | keyword_yield '(' rparen
2689 {
2690 #if 0
2691 $$ = NEW_YIELD(0);
2692 #endif
2693 $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2694
2695 }
2696 | keyword_yield
2697 {
2698 #if 0
2699 $$ = NEW_YIELD(0);
2700 #endif
2701 $$ = dispatch0(yield0);
2702
2703 }
2704 | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
2705 {
2706 #if 0
2707 in_defined = 0;
2708 $$ = NEW_DEFINED($5);
2709 #endif
2710 in_defined = 0;
2711 $$ = dispatch1(defined, $5);
2712
2713 }
2714 | keyword_not '(' expr rparen
2715 {
2716 #if 0
2717 $$ = call_uni_op(cond($3), '!');
2718 #endif
2719 $$ = dispatch2(unary, ripper_intern("not"), $3);
2720
2721 }
2722 | keyword_not '(' rparen
2723 {
2724 #if 0
2725 $$ = call_uni_op(cond(NEW_NIL()), '!');
2726 #endif
2727 $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2728
2729 }
2730 | fcall brace_block
2731 {
2732 #if 0
2733 $2->nd_iter = $1;
2734 $$ = $2;
2735 #endif
2736 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2737 $$ = method_add_block($$, $2);
2738
2739 }
2740 | method_call
2741 | method_call brace_block
2742 {
2743 #if 0
2744 block_dup_check($1->nd_args, $2);
2745 $2->nd_iter = $1;
2746 $$ = $2;
2747 #endif
2748 $$ = method_add_block($1, $2);
2749
2750 }
2751 | tLAMBDA lambda
2752 {
2753 $$ = $2;
2754 }
2755 | k_if expr_value then
2756 compstmt
2757 if_tail
2758 k_end
2759 {
2760 #if 0
2761 $$ = NEW_IF(cond($2), $4, $5);
2762 fixpos($$, $2);
2763 #endif
2764 $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2765
2766 }
2767 | k_unless expr_value then
2768 compstmt
2769 opt_else
2770 k_end
2771 {
2772 #if 0
2773 $$ = NEW_UNLESS(cond($2), $4, $5);
2774 fixpos($$, $2);
2775 #endif
2776 $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2777
2778 }
2779 | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
2780 compstmt
2781 k_end
2782 {
2783 #if 0
2784 $$ = NEW_WHILE(cond($3), $6, 1);
2785 fixpos($$, $3);
2786 #endif
2787 $$ = dispatch2(while, $3, $6);
2788
2789 }
2790 | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
2791 compstmt
2792 k_end
2793 {
2794 #if 0
2795 $$ = NEW_UNTIL(cond($3), $6, 1);
2796 fixpos($$, $3);
2797 #endif
2798 $$ = dispatch2(until, $3, $6);
2799
2800 }
2801 | k_case expr_value opt_terms
2802 case_body
2803 k_end
2804 {
2805 #if 0
2806 $$ = NEW_CASE($2, $4);
2807 fixpos($$, $2);
2808 #endif
2809 $$ = dispatch2(case, $2, $4);
2810
2811 }
2812 | k_case opt_terms case_body k_end
2813 {
2814 #if 0
2815 $$ = NEW_CASE(0, $3);
2816 #endif
2817 $$ = dispatch2(case, Qnil, $3);
2818
2819 }
2820 | k_for for_var keyword_in
2821 {COND_PUSH(1);}
2822 expr_value do
2823 {COND_POP();}
2824 compstmt
2825 k_end
2826 {
2827 #if 0
2828 /*
2829 * for a, b, c in e
2830 * #=>
2831 * e.each{|*x| a, b, c = x
2832 *
2833 * for a in e
2834 * #=>
2835 * e.each{|x| a, = x}
2836 */
2837 ID id = internal_id();
2838 ID *tbl = ALLOC_N(ID, 2);
2839 NODE *m = NEW_ARGS_AUX(0, 0);
2840 NODE *args, *scope;
2841
2842 if (nd_type($2) == NODE_MASGN) {
2843 /* if args.length == 1 && args[0].kind_of?(Array)
2844 * args = args[0]
2845 * end
2846 */
2847 NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
2848 NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
2849 m->nd_next = block_append(
2850 NEW_IF(
2851 NEW_NODE(NODE_AND,
2852 NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
2853 idEq, one),
2854 NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
2855 rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
2856 0),
2857 NEW_DASGN_CURR(id,
2858 NEW_CALL(NEW_DVAR(id), idAREF, zero)),
2859 0),
2860 node_assign($2, NEW_DVAR(id)));
2861
2862 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2863 }
2864 else {
2865 if (nd_type($2) == NODE_LASGN ||
2866 nd_type($2) == NODE_DASGN ||
2867 nd_type($2) == NODE_DASGN_CURR) {
2868 $2->nd_value = NEW_DVAR(id);
2869 m->nd_plen = 1;
2870 m->nd_next = $2;
2871 args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
2872 }
2873 else {
2874 m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
2875 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2876 }
2877 }
2878 scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
2879 tbl[0] = 1; tbl[1] = id;
2880 $$ = NEW_FOR(0, $5, scope);
2881 fixpos($$, $2);
2882 #endif
2883 $$ = dispatch3(for, $2, $5, $8);
2884
2885 }
2886 | k_class cpath superclass
2887 {
2888 if (in_def || in_single)
2889 yyerror("class definition in method body");
2890 local_push(0);
2891 #if 0
2892 $<num>$ = ruby_sourceline;
2893 #endif
2894
2895 }
2896 bodystmt
2897 k_end
2898 {
2899 #if 0
2900 $$ = NEW_CLASS($2, $5, $3);
2901 nd_set_line($$, $<num>4);
2902 #endif
2903 $$ = dispatch3(class, $2, $3, $5);
2904
2905 local_pop();
2906 }
2907 | k_class tLSHFT expr
2908 {
2909 $<num>$ = in_def;
2910 in_def = 0;
2911 }
2912 term
2913 {
2914 $<num>$ = in_single;
2915 in_single = 0;
2916 local_push(0);
2917 }
2918 bodystmt
2919 k_end
2920 {
2921 #if 0
2922 $$ = NEW_SCLASS($3, $7);
2923 fixpos($$, $3);
2924 #endif
2925 $$ = dispatch2(sclass, $3, $7);
2926
2927 local_pop();
2928 in_def = $<num>4;
2929 in_single = $<num>6;
2930 }
2931 | k_module cpath
2932 {
2933 if (in_def || in_single)
2934 yyerror("module definition in method body");
2935 local_push(0);
2936 #if 0
2937 $<num>$ = ruby_sourceline;
2938 #endif
2939
2940 }
2941 bodystmt
2942 k_end
2943 {
2944 #if 0
2945 $$ = NEW_MODULE($2, $4);
2946 nd_set_line($$, $<num>3);
2947 #endif
2948 $$ = dispatch2(module, $2, $4);
2949
2950 local_pop();
2951 }
2952 | k_def fname
2953 {
2954 $<id>$ = cur_mid;
2955 cur_mid = $2;
2956 in_def++;
2957 local_push(0);
2958 }
2959 f_arglist
2960 bodystmt
2961 k_end
2962 {
2963 #if 0
2964 NODE *body = remove_begin($5);
2965 reduce_nodes(&body);
2966 $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
2967 nd_set_line($$, $<num>1);
2968 #endif
2969 $$ = dispatch3(def, $2, $4, $5);
2970
2971 local_pop();
2972 in_def--;
2973 cur_mid = $<id>3;
2974 }
2975 | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
2976 {
2977 in_single++;
2978 lex_state = EXPR_ENDFN; /* force for args */
2979 local_push(0);
2980 }
2981 f_arglist
2982 bodystmt
2983 k_end
2984 {
2985 #if 0
2986 NODE *body = remove_begin($8);
2987 reduce_nodes(&body);
2988 $$ = NEW_DEFS($2, $5, $7, body);
2989 nd_set_line($$, $<num>1);
2990 #endif
2991 $$ = dispatch5(defs, $2, $3, $5, $7, $8);
2992
2993 local_pop();
2994 in_single--;
2995 }
2996 | keyword_break
2997 {
2998 #if 0
2999 $$ = NEW_BREAK(0);
3000 #endif
3001 $$ = dispatch1(break, arg_new());
3002
3003 }
3004 | keyword_next
3005 {
3006 #if 0
3007 $$ = NEW_NEXT(0);
3008 #endif
3009 $$ = dispatch1(next, arg_new());
3010
3011 }
3012 | keyword_redo
3013 {
3014 #if 0
3015 $$ = NEW_REDO();
3016 #endif
3017 $$ = dispatch0(redo);
3018
3019 }
3020 | keyword_retry
3021 {
3022 #if 0
3023 $$ = NEW_RETRY();
3024 #endif
3025 $$ = dispatch0(retry);
3026
3027 }
3028 ;
3029
3030 primary_value : primary
3031 {
3032 #if 0
3033 value_expr($1);
3034 $$ = $1;
3035 if (!$$) $$ = NEW_NIL();
3036 #endif
3037 $$ = $1;
3038
3039 }
3040 ;
3041
3042 k_begin : keyword_begin
3043 {
3044 token_info_push("begin");
3045 }
3046 ;
3047
3048 k_if : keyword_if
3049 {
3050 token_info_push("if");
3051 }
3052 ;
3053
3054 k_unless : keyword_unless
3055 {
3056 token_info_push("unless");
3057 }
3058 ;
3059
3060 k_while : keyword_while
3061 {
3062 token_info_push("while");
3063 }
3064 ;
3065
3066 k_until : keyword_until
3067 {
3068 token_info_push("until");
3069 }
3070 ;
3071
3072 k_case : keyword_case
3073 {
3074 token_info_push("case");
3075 }
3076 ;
3077
3078 k_for : keyword_for
3079 {
3080 token_info_push("for");
3081 }
3082 ;
3083
3084 k_class : keyword_class
3085 {
3086 token_info_push("class");
3087 }
3088 ;
3089
3090 k_module : keyword_module
3091 {
3092 token_info_push("module");
3093 }
3094 ;
3095
3096 k_def : keyword_def
3097 {
3098 token_info_push("def");
3099 #if 0
3100 $<num>$ = ruby_sourceline;
3101 #endif
3102
3103 }
3104 ;
3105
3106 k_end : keyword_end
3107 {
3108 token_info_pop("end");
3109 }
3110 ;
3111
3112 then : term
3113 /*
3114 */
3115 { $$ = Qnil; }
3116
3117 | keyword_then
3118 | term keyword_then
3119 /*
3120 */
3121 { $$ = $2; }
3122
3123 ;
3124
3125 do : term
3126 /*
3127 */
3128 { $$ = Qnil; }
3129
3130 | keyword_do_cond
3131 ;
3132
3133 if_tail : opt_else
3134 | keyword_elsif expr_value then
3135 compstmt
3136 if_tail
3137 {
3138 #if 0
3139 $$ = NEW_IF(cond($2), $4, $5);
3140 fixpos($$, $2);
3141 #endif
3142 $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
3143
3144 }
3145 ;
3146
3147 opt_else : none
3148 | keyword_else compstmt
3149 {
3150 #if 0
3151 $$ = $2;
3152 #endif
3153 $$ = dispatch1(else, $2);
3154
3155 }
3156 ;
3157
3158 for_var : lhs
3159 | mlhs
3160 ;
3161
3162 f_marg : f_norm_arg
3163 {
3164 $$ = assignable($1, 0);
3165 #if 0
3166 #endif
3167 $$ = dispatch1(mlhs_paren, $$);
3168
3169 }
3170 | tLPAREN f_margs rparen
3171 {
3172 #if 0
3173 $$ = $2;
3174 #endif
3175 $$ = dispatch1(mlhs_paren, $2);
3176
3177 }
3178 ;
3179
3180 f_marg_list : f_marg
3181 {
3182 #if 0
3183 $$ = NEW_LIST($1);
3184 #endif
3185 $$ = mlhs_add(mlhs_new(), $1);
3186
3187 }
3188 | f_marg_list ',' f_marg
3189 {
3190 #if 0
3191 $$ = list_append($1, $3);
3192 #endif
3193 $$ = mlhs_add($1, $3);
3194
3195 }
3196 ;
3197
3198 f_margs : f_marg_list
3199 {
3200 #if 0
3201 $$ = NEW_MASGN($1, 0);
3202 #endif
3203 $$ = $1;
3204
3205 }
3206 | f_marg_list ',' tSTAR f_norm_arg
3207 {
3208 $$ = assignable($4, 0);
3209 #if 0
3210 $$ = NEW_MASGN($1, $$);
3211 #endif
3212 $$ = mlhs_add_star($1, $$);
3213
3214 }
3215 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
3216 {
3217 $$ = assignable($4, 0);
3218 #if 0
3219 $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
3220 #endif
3221 $$ = mlhs_add_star($1, $$);
3222
3223 }
3224 | f_marg_list ',' tSTAR
3225 {
3226 #if 0
3227 $$ = NEW_MASGN($1, -1);
3228 #endif
3229 $$ = mlhs_add_star($1, Qnil);
3230
3231 }
3232 | f_marg_list ',' tSTAR ',' f_marg_list
3233 {
3234 #if 0
3235 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
3236 #endif
3237 $$ = mlhs_add_star($1, $5);
3238
3239 }
3240 | tSTAR f_norm_arg
3241 {
3242 $$ = assignable($2, 0);
3243 #if 0
3244 $$ = NEW_MASGN(0, $$);
3245 #endif
3246 $$ = mlhs_add_star(mlhs_new(), $$);
3247
3248 }
3249 | tSTAR f_norm_arg ',' f_marg_list
3250 {
3251 $$ = assignable($2, 0);
3252 #if 0
3253 $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
3254 #endif
3255 #if 0
3256 TODO: Check me
3257 #endif
3258 $$ = mlhs_add_star($$, $4);
3259
3260 }
3261 | tSTAR
3262 {
3263 #if 0
3264 $$ = NEW_MASGN(0, -1);
3265 #endif
3266 $$ = mlhs_add_star(mlhs_new(), Qnil);
3267
3268 }
3269 | tSTAR ',' f_marg_list
3270 {
3271 #if 0
3272 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
3273 #endif
3274 $$ = mlhs_add_star(mlhs_new(), Qnil);
3275
3276 }
3277 ;
3278
3279
3280 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
3281 {
3282 $$ = new_args_tail($1, $3, $4);
3283 }
3284 | f_block_kwarg opt_f_block_arg
3285 {
3286 $$ = new_args_tail($1, Qnone, $2);
3287 }
3288 | f_kwrest opt_f_block_arg
3289 {
3290 $$ = new_args_tail(Qnone, $1, $2);
3291 }
3292 | f_block_arg
3293 {
3294 $$ = new_args_tail(Qnone, Qnone, $1);
3295 }
3296 ;
3297
3298 opt_block_args_tail : ',' block_args_tail
3299 {
3300 $$ = $2;
3301 }
3302 | /* none */
3303 {
3304 $$ = new_args_tail(Qnone, Qnone, Qnone);
3305 }
3306 ;
3307
3308 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
3309 {
3310 $$ = new_args($1, $3, $5, Qnone, $6);
3311 }
3312 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3313 {
3314 $$ = new_args($1, $3, $5, $7, $8);
3315 }
3316 | f_arg ',' f_block_optarg opt_block_args_tail
3317 {
3318 $$ = new_args($1, $3, Qnone, Qnone, $4);
3319 }
3320 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
3321 {
3322 $$ = new_args($1, $3, Qnone, $5, $6);
3323 }
3324 | f_arg ',' f_rest_arg opt_block_args_tail
3325 {
3326 $$ = new_args($1, Qnone, $3, Qnone, $4);
3327 }
3328 | f_arg ','
3329 {
3330 $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
3331 #if 0
3332 #endif
3333 dispatch1(excessed_comma, $$);
3334
3335 }
3336 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
3337 {
3338 $$ = new_args($1, Qnone, $3, $5, $6);
3339 }
3340 | f_arg opt_block_args_tail
3341 {
3342 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
3343 }
3344 | f_block_optarg ',' f_rest_arg opt_block_args_tail
3345 {
3346 $$ = new_args(Qnone, $1, $3, Qnone, $4);
3347 }
3348 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3349 {
3350 $$ = new_args(Qnone, $1, $3, $5, $6);
3351 }
3352 | f_block_optarg opt_block_args_tail
3353 {
3354 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
3355 }
3356 | f_block_optarg ',' f_arg opt_block_args_tail
3357 {
3358 $$ = new_args(Qnone, $1, Qnone, $3, $4);
3359 }
3360 | f_rest_arg opt_block_args_tail
3361 {
3362 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
3363 }
3364 | f_rest_arg ',' f_arg opt_block_args_tail
3365 {
3366 $$ = new_args(Qnone, Qnone, $1, $3, $4);
3367 }
3368 | block_args_tail
3369 {
3370 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
3371 }
3372 ;
3373
3374 opt_block_param : none
3375 | block_param_def
3376 {
3377 command_start = TRUE;
3378 }
3379 ;
3380
3381 block_param_def : '|' opt_bv_decl '|'
3382 {
3383 #if 0
3384 $$ = 0;
3385 #endif
3386 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3387 escape_Qundef($2));
3388
3389 }
3390 | tOROP
3391 {
3392 #if 0
3393 $$ = 0;
3394 #endif
3395 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3396 Qnil);
3397
3398 }
3399 | '|' block_param opt_bv_decl '|'
3400 {
3401 #if 0
3402 $$ = $2;
3403 #endif
3404 $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3405
3406 }
3407 ;
3408
3409
3410 opt_bv_decl : opt_nl
3411 {
3412 $$ = 0;
3413 }
3414 | opt_nl ';' bv_decls opt_nl
3415 {
3416 #if 0
3417 $$ = 0;
3418 #endif
3419 $$ = $3;
3420
3421 }
3422 ;
3423
3424 bv_decls : bvar
3425 /*
3426 */
3427 {
3428 $$ = rb_ary_new3(1, $1);
3429 }
3430
3431 | bv_decls ',' bvar
3432 /*
3433 */
3434 {
3435 rb_ary_push($1, $3);
3436 }
3437
3438 ;
3439
3440 bvar : tIDENTIFIER
3441 {
3442 new_bv(get_id($1));
3443 #if 0
3444 #endif
3445 $$ = get_value($1);
3446
3447 }
3448 | f_bad_arg
3449 {
3450 $$ = 0;
3451 }
3452 ;
3453
3454 lambda : {
3455 $<vars>$ = dyna_push();
3456 }
3457 {
3458 $<num>$ = lpar_beg;
3459 lpar_beg = ++paren_nest;
3460 }
3461 f_larglist
3462 lambda_body
3463 {
3464 lpar_beg = $<num>2;
3465 #if 0
3466 $$ = NEW_LAMBDA($3, $4);
3467 #endif
3468 $$ = dispatch2(lambda, $3, $4);
3469
3470 dyna_pop($<vars>1);
3471 }
3472 ;
3473
3474 f_larglist : '(' f_args opt_bv_decl ')'
3475 {
3476 #if 0
3477 $$ = $2;
3478 #endif
3479 $$ = dispatch1(paren, $2);
3480
3481 }
3482 | f_args
3483 {
3484 #if 0
3485 $$ = $1;
3486 #endif
3487 $$ = $1;
3488
3489 }
3490 ;
3491
3492 lambda_body : tLAMBEG compstmt '}'
3493 {
3494 $$ = $2;
3495 }
3496 | keyword_do_LAMBDA compstmt keyword_end
3497 {
3498 $$ = $2;
3499 }
3500 ;
3501
3502 do_block : keyword_do_block
3503 {
3504 $<vars>1 = dyna_push();
3505 #if 0
3506 $<num>$ = ruby_sourceline;
3507 #endif
3508 }
3509 opt_block_param
3510 compstmt
3511 keyword_end
3512 {
3513 #if 0
3514 $$ = NEW_ITER($3,$4);
3515 nd_set_line($$, $<num>2);
3516 #endif
3517 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3518
3519 dyna_pop($<vars>1);
3520 }
3521 ;
3522
3523 block_call : command do_block
3524 {
3525 #if 0
3526 if (nd_type($1) == NODE_YIELD) {
3527 compile_error(PARSER_ARG "block given to yield");
3528 }
3529 else {
3530 block_dup_check($1->nd_args, $2);
3531 }
3532 $2->nd_iter = $1;
3533 $$ = $2;
3534 fixpos($$, $1);
3535 #endif
3536 $$ = method_add_block($1, $2);
3537
3538 }
3539 | block_call dot_or_colon operation2 opt_paren_args
3540 {
3541 #if 0
3542 $$ = NEW_CALL($1, $3, $4);
3543 #endif
3544 $$ = dispatch3(call, $1, $2, $3);
3545 $$ = method_optarg($$, $4);
3546
3547 }
3548 | block_call dot_or_colon operation2 opt_paren_args brace_block
3549 {
3550 #if 0
3551 block_dup_check($4, $5);
3552 $5->nd_iter = NEW_CALL($1, $3, $4);
3553 $$ = $5;
3554 fixpos($$, $1);
3555 #endif
3556 $$ = dispatch4(command_call, $1, $2, $3, $4);
3557 $$ = method_add_block($$, $5);
3558
3559 }
3560 | block_call dot_or_colon operation2 command_args do_block
3561 {
3562 #if 0
3563 block_dup_check($4, $5);
3564 $5->nd_iter = NEW_CALL($1, $3, $4);
3565 $$ = $5;
3566 fixpos($$, $1);
3567 #endif
3568 $$ = dispatch4(command_call, $1, $2, $3, $4);
3569 $$ = method_add_block($$, $5);
3570
3571 }
3572 ;
3573
3574 method_call : fcall paren_args
3575 {
3576 #if 0
3577 $$ = $1;
3578 $$->nd_args = $2;
3579 #endif
3580 $$ = method_arg(dispatch1(fcall, $1), $2);
3581
3582 }
3583 | primary_value '.' operation2
3584 {
3585 #if 0
3586 $<num>$ = ruby_sourceline;
3587 #endif
3588 }
3589 opt_paren_args
3590 {
3591 #if 0
3592 $$ = NEW_CALL($1, $3, $5);
3593 nd_set_line($$, $<num>4);
3594 #endif
3595 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3596 $$ = method_optarg($$, $5);
3597
3598 }
3599 | primary_value tCOLON2 operation2
3600 {
3601 #if 0
3602 $<num>$ = ruby_sourceline;
3603 #endif
3604 }
3605 paren_args
3606 {
3607 #if 0
3608 $$ = NEW_CALL($1, $3, $5);
3609 nd_set_line($$, $<num>4);
3610 #endif
3611 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3612 $$ = method_optarg($$, $5);
3613
3614 }
3615 | primary_value tCOLON2 operation3
3616 {
3617 #if 0
3618 $$ = NEW_CALL($1, $3, 0);
3619 #endif
3620 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3621
3622 }
3623 | primary_value '.'
3624 {
3625 #if 0
3626 $<num>$ = ruby_sourceline;
3627 #endif
3628 }
3629 paren_args
3630 {
3631 #if 0
3632 $$ = NEW_CALL($1, rb_intern("call"), $4);
3633 nd_set_line($$, $<num>3);
3634 #endif
3635 $$ = dispatch3(call, $1, ripper_id2sym('.'),
3636 ripper_intern("call"));
3637 $$ = method_optarg($$, $4);
3638
3639 }
3640 | primary_value tCOLON2
3641 {
3642 #if 0
3643 $<num>$ = ruby_sourceline;
3644 #endif
3645 }
3646 paren_args
3647 {
3648 #if 0
3649 $$ = NEW_CALL($1, rb_intern("call"), $4);
3650 nd_set_line($$, $<num>3);
3651 #endif
3652 $$ = dispatch3(call, $1, ripper_intern("::"),
3653 ripper_intern("call"));
3654 $$ = method_optarg($$, $4);
3655
3656 }
3657 | keyword_super paren_args
3658 {
3659 #if 0
3660 $$ = NEW_SUPER($2);
3661 #endif
3662 $$ = dispatch1(super, $2);
3663
3664 }
3665 | keyword_super
3666 {
3667 #if 0
3668 $$ = NEW_ZSUPER();
3669 #endif
3670 $$ = dispatch0(zsuper);
3671
3672 }
3673 | primary_value '[' opt_call_args rbracket
3674 {
3675 #if 0
3676 if ($1 && nd_type($1) == NODE_SELF)
3677 $$ = NEW_FCALL(tAREF, $3);
3678 else
3679 $$ = NEW_CALL($1, tAREF, $3);
3680 fixpos($$, $1);
3681 #endif
3682 $$ = dispatch2(aref, $1, escape_Qundef($3));
3683
3684 }
3685 ;
3686
3687 brace_block : '{'
3688 {
3689 $<vars>1 = dyna_push();
3690 #if 0
3691 $<num>$ = ruby_sourceline;
3692 #endif
3693
3694 }
3695 opt_block_param
3696 compstmt '}'
3697 {
3698 #if 0
3699 $$ = NEW_ITER($3,$4);
3700 nd_set_line($$, $<num>2);
3701 #endif
3702 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3703
3704 dyna_pop($<vars>1);
3705 }
3706 | keyword_do
3707 {
3708 $<vars>1 = dyna_push();
3709 #if 0
3710 $<num>$ = ruby_sourceline;
3711 #endif
3712
3713 }
3714 opt_block_param
3715 compstmt keyword_end
3716 {
3717 #if 0
3718 $$ = NEW_ITER($3,$4);
3719 nd_set_line($$, $<num>2);
3720 #endif
3721 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3722
3723 dyna_pop($<vars>1);
3724 }
3725 ;
3726
3727 case_body : keyword_when args then
3728 compstmt
3729 cases
3730 {
3731 #if 0
3732 $$ = NEW_WHEN($2, $4, $5);
3733 #endif
3734 $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3735
3736 }
3737 ;
3738
3739 cases : opt_else
3740 | case_body
3741 ;
3742
3743 opt_rescue : keyword_rescue exc_list exc_var then
3744 compstmt
3745 opt_rescue
3746 {
3747 #if 0
3748 if ($3) {
3749 $3 = node_assign($3, NEW_ERRINFO());
3750 $5 = block_append($3, $5);
3751 }
3752 $$ = NEW_RESBODY($2, $5, $6);
3753 fixpos($$, $2?$2:$5);
3754 #endif
3755 $$ = dispatch4(rescue,
3756 escape_Qundef($2),
3757 escape_Qundef($3),
3758 escape_Qundef($5),
3759 escape_Qundef($6));
3760
3761 }
3762 | none
3763 ;
3764
3765 exc_list : arg_value
3766 {
3767 #if 0
3768 $$ = NEW_LIST($1);
3769 #endif
3770 $$ = rb_ary_new3(1, $1);
3771
3772 }
3773 | mrhs
3774 {
3775 #if 0
3776 if (!($$ = splat_array($1))) $$ = $1;
3777 #endif
3778 $$ = $1;
3779
3780 }
3781 | none
3782 ;
3783
3784 exc_var : tASSOC lhs
3785 {
3786 $$ = $2;
3787 }
3788 | none
3789 ;
3790
3791 opt_ensure : keyword_ensure compstmt
3792 {
3793 #if 0
3794 $$ = $2;
3795 #endif
3796 $$ = dispatch1(ensure, $2);
3797
3798 }
3799 | none
3800 ;
3801
3802 literal : numeric
3803 | symbol
3804 {
3805 #if 0
3806 $$ = NEW_LIT(ID2SYM($1));
3807 #endif
3808 $$ = dispatch1(symbol_literal, $1);
3809
3810 }
3811 | dsym
3812 ;
3813
3814 strings : string
3815 {
3816 #if 0
3817 NODE *node = $1;
3818 if (!node) {
3819 node = NEW_STR(STR_NEW0());
3820 }
3821 else {
3822 node = evstr2dstr(node);
3823 }
3824 $$ = node;
3825 #endif
3826 $$ = $1;
3827
3828 }
3829 ;
3830
3831 string : tCHAR
3832 | string1
3833 | string string1
3834 {
3835 #if 0
3836 $$ = literal_concat($1, $2);
3837 #endif
3838 $$ = dispatch2(string_concat, $1, $2);
3839
3840 }
3841 ;
3842
3843 string1 : tSTRING_BEG string_contents tSTRING_END
3844 {
3845 #if 0
3846 $$ = $2;
3847 #endif
3848 $$ = dispatch1(string_literal, $2);
3849
3850 }
3851 ;
3852
3853 xstring : tXSTRING_BEG xstring_contents tSTRING_END
3854 {
3855 #if 0
3856 NODE *node = $2;
3857 if (!node) {
3858 node = NEW_XSTR(STR_NEW0());
3859 }
3860 else {
3861 switch (nd_type(node)) {
3862 case NODE_STR:
3863 nd_set_type(node, NODE_XSTR);
3864 break;
3865 case NODE_DSTR:
3866 nd_set_type(node, NODE_DXSTR);
3867 break;
3868 default:
3869 node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
3870 break;
3871 }
3872 }
3873 $$ = node;
3874 #endif
3875 $$ = dispatch1(xstring_literal, $2);
3876
3877 }
3878 ;
3879
3880 regexp : tREGEXP_BEG regexp_contents tREGEXP_END
3881 {
3882 #if 0
3883 int options = $3;
3884 NODE *node = $2;
3885 NODE *list, *prev;
3886 if (!node) {
3887 node = NEW_LIT(reg_compile(STR_NEW0(), options));
3888 }
3889 else switch (nd_type(node)) {
3890 case NODE_STR:
3891 {
3892 VALUE src = node->nd_lit;
3893 nd_set_type(node, NODE_LIT);
3894 node->nd_lit = reg_compile(src, options);
3895 }
3896 break;
3897 default:
3898 node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
3899 case NODE_DSTR:
3900 if (options & RE_OPTION_ONCE) {
3901 nd_set_type(node, NODE_DREGX_ONCE);
3902 }
3903 else {
3904 nd_set_type(node, NODE_DREGX);
3905 }
3906 node->nd_cflag = options & RE_OPTION_MASK;
3907 if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
3908 for (list = (prev = node)->nd_next; list; list = list->nd_next) {
3909 if (nd_type(list->nd_head) == NODE_STR) {
3910 VALUE tail = list->nd_head->nd_lit;
3911 if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
3912 VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
3913 if (!literal_concat0(parser, lit, tail)) {
3914 node = 0;
3915 break;
3916 }
3917 rb_str_resize(tail, 0);
3918 prev->nd_next = list->nd_next;
3919 rb_gc_force_recycle((VALUE)list->nd_head);
3920 rb_gc_force_recycle((VALUE)list);
3921 list = prev;
3922 }
3923 else {
3924 prev = list;
3925 }
3926 }
3927 else {
3928 prev = 0;
3929 }
3930 }
3931 if (!node->nd_next) {
3932 VALUE src = node->nd_lit;
3933 nd_set_type(node, NODE_LIT);
3934 node->nd_lit = reg_compile(src, options);
3935 }
3936 break;
3937 }
3938 $$ = node;
3939 #endif
3940 $$ = dispatch2(regexp_literal, $2, $3);
3941
3942 }
3943 ;
3944
3945 words : tWORDS_BEG ' ' tSTRING_END
3946 {
3947 #if 0
3948 $$ = NEW_ZARRAY();
3949 #endif
3950 $$ = dispatch0(words_new);
3951 $$ = dispatch1(array, $$);
3952
3953 }
3954 | tWORDS_BEG word_list tSTRING_END
3955 {
3956 #if 0
3957 $$ = $2;
3958 #endif
3959 $$ = dispatch1(array, $2);
3960
3961 }
3962 ;
3963
3964 word_list : /* none */
3965 {
3966 #if 0
3967 $$ = 0;
3968 #endif
3969 $$ = dispatch0(words_new);
3970
3971 }
3972 | word_list word ' '
3973 {
3974 #if 0
3975 $$ = list_append($1, evstr2dstr($2));
3976 #endif
3977 $$ = dispatch2(words_add, $1, $2);
3978
3979 }
3980 ;
3981
3982 word : string_content
3983 /*
3984 */
3985 {
3986 $$ = dispatch0(word_new);
3987 $$ = dispatch2(word_add, $$, $1);
3988 }
3989
3990 | word string_content
3991 {
3992 #if 0
3993 $$ = literal_concat($1, $2);
3994 #endif
3995 $$ = dispatch2(word_add, $1, $2);
3996
3997 }
3998 ;
3999
4000 symbols : tSYMBOLS_BEG ' ' tSTRING_END
4001 {
4002 #if 0
4003 $$ = NEW_ZARRAY();
4004 #endif
4005 $$ = dispatch0(symbols_new);
4006 $$ = dispatch1(array, $$);
4007
4008 }
4009 | tSYMBOLS_BEG symbol_list tSTRING_END
4010 {
4011 #if 0
4012 $$ = $2;
4013 #endif
4014 $$ = dispatch1(array, $2);
4015
4016 }
4017 ;
4018
4019 symbol_list : /* none */
4020 {
4021 #if 0
4022 $$ = 0;
4023 #endif
4024 $$ = dispatch0(symbols_new);
4025
4026 }
4027 | symbol_list word ' '
4028 {
4029 #if 0
4030 $2 = evstr2dstr($2);
4031 nd_set_type($2, NODE_DSYM);
4032 $$ = list_append($1, $2);
4033 #endif
4034 $$ = dispatch2(symbols_add, $1, $2);
4035
4036 }
4037 ;
4038
4039 qwords : tQWORDS_BEG ' ' tSTRING_END
4040 {
4041 #if 0
4042 $$ = NEW_ZARRAY();
4043 #endif
4044 $$ = dispatch0(qwords_new);
4045 $$ = dispatch1(array, $$);
4046
4047 }
4048 | tQWORDS_BEG qword_list tSTRING_END
4049 {
4050 #if 0
4051 $$ = $2;
4052 #endif
4053 $$ = dispatch1(array, $2);
4054
4055 }
4056 ;
4057
4058 qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
4059 {
4060 #if 0
4061 $$ = NEW_ZARRAY();
4062 #endif
4063 $$ = dispatch0(qsymbols_new);
4064 $$ = dispatch1(array, $$);
4065
4066 }
4067 | tQSYMBOLS_BEG qsym_list tSTRING_END
4068 {
4069 #if 0
4070 $$ = $2;
4071 #endif
4072 $$ = dispatch1(array, $2);
4073
4074 }
4075 ;
4076
4077 qword_list : /* none */
4078 {
4079 #if 0
4080 $$ = 0;
4081 #endif
4082 $$ = dispatch0(qwords_new);
4083
4084 }
4085 | qword_list tSTRING_CONTENT ' '
4086 {
4087 #if 0
4088 $$ = list_append($1, $2);
4089 #endif
4090 $$ = dispatch2(qwords_add, $1, $2);
4091
4092 }
4093 ;
4094
4095 qsym_list : /* none */
4096 {
4097 #if 0
4098 $$ = 0;
4099 #endif
4100 $$ = dispatch0(qsymbols_new);
4101
4102 }
4103 | qsym_list tSTRING_CONTENT ' '
4104 {
4105 #if 0
4106 VALUE lit;
4107 lit = $2->nd_lit;
4108 $2->nd_lit = ID2SYM(rb_intern_str(lit));
4109 nd_set_type($2, NODE_LIT);
4110 $$ = list_append($1, $2);
4111 #endif
4112 $$ = dispatch2(qsymbols_add, $1, $2);
4113
4114 }
4115 ;
4116
4117 string_contents : /* none */
4118 {
4119 #if 0
4120 $$ = 0;
4121 #endif
4122 $$ = dispatch0(string_content);
4123
4124 }
4125 | string_contents string_content
4126 {
4127 #if 0
4128 $$ = literal_concat($1, $2);
4129 #endif
4130 $$ = dispatch2(string_add, $1, $2);
4131
4132 }
4133 ;
4134
4135 xstring_contents: /* none */
4136 {
4137 #if 0
4138 $$ = 0;
4139 #endif
4140 $$ = dispatch0(xstring_new);
4141
4142 }
4143 | xstring_contents string_content
4144 {
4145 #if 0
4146 $$ = literal_concat($1, $2);
4147 #endif
4148 $$ = dispatch2(xstring_add, $1, $2);
4149
4150 }
4151 ;
4152
4153 regexp_contents: /* none */
4154 {
4155 #if 0
4156 $$ = 0;
4157 #endif
4158 $$ = dispatch0(regexp_new);
4159
4160 }
4161 | regexp_contents string_content
4162 {
4163 #if 0
4164 NODE *head = $1, *tail = $2;
4165 if (!head) {
4166 $$ = tail;
4167 }
4168 else if (!tail) {
4169 $$ = head;
4170 }
4171 else {
4172 switch (nd_type(head)) {
4173 case NODE_STR:
4174 nd_set_type(head, NODE_DSTR);
4175 break;
4176 case NODE_DSTR:
4177 break;
4178 default:
4179 head = list_append(NEW_DSTR(Qnil), head);
4180 break;
4181 }
4182 $$ = list_append(head, tail);
4183 }
4184 #endif
4185 $$ = dispatch2(regexp_add, $1, $2);
4186
4187 }
4188 ;
4189
4190 string_content : tSTRING_CONTENT
4191 | tSTRING_DVAR
4192 {
4193 $<node>$ = lex_strterm;
4194 lex_strterm = 0;
4195 lex_state = EXPR_BEG;
4196 }
4197 string_dvar
4198 {
4199 #if 0
4200 lex_strterm = $<node>2;
4201 $$ = NEW_EVSTR($3);
4202 #endif
4203 lex_strterm = $<node>2;
4204 $$ = dispatch1(string_dvar, $3);
4205
4206 }
4207 | tSTRING_DBEG
4208 {
4209 $<val>1 = cond_stack;
4210 $<val>$ = cmdarg_stack;
4211 cond_stack = 0;
4212 cmdarg_stack = 0;
4213 }
4214 {
4215 $<node>$ = lex_strterm;
4216 lex_strterm = 0;
4217 lex_state = EXPR_BEG;
4218 }
4219 {
4220 $<num>$ = brace_nest;
4221 brace_nest = 0;
4222 }
4223 compstmt tSTRING_DEND
4224 {
4225 cond_stack = $<val>1;
4226 cmdarg_stack = $<val>2;
4227 lex_strterm = $<node>3;
4228 brace_nest = $<num>4;
4229 #if 0
4230 if ($5) $5->flags &= ~NODE_FL_NEWLINE;
4231 $$ = new_evstr($5);
4232 #endif
4233 $$ = dispatch1(string_embexpr, $5);
4234
4235 }
4236 ;
4237
4238 string_dvar : tGVAR
4239 {
4240 #if 0
4241 $$ = NEW_GVAR($1);
4242 #endif
4243 $$ = dispatch1(var_ref, $1);
4244
4245 }
4246 | tIVAR
4247 {
4248 #if 0
4249 $$ = NEW_IVAR($1);
4250 #endif
4251 $$ = dispatch1(var_ref, $1);
4252
4253 }
4254 | tCVAR
4255 {
4256 #if 0
4257 $$ = NEW_CVAR($1);
4258 #endif
4259 $$ = dispatch1(var_ref, $1);
4260
4261 }
4262 | backref
4263 ;
4264
4265 symbol : tSYMBEG sym
4266 {
4267 lex_state = EXPR_END;
4268 #if 0
4269 $$ = $2;
4270 #endif
4271 $$ = dispatch1(symbol, $2);
4272
4273 }
4274 ;
4275
4276 sym : fname
4277 | tIVAR
4278 | tGVAR
4279 | tCVAR
4280 ;
4281
4282 dsym : tSYMBEG xstring_contents tSTRING_END
4283 {
4284 lex_state = EXPR_END;
4285 #if 0
4286 $$ = dsym_node($2);
4287 #endif
4288 $$ = dispatch1(dyna_symbol, $2);
4289
4290 }
4291 ;
4292
4293 numeric : tINTEGER
4294 | tFLOAT
4295 | tUMINUS_NUM tINTEGER %prec tLOWEST
4296 {
4297 #if 0
4298 $$ = negate_lit($2);
4299 #endif
4300 $$ = dispatch2(unary, ripper_intern("-@"), $2);
4301
4302 }
4303 | tUMINUS_NUM tFLOAT %prec tLOWEST
4304 {
4305 #if 0
4306 $$ = negate_lit($2);
4307 #endif
4308 $$ = dispatch2(unary, ripper_intern("-@"), $2);
4309
4310 }
4311 ;
4312
4313 user_variable : tIDENTIFIER
4314 | tIVAR
4315 | tGVAR
4316 | tCONSTANT
4317 | tCVAR
4318 ;
4319
4320 keyword_variable: keyword_nil {ifndef_ripper($$ = keyword_nil);}
4321 | keyword_self {ifndef_ripper($$ = keyword_self);}
4322 | keyword_true {ifndef_ripper($$ = keyword_true);}
4323 | keyword_false {ifndef_ripper($$ = keyword_false);}
4324 | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
4325 | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
4326 | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);}
4327 ;
4328
4329 var_ref : user_variable
4330 {
4331 #if 0
4332 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4333 #endif
4334 if (id_is_var(get_id($1))) {
4335 $$ = dispatch1(var_ref, $1);
4336 }
4337 else {
4338 $$ = dispatch1(vcall, $1);
4339 }
4340
4341 }
4342 | keyword_variable
4343 {
4344 #if 0
4345 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4346 #endif
4347 $$ = dispatch1(var_ref, $1);
4348
4349 }
4350 ;
4351
4352 var_lhs : user_variable
4353 {
4354 $$ = assignable($1, 0);
4355 #if 0
4356 #endif
4357 $$ = dispatch1(var_field, $$);
4358
4359 }
4360 | keyword_variable
4361 {
4362 $$ = assignable($1, 0);
4363 #if 0
4364 #endif
4365 $$ = dispatch1(var_field, $$);
4366
4367 }
4368 ;
4369
4370 backref : tNTH_REF
4371 | tBACK_REF
4372 ;
4373
4374 superclass : term
4375 {
4376 #if 0
4377 $$ = 0;
4378 #endif
4379 $$ = Qnil;
4380
4381 }
4382 | '<'
4383 {
4384 lex_state = EXPR_BEG;
4385 command_start = TRUE;
4386 }
4387 expr_value term
4388 {
4389 $$ = $3;
4390 }
4391 | error term
4392 {
4393 #if 0
4394 yyerrok;
4395 $$ = 0;
4396 #endif
4397 yyerrok;
4398 $$ = Qnil;
4399
4400 }
4401 ;
4402
4403 f_arglist : '(' f_args rparen
4404 {
4405 #if 0
4406 $$ = $2;
4407 #endif
4408 $$ = dispatch1(paren, $2);
4409
4410 lex_state = EXPR_BEG;
4411 command_start = TRUE;
4412 }
4413 | f_args term
4414 {
4415 $$ = $1;
4416 lex_state = EXPR_BEG;
4417 command_start = TRUE;
4418 }
4419 ;
4420
4421 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
4422 {
4423 $$ = new_args_tail($1, $3, $4);
4424 }
4425 | f_kwarg opt_f_block_arg
4426 {
4427 $$ = new_args_tail($1, Qnone, $2);
4428 }
4429 | f_kwrest opt_f_block_arg
4430 {
4431 $$ = new_args_tail(Qnone, $1, $2);
4432 }
4433 | f_block_arg
4434 {
4435 $$ = new_args_tail(Qnone, Qnone, $1);
4436 }
4437 ;
4438
4439 opt_args_tail : ',' args_tail
4440 {
4441 $$ = $2;
4442 }
4443 | /* none */
4444 {
4445 $$ = new_args_tail(Qnone, Qnone, Qnone);
4446 }
4447 ;
4448
4449 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
4450 {
4451 $$ = new_args($1, $3, $5, Qnone, $6);
4452 }
4453 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4454 {
4455 $$ = new_args($1, $3, $5, $7, $8);
4456 }
4457 | f_arg ',' f_optarg opt_args_tail
4458 {
4459 $$ = new_args($1, $3, Qnone, Qnone, $4);
4460 }
4461 | f_arg ',' f_optarg ',' f_arg opt_args_tail
4462 {
4463 $$ = new_args($1, $3, Qnone, $5, $6);
4464 }
4465 | f_arg ',' f_rest_arg opt_args_tail
4466 {
4467 $$ = new_args($1, Qnone, $3, Qnone, $4);
4468 }
4469 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
4470 {
4471 $$ = new_args($1, Qnone, $3, $5, $6);
4472 }
4473 | f_arg opt_args_tail
4474 {
4475 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
4476 }
4477 | f_optarg ',' f_rest_arg opt_args_tail
4478 {
4479 $$ = new_args(Qnone, $1, $3, Qnone, $4);
4480 }
4481 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4482 {
4483 $$ = new_args(Qnone, $1, $3, $5, $6);
4484 }
4485 | f_optarg opt_args_tail
4486 {
4487 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
4488 }
4489 | f_optarg ',' f_arg opt_args_tail
4490 {
4491 $$ = new_args(Qnone, $1, Qnone, $3, $4);
4492 }
4493 | f_rest_arg opt_args_tail
4494 {
4495 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
4496 }
4497 | f_rest_arg ',' f_arg opt_args_tail
4498 {
4499 $$ = new_args(Qnone, Qnone, $1, $3, $4);
4500 }
4501 | args_tail
4502 {
4503 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
4504 }
4505 | /* none */
4506 {
4507 $$ = new_args_tail(Qnone, Qnone, Qnone);
4508 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
4509 }
4510 ;
4511
4512 f_bad_arg : tCONSTANT
4513 {
4514 #if 0
4515 yyerror("formal argument cannot be a constant");
4516 $$ = 0;
4517 #endif
4518 $$ = dispatch1(param_error, $1);
4519
4520 }
4521 | tIVAR
4522 {
4523 #if 0
4524 yyerror("formal argument cannot be an instance variable");
4525 $$ = 0;
4526 #endif
4527 $$ = dispatch1(param_error, $1);
4528
4529 }
4530 | tGVAR
4531 {
4532 #if 0
4533 yyerror("formal argument cannot be a global variable");
4534 $$ = 0;
4535 #endif
4536 $$ = dispatch1(param_error, $1);
4537
4538 }
4539 | tCVAR
4540 {
4541 #if 0
4542 yyerror("formal argument cannot be a class variable");
4543 $$ = 0;
4544 #endif
4545 $$ = dispatch1(param_error, $1);
4546
4547 }
4548 ;
4549
4550 f_norm_arg : f_bad_arg
4551 | tIDENTIFIER
4552 {
4553 formal_argument(get_id($1));
4554 $$ = $1;
4555 }
4556 ;
4557
4558 f_arg_item : f_norm_arg
4559 {
4560 arg_var(get_id($1));
4561 #if 0
4562 $$ = NEW_ARGS_AUX($1, 1);
4563 #endif
4564 $$ = get_value($1);
4565
4566 }
4567 | tLPAREN f_margs rparen
4568 {
4569 ID tid = internal_id();
4570 arg_var(tid);
4571 #if 0
4572 if (dyna_in_block()) {
4573 $2->nd_value = NEW_DVAR(tid);
4574 }
4575 else {
4576 $2->nd_value = NEW_LVAR(tid);
4577 }
4578 $$ = NEW_ARGS_AUX(tid, 1);
4579 $$->nd_next = $2;
4580 #endif
4581 $$ = dispatch1(mlhs_paren, $2);
4582
4583 }
4584 ;
4585
4586 f_arg : f_arg_item
4587 /*
4588 */
4589 {
4590 $$ = rb_ary_new3(1, $1);
4591 }
4592
4593 | f_arg ',' f_arg_item
4594 {
4595 #if 0
4596 $$ = $1;
4597 $$->nd_plen++;
4598 $$->nd_next = block_append($$->nd_next, $3->nd_next);
4599 rb_gc_force_recycle((VALUE)$3);
4600 #endif
4601 $$ = rb_ary_push($1, $3);
4602
4603 }
4604 ;
4605
4606 f_kw : tLABEL arg_value
4607 {
4608 arg_var(formal_argument(get_id($1)));
4609 $$ = assignable($1, $2);
4610 #if 0
4611 $$ = NEW_KW_ARG(0, $$);
4612 #endif
4613 $$ = rb_assoc_new($$, $2);
4614
4615 }
4616 ;
4617
4618 f_block_kw : tLABEL primary_value
4619 {
4620 arg_var(formal_argument(get_id($1)));
4621 $$ = assignable($1, $2);
4622 #if 0
4623 $$ = NEW_KW_ARG(0, $$);
4624 #endif
4625 $$ = rb_assoc_new($$, $2);
4626
4627 }
4628 ;
4629
4630 f_block_kwarg : f_block_kw
4631 {
4632 #if 0
4633 $$ = $1;
4634 #endif
4635 $$ = rb_ary_new3(1, $1);
4636
4637 }
4638 | f_block_kwarg ',' f_block_kw
4639 {
4640 #if 0
4641 NODE *kws = $1;
4642
4643 while (kws->nd_next) {
4644 kws = kws->nd_next;
4645 }
4646 kws->nd_next = $3;
4647 $$ = $1;
4648 #endif
4649 $$ = rb_ary_push($1, $3);
4650
4651 }
4652 ;
4653
4654
4655 f_kwarg : f_kw
4656 {
4657 #if 0
4658 $$ = $1;
4659 #endif
4660 $$ = rb_ary_new3(1, $1);
4661
4662 }
4663 | f_kwarg ',' f_kw
4664 {
4665 #if 0
4666 NODE *kws = $1;
4667
4668 while (kws->nd_next) {
4669 kws = kws->nd_next;
4670 }
4671 kws->nd_next = $3;
4672 $$ = $1;
4673 #endif
4674 $$ = rb_ary_push($1, $3);
4675
4676 }
4677 ;
4678
4679 kwrest_mark : tPOW
4680 | tDSTAR
4681 ;
4682
4683 f_kwrest : kwrest_mark tIDENTIFIER
4684 {
4685 shadowing_lvar(get_id($2));
4686 $$ = $2;
4687 }
4688 | kwrest_mark
4689 {
4690 $$ = internal_id();
4691 }
4692 ;
4693
4694 f_opt : tIDENTIFIER '=' arg_value
4695 {
4696 arg_var(formal_argument(get_id($1)));
4697 $$ = assignable($1, $3);
4698 #if 0
4699 $$ = NEW_OPT_ARG(0, $$);
4700 #endif
4701 $$ = rb_assoc_new($$, $3);
4702
4703 }
4704 ;
4705
4706 f_block_opt : tIDENTIFIER '=' primary_value
4707 {
4708 arg_var(formal_argument(get_id($1)));
4709 $$ = assignable($1, $3);
4710 #if 0
4711 $$ = NEW_OPT_ARG(0, $$);
4712 #endif
4713 $$ = rb_assoc_new($$, $3);
4714
4715 }
4716 ;
4717
4718 f_block_optarg : f_block_opt
4719 {
4720 #if 0
4721 $$ = $1;
4722 #endif
4723 $$ = rb_ary_new3(1, $1);
4724
4725 }
4726 | f_block_optarg ',' f_block_opt
4727 {
4728 #if 0
4729 NODE *opts = $1;
4730
4731 while (opts->nd_next) {
4732 opts = opts->nd_next;
4733 }
4734 opts->nd_next = $3;
4735 $$ = $1;
4736 #endif
4737 $$ = rb_ary_push($1, $3);
4738
4739 }
4740 ;
4741
4742 f_optarg : f_opt
4743 {
4744 #if 0
4745 $$ = $1;
4746 #endif
4747 $$ = rb_ary_new3(1, $1);
4748
4749 }
4750 | f_optarg ',' f_opt
4751 {
4752 #if 0
4753 NODE *opts = $1;
4754
4755 while (opts->nd_next) {
4756 opts = opts->nd_next;
4757 }
4758 opts->nd_next = $3;
4759 $$ = $1;
4760 #endif
4761 $$ = rb_ary_push($1, $3);
4762
4763 }
4764 ;
4765
4766 restarg_mark : '*'
4767 | tSTAR
4768 ;
4769
4770 f_rest_arg : restarg_mark tIDENTIFIER
4771 {
4772 #if 0
4773 if (!is_local_id($2))
4774 yyerror("rest argument must be local variable");
4775 #endif
4776 arg_var(shadowing_lvar(get_id($2)));
4777 #if 0
4778 $$ = $2;
4779 #endif
4780 $$ = dispatch1(rest_param, $2);
4781
4782 }
4783 | restarg_mark
4784 {
4785 #if 0
4786 $$ = internal_id();
4787 arg_var($$);
4788 #endif
4789 $$ = dispatch1(rest_param, Qnil);
4790
4791 }
4792 ;
4793
4794 blkarg_mark : '&'
4795 | tAMPER
4796 ;
4797
4798 f_block_arg : blkarg_mark tIDENTIFIER
4799 {
4800 #if 0
4801 if (!is_local_id($2))
4802 yyerror("block argument must be local variable");
4803 else if (!dyna_in_block() && local_id($2))
4804 yyerror("duplicated block argument name");
4805 #endif
4806 arg_var(shadowing_lvar(get_id($2)));
4807 #if 0
4808 $$ = $2;
4809 #endif
4810 $$ = dispatch1(blockarg, $2);
4811
4812 }
4813 ;
4814
4815 opt_f_block_arg : ',' f_block_arg
4816 {
4817 $$ = $2;
4818 }
4819 | none
4820 {
4821 #if 0
4822 $$ = 0;
4823 #endif
4824 $$ = Qundef;
4825
4826 }
4827 ;
4828
4829 singleton : var_ref
4830 {
4831 #if 0
4832 value_expr($1);
4833 $$ = $1;
4834 if (!$$) $$ = NEW_NIL();
4835 #endif
4836 $$ = $1;
4837
4838 }
4839 | '(' {lex_state = EXPR_BEG;} expr rparen
4840 {
4841 #if 0
4842 if ($3 == 0) {
4843 yyerror("can't define singleton method for ().");
4844 }
4845 else {
4846 switch (nd_type($3)) {
4847 case NODE_STR:
4848 case NODE_DSTR:
4849 case NODE_XSTR:
4850 case NODE_DXSTR:
4851 case NODE_DREGX:
4852 case NODE_LIT:
4853 case NODE_ARRAY:
4854 case NODE_ZARRAY:
4855 yyerror("can't define singleton method for literals");
4856 default:
4857 value_expr($3);
4858 break;
4859 }
4860 }
4861 $$ = $3;
4862 #endif
4863 $$ = dispatch1(paren, $3);
4864
4865 }
4866 ;
4867
4868 assoc_list : none
4869 | assocs trailer
4870 {
4871 #if 0
4872 $$ = $1;
4873 #endif
4874 $$ = dispatch1(assoclist_from_args, $1);
4875
4876 }
4877 ;
4878
4879 assocs : assoc
4880 /*
4881 */
4882 {
4883 $$ = rb_ary_new3(1, $1);
4884 }
4885
4886 | assocs ',' assoc
4887 {
4888 #if 0
4889 $$ = list_concat($1, $3);
4890 #endif
4891 $$ = rb_ary_push($1, $3);
4892
4893 }
4894 ;
4895
4896 assoc : arg_value tASSOC arg_value
4897 {
4898 #if 0
4899 $$ = list_append(NEW_LIST($1), $3);
4900 #endif
4901 $$ = dispatch2(assoc_new, $1, $3);
4902
4903 }
4904 | tLABEL arg_value
4905 {
4906 #if 0
4907 $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
4908 #endif
4909 $$ = dispatch2(assoc_new, $1, $2);
4910
4911 }
4912 | tDSTAR arg_value
4913 {
4914 #if 0
4915 $$ = list_append(NEW_LIST(0), $2);
4916 #endif
4917 $$ = dispatch1(assoc_splat, $2);
4918
4919 }
4920 ;
4921
4922 ;
4923
4924 operation : tIDENTIFIER
4925 | tCONSTANT
4926 | tFID
4927 ;
4928
4929 operation2 : tIDENTIFIER
4930 | tCONSTANT
4931 | tFID
4932 | op
4933 ;
4934
4935 operation3 : tIDENTIFIER
4936 | tFID
4937 | op
4938 ;
4939
4940 dot_or_colon : '.'
4941 /*
4942 */
4943 { $$ = $<val>1; }
4944
4945 | tCOLON2
4946 /*
4947 */
4948 { $$ = $<val>1; }
4949
4950 ;
4951
4952 opt_terms : /* none */
4953 | terms
4954 ;
4955
4956 opt_nl : /* none */
4957 | '\n'
4958 ;
4959
4960 rparen : opt_nl ')'
4961 ;
4962
4963 rbracket : opt_nl ']'
4964 ;
4965
4966 trailer : /* none */
4967 | '\n'
4968 | ','
4969 ;
4970
4971 term : ';' {yyerrok;}
4972 | '\n'
4973 ;
4974
4975 terms : term
4976 | terms ';' {yyerrok;}
4977 ;
4978
4979 none : /* none */
4980 {
4981 #if 0
4982 $$ = 0;
4983 #endif
4984 $$ = Qundef;
4985
4986 }
4987 ;
4988 %%
4989 # undef parser
4990 # undef yylex
4991 # undef yylval
4992 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
4993
4994 static int parser_regx_options(struct parser_params*);
4995 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
4996 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
4997 static int parser_parse_string(struct parser_params*,NODE*);
4998 static int parser_here_document(struct parser_params*,NODE*);
4999
5000
5001 # define nextc() parser_nextc(parser)
5002 # define pushback(c) parser_pushback(parser, (c))
5003 # define newtok() parser_newtok(parser)
5004 # define tokspace(n) parser_tokspace(parser, (n))
5005 # define tokadd(c) parser_tokadd(parser, (c))
5006 # define tok_hex(numlen) parser_tok_hex(parser, (numlen))
5007 # define read_escape(flags,e) parser_read_escape(parser, (flags), (e))
5008 # define tokadd_escape(e) parser_tokadd_escape(parser, (e))
5009 # define regx_options() parser_regx_options(parser)
5010 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,(f),(t),(p),(n),(e))
5011 # define parse_string(n) parser_parse_string(parser,(n))
5012 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, (c), (enc))
5013 # define here_document(n) parser_here_document(parser,(n))
5014 # define heredoc_identifier() parser_heredoc_identifier(parser)
5015 # define heredoc_restore(n) parser_heredoc_restore(parser,(n))
5016 # define whole_match_p(e,l,i) parser_whole_match_p(parser,(e),(l),(i))
5017
5018 #ifndef RIPPER
5019 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
5020 # define set_yylval_num(x) (yylval.num = (x))
5021 # define set_yylval_id(x) (yylval.id = (x))
5022 # define set_yylval_name(x) (yylval.id = (x))
5023 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
5024 # define set_yylval_node(x) (yylval.node = (x))
5025 # define yylval_id() (yylval.id)
5026 #else
5027 static inline VALUE
5028 ripper_yylval_id(ID x)
5029 {
5030 return (VALUE)NEW_LASGN(x, ID2SYM(x));
5031 }
5032 # define set_yylval_str(x) (void)(x)
5033 # define set_yylval_num(x) (void)(x)
5034 # define set_yylval_id(x) (void)(x)
5035 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
5036 # define set_yylval_literal(x) (void)(x)
5037 # define set_yylval_node(x) (void)(x)
5038 # define yylval_id() yylval.id
5039 #endif
5040
5041 #ifndef RIPPER
5042 #define ripper_flush(p) (void)(p)
5043 #else
5044 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
5045
5046 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5047
5048 static int
5049 ripper_has_scan_event(struct parser_params *parser)
5050 {
5051
5052 if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
5053 return lex_p > parser->tokp;
5054 }
5055
5056 static VALUE
5057 ripper_scan_event_val(struct parser_params *parser, int t)
5058 {
5059 VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
5060 VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
5061 ripper_flush(parser);
5062 return rval;
5063 }
5064
5065 static void
5066 ripper_dispatch_scan_event(struct parser_params *parser, int t)
5067 {
5068 if (!ripper_has_scan_event(parser)) return;
5069 yylval_rval = ripper_scan_event_val(parser, t);
5070 }
5071
5072 static void
5073 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
5074 {
5075 if (!ripper_has_scan_event(parser)) return;
5076 (void)ripper_scan_event_val(parser, t);
5077 }
5078
5079 static void
5080 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
5081 {
5082 int saved_line = ruby_sourceline;
5083 const char *saved_tokp = parser->tokp;
5084
5085 ruby_sourceline = parser->delayed_line;
5086 parser->tokp = lex_pbeg + parser->delayed_col;
5087 yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
5088 parser->delayed = Qnil;
5089 ruby_sourceline = saved_line;
5090 parser->tokp = saved_tokp;
5091 }
5092 #endif /* RIPPER */
5093
5094 #include "ruby/regex.h"
5095 #include "ruby/util.h"
5096
5097 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
5098 since ours (we hope) works properly with all combinations of
5099 machines, compilers, `char' and `unsigned char' argument types.
5100 (Per Bothner suggested the basic approach.) */
5101 #undef SIGN_EXTEND_CHAR
5102 #if __STDC__
5103 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
5104 #else /* not __STDC__ */
5105 /* As in Harbison and Steele. */
5106 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
5107 #endif
5108
5109 #define parser_encoding_name() (current_enc->name)
5110 #define parser_mbclen() mbclen((lex_p-1),lex_pend,current_enc)
5111 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
5112 #define is_identchar(p,e,enc) (rb_enc_isalnum(*(p),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
5113 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
5114
5115 #define parser_isascii() ISASCII(*(lex_p-1))
5116
5117 #ifndef RIPPER
5118 static int
5119 token_info_get_column(struct parser_params *parser, const char *token)
5120 {
5121 int column = 1;
5122 const char *p, *pend = lex_p - strlen(token);
5123 for (p = lex_pbeg; p < pend; p++) {
5124 if (*p == '\t') {
5125 column = (((column - 1) / 8) + 1) * 8;
5126 }
5127 column++;
5128 }
5129 return column;
5130 }
5131
5132 static int
5133 token_info_has_nonspaces(struct parser_params *parser, const char *token)
5134 {
5135 const char *p, *pend = lex_p - strlen(token);
5136 for (p = lex_pbeg; p < pend; p++) {
5137 if (*p != ' ' && *p != '\t') {
5138 return 1;
5139 }
5140 }
5141 return 0;
5142 }
5143
5144 #undef token_info_push
5145 static void
5146 token_info_push(struct parser_params *parser, const char *token)
5147 {
5148 token_info *ptinfo;
5149
5150 if (!parser->parser_token_info_enabled) return;
5151 ptinfo = ALLOC(token_info);
5152 ptinfo->token = token;
5153 ptinfo->linenum = ruby_sourceline;
5154 ptinfo->column = token_info_get_column(parser, token);
5155 ptinfo->nonspc = token_info_has_nonspaces(parser, token);
5156 ptinfo->next = parser->parser_token_info;
5157
5158 parser->parser_token_info = ptinfo;
5159 }
5160
5161 #undef token_info_pop
5162 static void
5163 token_info_pop(struct parser_params *parser, const char *token)
5164 {
5165 int linenum;
5166 token_info *ptinfo = parser->parser_token_info;
5167
5168 if (!ptinfo) return;
5169 parser->parser_token_info = ptinfo->next;
5170 if (token_info_get_column(parser, token) == ptinfo->column) { /* OK */
5171 goto finish;
5172 }
5173 linenum = ruby_sourceline;
5174 if (linenum == ptinfo->linenum) { /* SKIP */
5175 goto finish;
5176 }
5177 if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) { /* SKIP */
5178 goto finish;
5179 }
5180 if (parser->parser_token_info_enabled) {
5181 rb_compile_warn(ruby_sourcefile, linenum,
5182 "mismatched indentations at '%s' with '%s' at %d",
5183 token, ptinfo->token, ptinfo->linenum);
5184 }
5185
5186 finish:
5187 xfree(ptinfo);
5188 }
5189 #endif /* RIPPER */
5190
5191 static int
5192 parser_yyerror(struct parser_params *parser, const char *msg)
5193 {
5194 #ifndef RIPPER
5195 const int max_line_margin = 30;
5196 const char *p, *pe;
5197 char *buf;
5198 long len;
5199 int i;
5200
5201 compile_error(PARSER_ARG "%s", msg);
5202 p = lex_p;
5203 while (lex_pbeg <= p) {
5204 if (*p == '\n') break;
5205 p--;
5206 }
5207 p++;
5208
5209 pe = lex_p;
5210 while (pe < lex_pend) {
5211 if (*pe == '\n') break;
5212 pe++;
5213 }
5214
5215 len = pe - p;
5216 if (len > 4) {
5217 char *p2;
5218 const char *pre = "", *post = "";
5219
5220 if (len > max_line_margin * 2 + 10) {
5221 if (lex_p - p > max_line_margin) {
5222 p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
5223 pre = "...";
5224 }
5225 if (pe - lex_p > max_line_margin) {
5226 pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
5227 post = "...";
5228 }
5229 len = pe - p;
5230 }
5231 buf = ALLOCA_N(char, len+2);
5232 MEMCPY(buf, p, char, len);
5233 buf[len] = '\0';
5234 rb_compile_error_append("%s%s%s", pre, buf, post);
5235
5236 i = (int)(lex_p - p);
5237 p2 = buf; pe = buf + len;
5238
5239 while (p2 < pe) {
5240 if (*p2 != '\t') *p2 = ' ';
5241 p2++;
5242 }
5243 buf[i] = '^';
5244 buf[i+1] = '\0';
5245 rb_compile_error_append("%s%s", pre, buf);
5246 }
5247 #else
5248 dispatch1(parse_error, STR_NEW2(msg));
5249 #endif /* !RIPPER */
5250 return 0;
5251 }
5252
5253 static void parser_prepare(struct parser_params *parser);
5254
5255 #ifndef RIPPER
5256 static VALUE
5257 debug_lines(const char *f)
5258 {
5259 ID script_lines;
5260 CONST_ID(script_lines, "SCRIPT_LINES__");
5261 if (rb_const_defined_at(rb_cObject, script_lines)) {
5262 VALUE hash = rb_const_get_at(rb_cObject, script_lines);
5263 if (RB_TYPE_P(hash, T_HASH)) {
5264 VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5265 VALUE lines = rb_ary_new();
5266 rb_hash_aset(hash, fname, lines);
5267 return lines;
5268 }
5269 }
5270 return 0;
5271 }
5272
5273 static VALUE
5274 coverage(const char *f, int n)
5275 {
5276 VALUE coverages = rb_get_coverages();
5277 if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
5278 VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5279 VALUE lines = rb_ary_new2(n);
5280 int i;
5281 RBASIC(lines)->klass = 0;
5282 for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
5283 RARRAY(lines)->as.heap.len = n;
5284 rb_hash_aset(coverages, fname, lines);
5285 return lines;
5286 }
5287 return 0;
5288 }
5289
5290 static int
5291 e_option_supplied(struct parser_params *parser)
5292 {
5293 return strcmp(ruby_sourcefile, "-e") == 0;
5294 }
5295
5296 static VALUE
5297 yycompile0(VALUE arg)
5298 {
5299 int n;
5300 NODE *tree;
5301 struct parser_params *parser = (struct parser_params *)arg;
5302
5303 if (!compile_for_eval && rb_safe_level() == 0) {
5304 ruby_debug_lines = debug_lines(ruby_sourcefile);
5305 if (ruby_debug_lines && ruby_sourceline > 0) {
5306 VALUE str = STR_NEW0();
5307 n = ruby_sourceline;
5308 do {
5309 rb_ary_push(ruby_debug_lines, str);
5310 } while (--n);
5311 }
5312
5313 if (!e_option_supplied(parser)) {
5314 ruby_coverage = coverage(ruby_sourcefile, ruby_sourceline);
5315 }
5316 }
5317
5318 parser_prepare(parser);
5319 deferred_nodes = 0;
5320 #ifndef RIPPER
5321 parser->parser_token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
5322 #endif
5323 #ifndef RIPPER
5324 if (RUBY_DTRACE_PARSE_BEGIN_ENABLED()) {
5325 RUBY_DTRACE_PARSE_BEGIN(parser->parser_ruby_sourcefile,
5326 parser->parser_ruby_sourceline);
5327 }
5328 #endif
5329 n = yyparse((void*)parser);
5330 #ifndef RIPPER
5331 if (RUBY_DTRACE_PARSE_END_ENABLED()) {
5332 RUBY_DTRACE_PARSE_END(parser->parser_ruby_sourcefile,
5333 parser->parser_ruby_sourceline);
5334 }
5335 #endif
5336 ruby_debug_lines = 0;
5337 ruby_coverage = 0;
5338 compile_for_eval = 0;
5339
5340 lex_strterm = 0;
5341 lex_p = lex_pbeg = lex_pend = 0;
5342 lex_lastline = lex_nextline = 0;
5343 if (parser->nerr) {
5344 return 0;
5345 }
5346 tree = ruby_eval_tree;
5347 if (!tree) {
5348 tree = NEW_NIL();
5349 }
5350 else if (ruby_eval_tree_begin) {
5351 tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
5352 }
5353 return (VALUE)tree;
5354 }
5355
5356 static NODE*
5357 yycompile(struct parser_params *parser, const char *f, int line)
5358 {
5359 ruby_sourcefile = ruby_strdup(f);
5360 ruby_sourceline = line - 1;
5361 return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
5362 }
5363 #endif /* !RIPPER */
5364
5365 static rb_encoding *
5366 must_be_ascii_compatible(VALUE s)
5367 {
5368 rb_encoding *enc = rb_enc_get(s);
5369 if (!rb_enc_asciicompat(enc)) {
5370 rb_raise(rb_eArgError, "invalid source encoding");
5371 }
5372 return enc;
5373 }
5374
5375 static VALUE
5376 lex_get_str(struct parser_params *parser, VALUE s)
5377 {
5378 char *beg, *end, *pend;
5379 rb_encoding *enc = must_be_ascii_compatible(s);
5380
5381 beg = RSTRING_PTR(s);
5382 if (lex_gets_ptr) {
5383 if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
5384 beg += lex_gets_ptr;
5385 }
5386 pend = RSTRING_PTR(s) + RSTRING_LEN(s);
5387 end = beg;
5388 while (end < pend) {
5389 if (*end++ == '\n') break;
5390 }
5391 lex_gets_ptr = end - RSTRING_PTR(s);
5392 return rb_enc_str_new(beg, end - beg, enc);
5393 }
5394
5395 static VALUE
5396 lex_getline(struct parser_params *parser)
5397 {
5398 VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
5399 if (NIL_P(line)) return line;
5400 must_be_ascii_compatible(line);
5401 #ifndef RIPPER
5402 if (ruby_debug_lines) {
5403 rb_enc_associate(line, current_enc);
5404 rb_ary_push(ruby_debug_lines, line);
5405 }
5406 if (ruby_coverage) {
5407 rb_ary_push(ruby_coverage, Qnil);
5408 }
5409 #endif
5410 return line;
5411 }
5412
5413 #ifdef RIPPER
5414 static rb_data_type_t parser_data_type;
5415 #else
5416 static const rb_data_type_t parser_data_type;
5417
5418 static NODE*
5419 parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5420 {
5421 struct parser_params *parser;
5422 NODE *node;
5423
5424 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5425 lex_gets = lex_get_str;
5426 lex_gets_ptr = 0;
5427 lex_input = s;
5428 lex_pbeg = lex_p = lex_pend = 0;
5429 compile_for_eval = rb_parse_in_eval();
5430
5431 node = yycompile(parser, f, line);
5432 RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5433
5434 return node;
5435 }
5436
5437 NODE*
5438 rb_compile_string(const char *f, VALUE s, int line)
5439 {
5440 must_be_ascii_compatible(s);
5441 return parser_compile_string(rb_parser_new(), f, s, line);
5442 }
5443
5444 NODE*
5445 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5446 {
5447 must_be_ascii_compatible(s);
5448 return parser_compile_string(vparser, f, s, line);
5449 }
5450
5451 NODE*
5452 rb_compile_cstr(const char *f, const char *s, int len, int line)
5453 {
5454 VALUE str = rb_str_new(s, len);
5455 return parser_compile_string(rb_parser_new(), f, str, line);
5456 }
5457
5458 NODE*
5459 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
5460 {
5461 VALUE str = rb_str_new(s, len);
5462 return parser_compile_string(vparser, f, str, line);
5463 }
5464
5465 static VALUE
5466 lex_io_gets(struct parser_params *parser, VALUE io)
5467 {
5468 return rb_io_gets(io);
5469 }
5470
5471 NODE*
5472 rb_compile_file(const char *f, VALUE file, int start)
5473 {
5474 VALUE volatile vparser = rb_parser_new();
5475
5476 return rb_parser_compile_file(vparser, f, file, start);
5477 }
5478
5479 NODE*
5480 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
5481 {
5482 struct parser_params *parser;
5483 NODE *node;
5484
5485 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5486 lex_gets = lex_io_gets;
5487 lex_input = file;
5488 lex_pbeg = lex_p = lex_pend = 0;
5489 compile_for_eval = rb_parse_in_eval();
5490
5491 node = yycompile(parser, f, start);
5492 RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5493
5494 return node;
5495 }
5496 #endif /* !RIPPER */
5497
5498 #define STR_FUNC_ESCAPE 0x01
5499 #define STR_FUNC_EXPAND 0x02
5500 #define STR_FUNC_REGEXP 0x04
5501 #define STR_FUNC_QWORDS 0x08
5502 #define STR_FUNC_SYMBOL 0x10
5503 #define STR_FUNC_INDENT 0x20
5504
5505 enum string_type {
5506 str_squote = (0),
5507 str_dquote = (STR_FUNC_EXPAND),
5508 str_xquote = (STR_FUNC_EXPAND),
5509 str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
5510 str_sword = (STR_FUNC_QWORDS),
5511 str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
5512 str_ssym = (STR_FUNC_SYMBOL),
5513 str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
5514 };
5515
5516 static VALUE
5517 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
5518 {
5519 VALUE str;
5520
5521 str = rb_enc_str_new(p, n, enc);
5522 if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
5523 if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
5524 }
5525 else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
5526 rb_enc_associate(str, rb_ascii8bit_encoding());
5527 }
5528 }
5529
5530 return str;
5531 }
5532
5533 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
5534 #define lex_eol_p() (lex_p >= lex_pend)
5535 #define peek(c) peek_n((c), 0)
5536 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
5537
5538 static inline int
5539 parser_nextc(struct parser_params *parser)
5540 {
5541 int c;
5542
5543 if (lex_p == lex_pend) {
5544 VALUE v = lex_nextline;
5545 lex_nextline = 0;
5546 if (!v) {
5547 if (parser->eofp)
5548 return -1;
5549
5550 if (!lex_input || NIL_P(v = lex_getline(parser))) {
5551 parser->eofp = Qtrue;
5552 lex_goto_eol(parser);
5553 return -1;
5554 }
5555 }
5556 {
5557 #ifdef RIPPER
5558 if (parser->tokp < lex_pend) {
5559 if (NIL_P(parser->delayed)) {
5560 parser->delayed = rb_str_buf_new(1024);
5561 rb_enc_associate(parser->delayed, current_enc);
5562 rb_str_buf_cat(parser->delayed,
5563 parser->tokp, lex_pend - parser->tokp);
5564 parser->delayed_line = ruby_sourceline;
5565 parser->delayed_col = (int)(parser->tokp - lex_pbeg);
5566 }
5567 else {
5568 rb_str_buf_cat(parser->delayed,
5569 parser->tokp, lex_pend - parser->tokp);
5570 }
5571 }
5572 #endif
5573 if (heredoc_end > 0) {
5574 ruby_sourceline = heredoc_end;
5575 heredoc_end = 0;
5576 }
5577 ruby_sourceline++;
5578 parser->line_count++;
5579 lex_pbeg = lex_p = RSTRING_PTR(v);
5580 lex_pend = lex_p + RSTRING_LEN(v);
5581 ripper_flush(parser);
5582 lex_lastline = v;
5583 }
5584 }
5585 c = (unsigned char)*lex_p++;
5586 if (c == '\r' && peek('\n')) {
5587 lex_p++;
5588 c = '\n';
5589 }
5590
5591 return c;
5592 }
5593
5594 static void
5595 parser_pushback(struct parser_params *parser, int c)
5596 {
5597 if (c == -1) return;
5598 lex_p--;
5599 if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
5600 lex_p--;
5601 }
5602 }
5603
5604 #define was_bol() (lex_p == lex_pbeg + 1)
5605
5606 #define tokfix() (tokenbuf[tokidx]='\0')
5607 #define tok() tokenbuf
5608 #define toklen() tokidx
5609 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
5610
5611 static char*
5612 parser_newtok(struct parser_params *parser)
5613 {
5614 tokidx = 0;
5615 tokline = ruby_sourceline;
5616 if (!tokenbuf) {
5617 toksiz = 60;
5618 tokenbuf = ALLOC_N(char, 60);
5619 }
5620 if (toksiz > 4096) {
5621 toksiz = 60;
5622 REALLOC_N(tokenbuf, char, 60);
5623 }
5624 return tokenbuf;
5625 }
5626
5627 static char *
5628 parser_tokspace(struct parser_params *parser, int n)
5629 {
5630 tokidx += n;
5631
5632 if (tokidx >= toksiz) {
5633 do {toksiz *= 2;} while (toksiz < tokidx);
5634 REALLOC_N(tokenbuf, char, toksiz);
5635 }
5636 return &tokenbuf[tokidx-n];
5637 }
5638
5639 static void
5640 parser_tokadd(struct parser_params *parser, int c)
5641 {
5642 tokenbuf[tokidx++] = (char)c;
5643 if (tokidx >= toksiz) {
5644 toksiz *= 2;
5645 REALLOC_N(tokenbuf, char, toksiz);
5646 }
5647 }
5648
5649 static int
5650 parser_tok_hex(struct parser_params *parser, size_t *numlen)
5651 {
5652 int c;
5653
5654 c = scan_hex(lex_p, 2, numlen);
5655 if (!*numlen) {
5656 yyerror("invalid hex escape");
5657 return 0;
5658 }
5659 lex_p += *numlen;
5660 return c;
5661 }
5662
5663 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5664
5665 /* return value is for ?\u3042 */
5666 static int
5667 parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
5668 int string_literal, int symbol_literal, int regexp_literal)
5669 {
5670 /*
5671 * If string_literal is true, then we allow multiple codepoints
5672 * in \u{}, and add the codepoints to the current token.
5673 * Otherwise we're parsing a character literal and return a single
5674 * codepoint without adding it
5675 */
5676
5677 int codepoint;
5678 size_t numlen;
5679
5680 if (regexp_literal) { tokadd('\\'); tokadd('u'); }
5681
5682 if (peek('{')) { /* handle \u{...} form */
5683 do {
5684 if (regexp_literal) { tokadd(*lex_p); }
5685 nextc();
5686 codepoint = scan_hex(lex_p, 6, &numlen);
5687 if (numlen == 0) {
5688 yyerror("invalid Unicode escape");
5689 return 0;
5690 }
5691 if (codepoint > 0x10ffff) {
5692 yyerror("invalid Unicode codepoint (too large)");
5693 return 0;
5694 }
5695 lex_p += numlen;
5696 if (regexp_literal) {
5697 tokcopy((int)numlen);
5698 }
5699 else if (codepoint >= 0x80) {
5700 *encp = rb_utf8_encoding();
5701 if (string_literal) tokaddmbc(codepoint, *encp);
5702 }
5703 else if (string_literal) {
5704 tokadd(codepoint);
5705 }
5706 } while (string_literal && (peek(' ') || peek('\t')));
5707
5708 if (!peek('}')) {
5709 yyerror("unterminated Unicode escape");
5710 return 0;
5711 }
5712
5713 if (regexp_literal) { tokadd('}'); }
5714 nextc();
5715 }
5716 else { /* handle \uxxxx form */
5717 codepoint = scan_hex(lex_p, 4, &numlen);
5718 if (numlen < 4) {
5719 yyerror("invalid Unicode escape");
5720 return 0;
5721 }
5722 lex_p += 4;
5723 if (regexp_literal) {
5724 tokcopy(4);
5725 }
5726 else if (codepoint >= 0x80) {
5727 *encp = rb_utf8_encoding();
5728 if (string_literal) tokaddmbc(codepoint, *encp);
5729 }
5730 else if (string_literal) {
5731 tokadd(codepoint);
5732 }
5733 }
5734
5735 return codepoint;
5736 }
5737
5738 #define ESCAPE_CONTROL 1
5739 #define ESCAPE_META 2
5740
5741 static int
5742 parser_read_escape(struct parser_params *parser, int flags,
5743 rb_encoding **encp)
5744 {
5745 int c;
5746 size_t numlen;
5747
5748 switch (c = nextc()) {
5749 case '\\': /* Backslash */
5750 return c;
5751
5752 case 'n': /* newline */
5753 return '\n';
5754
5755 case 't': /* horizontal tab */
5756 return '\t';
5757
5758 case 'r': /* carriage-return */
5759 return '\r';
5760
5761 case 'f': /* form-feed */
5762 return '\f';
5763
5764 case 'v': /* vertical tab */
5765 return '\13';
5766
5767 case 'a': /* alarm(bell) */
5768 return '\007';
5769
5770 case 'e': /* escape */
5771 return 033;
5772
5773 case '0': case '1': case '2': case '3': /* octal constant */
5774 case '4': case '5': case '6': case '7':
5775 pushback(c);
5776 c = scan_oct(lex_p, 3, &numlen);
5777 lex_p += numlen;
5778 return c;
5779
5780 case 'x': /* hex constant */
5781 c = tok_hex(&numlen);
5782 if (numlen == 0) return 0;
5783 return c;
5784
5785 case 'b': /* backspace */
5786 return '\010';
5787
5788 case 's': /* space */
5789 return ' ';
5790
5791 case 'M':
5792 if (flags & ESCAPE_META) goto eof;
5793 if ((c = nextc()) != '-') {
5794 pushback(c);
5795 goto eof;
5796 }
5797 if ((c = nextc()) == '\\') {
5798 if (peek('u')) goto eof;
5799 return read_escape(flags|ESCAPE_META, encp) | 0x80;
5800 }
5801 else if (c == -1 || !ISASCII(c)) goto eof;
5802 else {
5803 return ((c & 0xff) | 0x80);
5804 }
5805
5806 case 'C':
5807 if ((c = nextc()) != '-') {
5808 pushback(c);
5809 goto eof;
5810 }
5811 case 'c':
5812 if (flags & ESCAPE_CONTROL) goto eof;
5813 if ((c = nextc())== '\\') {
5814 if (peek('u')) goto eof;
5815 c = read_escape(flags|ESCAPE_CONTROL, encp);
5816 }
5817 else if (c == '?')
5818 return 0177;
5819 else if (c == -1 || !ISASCII(c)) goto eof;
5820 return c & 0x9f;
5821
5822 eof:
5823 case -1:
5824 yyerror("Invalid escape character syntax");
5825 return '\0';
5826
5827 default:
5828 return c;
5829 }
5830 }
5831
5832 static void
5833 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
5834 {
5835 int len = rb_enc_codelen(c, enc);
5836 rb_enc_mbcput(c, tokspace(len), enc);
5837 }
5838
5839 static int
5840 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
5841 {
5842 int c;
5843 int flags = 0;
5844 size_t numlen;
5845
5846 first:
5847 switch (c = nextc()) {
5848 case '\n':
5849 return 0; /* just ignore */
5850
5851 case '0': case '1': case '2': case '3': /* octal constant */
5852 case '4': case '5': case '6': case '7':
5853 {
5854 ruby_scan_oct(--lex_p, 3, &numlen);
5855 if (numlen == 0) goto eof;
5856 lex_p += numlen;
5857 tokcopy((int)numlen + 1);
5858 }
5859 return 0;
5860
5861 case 'x': /* hex constant */
5862 {
5863 tok_hex(&numlen);
5864 if (numlen == 0) return -1;
5865 tokcopy((int)numlen + 2);
5866 }
5867 return 0;
5868
5869 case 'M':
5870 if (flags & ESCAPE_META) goto eof;
5871 if ((c = nextc()) != '-') {
5872 pushback(c);
5873 goto eof;
5874 }
5875 tokcopy(3);
5876 flags |= ESCAPE_META;
5877 goto escaped;
5878
5879 case 'C':
5880 if (flags & ESCAPE_CONTROL) goto eof;
5881 if ((c = nextc()) != '-') {
5882 pushback(c);
5883 goto eof;
5884 }
5885 tokcopy(3);
5886 goto escaped;
5887
5888 case 'c':
5889 if (flags & ESCAPE_CONTROL) goto eof;
5890 tokcopy(2);
5891 flags |= ESCAPE_CONTROL;
5892 escaped:
5893 if ((c = nextc()) == '\\') {
5894 goto first;
5895 }
5896 else if (c == -1) goto eof;
5897 tokadd(c);
5898 return 0;
5899
5900 eof:
5901 case -1:
5902 yyerror("Invalid escape character syntax");
5903 return -1;
5904
5905 default:
5906 tokadd('\\');
5907 tokadd(c);
5908 }
5909 return 0;
5910 }
5911
5912 static int
5913 parser_regx_options(struct parser_params *parser)
5914 {
5915 int kcode = 0;
5916 int kopt = 0;
5917 int options = 0;
5918 int c, opt, kc;
5919
5920 newtok();
5921 while (c = nextc(), ISALPHA(c)) {
5922 if (c == 'o') {
5923 options |= RE_OPTION_ONCE;
5924 }
5925 else if (rb_char_to_option_kcode(c, &opt, &kc)) {
5926 if (kc >= 0) {
5927 if (kc != rb_ascii8bit_encindex()) kcode = c;
5928 kopt = opt;
5929 }
5930 else {
5931 options |= opt;
5932 }
5933 }
5934 else {
5935 tokadd(c);
5936 }
5937 }
5938 options |= kopt;
5939 pushback(c);
5940 if (toklen()) {
5941 tokfix();
5942 compile_error(PARSER_ARG "unknown regexp option%s - %s",
5943 toklen() > 1 ? "s" : "", tok());
5944 }
5945 return options | RE_OPTION_ENCODING(kcode);
5946 }
5947
5948 static void
5949 dispose_string(VALUE str)
5950 {
5951 rb_str_free(str);
5952 rb_gc_force_recycle(str);
5953 }
5954
5955 static int
5956 parser_tokadd_mbchar(struct parser_params *parser, int c)
5957 {
5958 int len = parser_precise_mbclen();
5959 if (!MBCLEN_CHARFOUND_P(len)) {
5960 compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
5961 return -1;
5962 }
5963 tokadd(c);
5964 lex_p += --len;
5965 if (len > 0) tokcopy(len);
5966 return c;
5967 }
5968
5969 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
5970
5971 static inline int
5972 simple_re_meta(int c)
5973 {
5974 switch (c) {
5975 case '$': case '*': case '+': case '.':
5976 case '?': case '^': case '|':
5977 case ')': case ']': case '}': case '>':
5978 return TRUE;
5979 default:
5980 return FALSE;
5981 }
5982 }
5983
5984 static int
5985 parser_tokadd_string(struct parser_params *parser,
5986 int func, int term, int paren, long *nest,
5987 rb_encoding **encp)
5988 {
5989 int c;
5990 int has_nonascii = 0;
5991 rb_encoding *enc = *encp;
5992 char *errbuf = 0;
5993 static const char mixed_msg[] = "%s mixed within %s source";
5994
5995 #define mixed_error(enc1, enc2) if (!errbuf) { \
5996 size_t len = sizeof(mixed_msg) - 4; \
5997 len += strlen(rb_enc_name(enc1)); \
5998 len += strlen(rb_enc_name(enc2)); \
5999 errbuf = ALLOCA_N(char, len); \
6000 snprintf(errbuf, len, mixed_msg, \
6001 rb_enc_name(enc1), \
6002 rb_enc_name(enc2)); \
6003 yyerror(errbuf); \
6004 }
6005 #define mixed_escape(beg, enc1, enc2) do { \
6006 const char *pos = lex_p; \
6007 lex_p = (beg); \
6008 mixed_error((enc1), (enc2)); \
6009 lex_p = pos; \
6010 } while (0)
6011
6012 while ((c = nextc()) != -1) {
6013 if (paren && c == paren) {
6014 ++*nest;
6015 }
6016 else if (c == term) {
6017 if (!nest || !*nest) {
6018 pushback(c);
6019 break;
6020 }
6021 --*nest;
6022 }
6023 else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
6024 int c2 = *lex_p;
6025 if (c2 == '$' || c2 == '@' || c2 == '{') {
6026 pushback(c);
6027 break;
6028 }
6029 }
6030 else if (c == '\\') {
6031 const char *beg = lex_p - 1;
6032 c = nextc();
6033 switch (c) {
6034 case '\n':
6035 if (func & STR_FUNC_QWORDS) break;
6036 if (func & STR_FUNC_EXPAND) continue;
6037 tokadd('\\');
6038 break;
6039
6040 case '\\':
6041 if (func & STR_FUNC_ESCAPE) tokadd(c);
6042 break;
6043
6044 case 'u':
6045 if ((func & STR_FUNC_EXPAND) == 0) {
6046 tokadd('\\');
6047 break;
6048 }
6049 parser_tokadd_utf8(parser, &enc, 1,
6050 func & STR_FUNC_SYMBOL,
6051 func & STR_FUNC_REGEXP);
6052 if (has_nonascii && enc != *encp) {
6053 mixed_escape(beg, enc, *encp);
6054 }
6055 continue;
6056
6057 default:
6058 if (c == -1) return -1;
6059 if (!ISASCII(c)) {
6060 if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
6061 goto non_ascii;
6062 }
6063 if (func & STR_FUNC_REGEXP) {
6064 if (c == term && !simple_re_meta(c)) {
6065 tokadd(c);
6066 continue;
6067 }
6068 pushback(c);
6069 if ((c = tokadd_escape(&enc)) < 0)
6070 return -1;
6071 if (has_nonascii && enc != *encp) {
6072 mixed_escape(beg, enc, *encp);
6073 }
6074 continue;
6075 }
6076 else if (func & STR_FUNC_EXPAND) {
6077 pushback(c);
6078 if (func & STR_FUNC_ESCAPE) tokadd('\\');
6079 c = read_escape(0, &enc);
6080 }
6081 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6082 /* ignore backslashed spaces in %w */
6083 }
6084 else if (c != term && !(paren && c == paren)) {
6085 tokadd('\\');
6086 pushback(c);
6087 continue;
6088 }
6089 }
6090 }
6091 else if (!parser_isascii()) {
6092 non_ascii:
6093 has_nonascii = 1;
6094 if (enc != *encp) {
6095 mixed_error(enc, *encp);
6096 continue;
6097 }
6098 if (tokadd_mbchar(c) == -1) return -1;
6099 continue;
6100 }
6101 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6102 pushback(c);
6103 break;
6104 }
6105 if (c & 0x80) {
6106 has_nonascii = 1;
6107 if (enc != *encp) {
6108 mixed_error(enc, *encp);
6109 continue;
6110 }
6111 }
6112 tokadd(c);
6113 }
6114 *encp = enc;
6115 return c;
6116 }
6117
6118 #define NEW_STRTERM(func, term, paren) \
6119 rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
6120
6121 #ifdef RIPPER
6122 static void
6123 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
6124 {
6125 if (!NIL_P(parser->delayed)) {
6126 ptrdiff_t len = lex_p - parser->tokp;
6127 if (len > 0) {
6128 rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
6129 }
6130 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6131 parser->tokp = lex_p;
6132 }
6133 }
6134
6135 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
6136 #else
6137 #define flush_string_content(enc) ((void)(enc))
6138 #endif
6139
6140 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
6141 /* this can be shared with ripper, since it's independent from struct
6142 * parser_params. */
6143 #ifndef RIPPER
6144 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
6145 #define SPECIAL_PUNCT(idx) ( \
6146 BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
6147 BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
6148 BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
6149 BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
6150 BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
6151 BIT('0', idx))
6152 const unsigned int ruby_global_name_punct_bits[] = {
6153 SPECIAL_PUNCT(0),
6154 SPECIAL_PUNCT(1),
6155 SPECIAL_PUNCT(2),
6156 };
6157 #undef BIT
6158 #undef SPECIAL_PUNCT
6159 #endif
6160
6161 static inline int
6162 is_global_name_punct(const char c)
6163 {
6164 if (c <= 0x20 || 0x7e < c) return 0;
6165 return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
6166 }
6167
6168 static int
6169 parser_peek_variable_name(struct parser_params *parser)
6170 {
6171 int c;
6172 const char *p = lex_p;
6173
6174 if (p + 1 >= lex_pend) return 0;
6175 c = *p++;
6176 switch (c) {
6177 case '$':
6178 if ((c = *p) == '-') {
6179 if (++p >= lex_pend) return 0;
6180 c = *p;
6181 }
6182 else if (is_global_name_punct(c) || ISDIGIT(c)) {
6183 return tSTRING_DVAR;
6184 }
6185 break;
6186 case '@':
6187 if ((c = *p) == '@') {
6188 if (++p >= lex_pend) return 0;
6189 c = *p;
6190 }
6191 break;
6192 case '{':
6193 lex_p = p;
6194 command_start = TRUE;
6195 return tSTRING_DBEG;
6196 default:
6197 return 0;
6198 }
6199 if (!ISASCII(c) || c == '_' || ISALPHA(c))
6200 return tSTRING_DVAR;
6201 return 0;
6202 }
6203
6204 static int
6205 parser_parse_string(struct parser_params *parser, NODE *quote)
6206 {
6207 int func = (int)quote->nd_func;
6208 int term = nd_term(quote);
6209 int paren = nd_paren(quote);
6210 int c, space = 0;
6211 rb_encoding *enc = current_enc;
6212
6213 if (func == -1) return tSTRING_END;
6214 c = nextc();
6215 if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6216 do {c = nextc();} while (ISSPACE(c));
6217 space = 1;
6218 }
6219 if (c == term && !quote->nd_nest) {
6220 if (func & STR_FUNC_QWORDS) {
6221 quote->nd_func = -1;
6222 return ' ';
6223 }
6224 if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
6225 set_yylval_num(regx_options());
6226 return tREGEXP_END;
6227 }
6228 if (space) {
6229 pushback(c);
6230 return ' ';
6231 }
6232 newtok();
6233 if ((func & STR_FUNC_EXPAND) && c == '#') {
6234 int t = parser_peek_variable_name(parser);
6235 if (t) return t;
6236 tokadd('#');
6237 c = nextc();
6238 }
6239 pushback(c);
6240 if (tokadd_string(func, term, paren, &quote->nd_nest,
6241 &enc) == -1) {
6242 ruby_sourceline = nd_line(quote);
6243 if (func & STR_FUNC_REGEXP) {
6244 if (parser->eofp)
6245 compile_error(PARSER_ARG "unterminated regexp meets end of file");
6246 return tREGEXP_END;
6247 }
6248 else {
6249 if (parser->eofp)
6250 compile_error(PARSER_ARG "unterminated string meets end of file");
6251 return tSTRING_END;
6252 }
6253 }
6254
6255 tokfix();
6256 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6257 flush_string_content(enc);
6258
6259 return tSTRING_CONTENT;
6260 }
6261
6262 static int
6263 parser_heredoc_identifier(struct parser_params *parser)
6264 {
6265 int c = nextc(), term, func = 0;
6266 long len;
6267
6268 if (c == '-') {
6269 c = nextc();
6270 func = STR_FUNC_INDENT;
6271 }
6272 switch (c) {
6273 case '\'':
6274 func |= str_squote; goto quoted;
6275 case '"':
6276 func |= str_dquote; goto quoted;
6277 case '`':
6278 func |= str_xquote;
6279 quoted:
6280 newtok();
6281 tokadd(func);
6282 term = c;
6283 while ((c = nextc()) != -1 && c != term) {
6284 if (tokadd_mbchar(c) == -1) return 0;
6285 }
6286 if (c == -1) {
6287 compile_error(PARSER_ARG "unterminated here document identifier");
6288 return 0;
6289 }
6290 break;
6291
6292 default:
6293 if (!parser_is_identchar()) {
6294 pushback(c);
6295 if (func & STR_FUNC_INDENT) {
6296 pushback('-');
6297 }
6298 return 0;
6299 }
6300 newtok();
6301 term = '"';
6302 tokadd(func |= str_dquote);
6303 do {
6304 if (tokadd_mbchar(c) == -1) return 0;
6305 } while ((c = nextc()) != -1 && parser_is_identchar());
6306 pushback(c);
6307 break;
6308 }
6309
6310 tokfix();
6311 #ifdef RIPPER
6312 ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
6313 #endif
6314 len = lex_p - lex_pbeg;
6315 lex_goto_eol(parser);
6316 lex_strterm = rb_node_newnode(NODE_HEREDOC,
6317 STR_NEW(tok(), toklen()), /* nd_lit */
6318 len, /* nd_nth */
6319 lex_lastline); /* nd_orig */
6320 nd_set_line(lex_strterm, ruby_sourceline);
6321 ripper_flush(parser);
6322 return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
6323 }
6324
6325 static void
6326 parser_heredoc_restore(struct parser_params *parser, NODE *here)
6327 {
6328 VALUE line;
6329
6330 line = here->nd_orig;
6331 lex_lastline = line;
6332 lex_pbeg = RSTRING_PTR(line);
6333 lex_pend = lex_pbeg + RSTRING_LEN(line);
6334 lex_p = lex_pbeg + here->nd_nth;
6335 heredoc_end = ruby_sourceline;
6336 ruby_sourceline = nd_line(here);
6337 dispose_string(here->nd_lit);
6338 rb_gc_force_recycle((VALUE)here);
6339 ripper_flush(parser);
6340 }
6341
6342 static int
6343 parser_whole_match_p(struct parser_params *parser,
6344 const char *eos, long len, int indent)
6345 {
6346 const char *p = lex_pbeg;
6347 long n;
6348
6349 if (indent) {
6350 while (*p && ISSPACE(*p)) p++;
6351 }
6352 n = lex_pend - (p + len);
6353 if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
6354 return strncmp(eos, p, len) == 0;
6355 }
6356
6357 #ifdef RIPPER
6358 static void
6359 ripper_dispatch_heredoc_end(struct parser_params *parser)
6360 {
6361 if (!NIL_P(parser->delayed))
6362 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6363 lex_goto_eol(parser);
6364 ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
6365 }
6366
6367 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
6368 #else
6369 #define dispatch_heredoc_end() ((void)0)
6370 #endif
6371
6372 static int
6373 parser_here_document(struct parser_params *parser, NODE *here)
6374 {
6375 int c, func, indent = 0;
6376 const char *eos, *p, *pend;
6377 long len;
6378 VALUE str = 0;
6379 rb_encoding *enc = current_enc;
6380
6381 eos = RSTRING_PTR(here->nd_lit);
6382 len = RSTRING_LEN(here->nd_lit) - 1;
6383 indent = (func = *eos++) & STR_FUNC_INDENT;
6384
6385 if ((c = nextc()) == -1) {
6386 error:
6387 compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
6388 #ifdef RIPPER
6389 if (NIL_P(parser->delayed)) {
6390 ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
6391 }
6392 else {
6393 if (str ||
6394 ((len = lex_p - parser->tokp) > 0 &&
6395 (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
6396 rb_str_append(parser->delayed, str);
6397 }
6398 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6399 }
6400 lex_goto_eol(parser);
6401 #endif
6402 restore:
6403 heredoc_restore(lex_strterm);
6404 lex_strterm = 0;
6405 return 0;
6406 }
6407 if (was_bol() && whole_match_p(eos, len, indent)) {
6408 dispatch_heredoc_end();
6409 heredoc_restore(lex_strterm);
6410 return tSTRING_END;
6411 }
6412
6413 if (!(func & STR_FUNC_EXPAND)) {
6414 do {
6415 p = RSTRING_PTR(lex_lastline);
6416 pend = lex_pend;
6417 if (pend > p) {
6418 switch (pend[-1]) {
6419 case '\n':
6420 if (--pend == p || pend[-1] != '\r') {
6421 pend++;
6422 break;
6423 }
6424 case '\r':
6425 --pend;
6426 }
6427 }
6428 if (str)
6429 rb_str_cat(str, p, pend - p);
6430 else
6431 str = STR_NEW(p, pend - p);
6432 if (pend < lex_pend) rb_str_cat(str, "\n", 1);
6433 lex_goto_eol(parser);
6434 if (nextc() == -1) {
6435 if (str) dispose_string(str);
6436 goto error;
6437 }
6438 } while (!whole_match_p(eos, len, indent));
6439 }
6440 else {
6441 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
6442 newtok();
6443 if (c == '#') {
6444 int t = parser_peek_variable_name(parser);
6445 if (t) return t;
6446 tokadd('#');
6447 c = nextc();
6448 }
6449 do {
6450 pushback(c);
6451 if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
6452 if (parser->eofp) goto error;
6453 goto restore;
6454 }
6455 if (c != '\n') {
6456 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6457 flush_string_content(enc);
6458 return tSTRING_CONTENT;
6459 }
6460 tokadd(nextc());
6461 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
6462 if ((c = nextc()) == -1) goto error;
6463 } while (!whole_match_p(eos, len, indent));
6464 str = STR_NEW3(tok(), toklen(), enc, func);
6465 }
6466 dispatch_heredoc_end();
6467 heredoc_restore(lex_strterm);
6468 lex_strterm = NEW_STRTERM(-1, 0, 0);
6469 set_yylval_str(str);
6470 return tSTRING_CONTENT;
6471 }
6472
6473 #include "lex.c"
6474
6475 static void
6476 arg_ambiguous_gen(struct parser_params *parser)
6477 {
6478 #ifndef RIPPER
6479 rb_warning0("ambiguous first argument; put parentheses or even spaces");
6480 #else
6481 dispatch0(arg_ambiguous);
6482 #endif
6483 }
6484 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
6485
6486 static ID
6487 formal_argument_gen(struct parser_params *parser, ID lhs)
6488 {
6489 #ifndef RIPPER
6490 if (!is_local_id(lhs))
6491 yyerror("formal argument must be local variable");
6492 #endif
6493 shadowing_lvar(lhs);
6494 return lhs;
6495 }
6496
6497 static int
6498 lvar_defined_gen(struct parser_params *parser, ID id)
6499 {
6500 return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
6501 }
6502
6503 /* emacsen -*- hack */
6504 static long
6505 parser_encode_length(struct parser_params *parser, const char *name, long len)
6506 {
6507 long nlen;
6508
6509 if (len > 5 && name[nlen = len - 5] == '-') {
6510 if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
6511 return nlen;
6512 }
6513 if (len > 4 && name[nlen = len - 4] == '-') {
6514 if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
6515 return nlen;
6516 if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
6517 !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
6518 /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
6519 return nlen;
6520 }
6521 return len;
6522 }
6523
6524 static void
6525 parser_set_encode(struct parser_params *parser, const char *name)
6526 {
6527 int idx = rb_enc_find_index(name);
6528 rb_encoding *enc;
6529 VALUE excargs[3];
6530
6531 if (idx < 0) {
6532 excargs[1] = rb_sprintf("unknown encoding name: %s", name);
6533 error:
6534 excargs[0] = rb_eArgError;
6535 excargs[2] = rb_make_backtrace();
6536 rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
6537 rb_exc_raise(rb_make_exception(3, excargs));
6538 }
6539 enc = rb_enc_from_index(idx);
6540 if (!rb_enc_asciicompat(enc)) {
6541 excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
6542 goto error;
6543 }
6544 parser->enc = enc;
6545 #ifndef RIPPER
6546 if (ruby_debug_lines) {
6547 long i, n = RARRAY_LEN(ruby_debug_lines);
6548 const VALUE *p = RARRAY_PTR(ruby_debug_lines);
6549 for (i = 0; i < n; ++i) {
6550 rb_enc_associate_index(*p, idx);
6551 }
6552 }
6553 #endif
6554 }
6555
6556 static int
6557 comment_at_top(struct parser_params *parser)
6558 {
6559 const char *p = lex_pbeg, *pend = lex_p - 1;
6560 if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
6561 while (p < pend) {
6562 if (!ISSPACE(*p)) return 0;
6563 p++;
6564 }
6565 return 1;
6566 }
6567
6568 #ifndef RIPPER
6569 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
6570 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
6571
6572 static void
6573 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
6574 {
6575 if (!comment_at_top(parser)) {
6576 return;
6577 }
6578 parser_set_encode(parser, val);
6579 }
6580
6581 static void
6582 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
6583 {
6584 int *p = &parser->parser_token_info_enabled;
6585
6586 switch (*val) {
6587 case 't': case 'T':
6588 if (strcasecmp(val, "true") == 0) {
6589 *p = TRUE;
6590 return;
6591 }
6592 break;
6593 case 'f': case 'F':
6594 if (strcasecmp(val, "false") == 0) {
6595 *p = FALSE;
6596 return;
6597 }
6598 break;
6599 }
6600 rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
6601 }
6602
6603 struct magic_comment {
6604 const char *name;
6605 rb_magic_comment_setter_t func;
6606 rb_magic_comment_length_t length;
6607 };
6608
6609 static const struct magic_comment magic_comments[] = {
6610 {"coding", magic_comment_encoding, parser_encode_length},
6611 {"encoding", magic_comment_encoding, parser_encode_length},
6612 {"warn_indent", parser_set_token_info},
6613 };
6614 #endif
6615
6616 static const char *
6617 magic_comment_marker(const char *str, long len)
6618 {
6619 long i = 2;
6620
6621 while (i < len) {
6622 switch (str[i]) {
6623 case '-':
6624 if (str[i-1] == '*' && str[i-2] == '-') {
6625 return str + i + 1;
6626 }
6627 i += 2;
6628 break;
6629 case '*':
6630 if (i + 1 >= len) return 0;
6631 if (str[i+1] != '-') {
6632 i += 4;
6633 }
6634 else if (str[i-1] != '-') {
6635 i += 2;
6636 }
6637 else {
6638 return str + i + 2;
6639 }
6640 break;
6641 default:
6642 i += 3;
6643 break;
6644 }
6645 }
6646 return 0;
6647 }
6648
6649 static int
6650 parser_magic_comment(struct parser_params *parser, const char *str, long len)
6651 {
6652 VALUE name = 0, val = 0;
6653 const char *beg, *end, *vbeg, *vend;
6654 #define str_copy(_s, _p, _n) ((_s) \
6655 ? (void)(rb_str_resize((_s), (_n)), \
6656 MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
6657 : (void)((_s) = STR_NEW((_p), (_n))))
6658
6659 if (len <= 7) return FALSE;
6660 if (!(beg = magic_comment_marker(str, len))) return FALSE;
6661 if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
6662 str = beg;
6663 len = end - beg - 3;
6664
6665 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
6666 while (len > 0) {
6667 #ifndef RIPPER
6668 const struct magic_comment *p = magic_comments;
6669 #endif
6670 char *s;
6671 int i;
6672 long n = 0;
6673
6674 for (; len > 0 && *str; str++, --len) {
6675 switch (*str) {
6676 case '\'': case '"': case ':': case ';':
6677 continue;
6678 }
6679 if (!ISSPACE(*str)) break;
6680 }
6681 for (beg = str; len > 0; str++, --len) {
6682 switch (*str) {
6683 case '\'': case '"': case ':': case ';':
6684 break;
6685 default:
6686 if (ISSPACE(*str)) break;
6687 continue;
6688 }
6689 break;
6690 }
6691 for (end = str; len > 0 && ISSPACE(*str); str++, --len);
6692 if (!len) break;
6693 if (*str != ':') continue;
6694
6695 do str++; while (--len > 0 && ISSPACE(*str));
6696 if (!len) break;
6697 if (*str == '"') {
6698 for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
6699 if (*str == '\\') {
6700 --len;
6701 ++str;
6702 }
6703 }
6704 vend = str;
6705 if (len) {
6706 --len;
6707 ++str;
6708 }
6709 }
6710 else {
6711 for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
6712 vend = str;
6713 }
6714 while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
6715
6716 n = end - beg;
6717 str_copy(name, beg, n);
6718 s = RSTRING_PTR(name);
6719 for (i = 0; i < n; ++i) {
6720 if (s[i] == '-') s[i] = '_';
6721 }
6722 #ifndef RIPPER
6723 do {
6724 if (STRNCASECMP(p->name, s, n) == 0) {
6725 n = vend - vbeg;
6726 if (p->length) {
6727 n = (*p->length)(parser, vbeg, n);
6728 }
6729 str_copy(val, vbeg, n);
6730 (*p->func)(parser, s, RSTRING_PTR(val));
6731 break;
6732 }
6733 } while (++p < magic_comments + numberof(magic_comments));
6734 #else
6735 str_copy(val, vbeg, vend - vbeg);
6736 dispatch2(magic_comment, name, val);
6737 #endif
6738 }
6739
6740 return TRUE;
6741 }
6742
6743 static void
6744 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
6745 {
6746 int sep = 0;
6747 const char *beg = str;
6748 VALUE s;
6749
6750 for (;;) {
6751 if (send - str <= 6) return;
6752 switch (str[6]) {
6753 case 'C': case 'c': str += 6; continue;
6754 case 'O': case 'o': str += 5; continue;
6755 case 'D': case 'd': str += 4; continue;
6756 case 'I': case 'i': str += 3; continue;
6757 case 'N': case 'n': str += 2; continue;
6758 case 'G': case 'g': str += 1; continue;
6759 case '=': case ':':
6760 sep = 1;
6761 str += 6;
6762 break;
6763 default:
6764 str += 6;
6765 if (ISSPACE(*str)) break;
6766 continue;
6767 }
6768 if (STRNCASECMP(str-6, "coding", 6) == 0) break;
6769 }
6770 for (;;) {
6771 do {
6772 if (++str >= send) return;
6773 } while (ISSPACE(*str));
6774 if (sep) break;
6775 if (*str != '=' && *str != ':') return;
6776 sep = 1;
6777 str++;
6778 }
6779 beg = str;
6780 while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
6781 s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
6782 parser_set_encode(parser, RSTRING_PTR(s));
6783 rb_str_resize(s, 0);
6784 }
6785
6786 static void
6787 parser_prepare(struct parser_params *parser)
6788 {
6789 int c = nextc();
6790 switch (c) {
6791 case '#':
6792 if (peek('!')) parser->has_shebang = 1;
6793 break;
6794 case 0xef: /* UTF-8 BOM marker */
6795 if (lex_pend - lex_p >= 2 &&
6796 (unsigned char)lex_p[0] == 0xbb &&
6797 (unsigned char)lex_p[1] == 0xbf) {
6798 parser->enc = rb_utf8_encoding();
6799 lex_p += 2;
6800 lex_pbeg = lex_p;
6801 return;
6802 }
6803 break;
6804 case EOF:
6805 return;
6806 }
6807 pushback(c);
6808 parser->enc = rb_enc_get(lex_lastline);
6809 }
6810
6811 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
6812 #define IS_END() IS_lex_state(EXPR_END_ANY)
6813 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
6814 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
6815 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
6816 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
6817 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
6818
6819 #ifndef RIPPER
6820 #define ambiguous_operator(op, syn) ( \
6821 rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
6822 rb_warning0("even though it seems like "syn""))
6823 #else
6824 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
6825 #endif
6826 #define warn_balanced(op, syn) ((void) \
6827 (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
6828 space_seen && !ISSPACE(c) && \
6829 (ambiguous_operator(op, syn), 0)))
6830
6831 static int
6832 parser_yylex(struct parser_params *parser)
6833 {
6834 register int c;
6835 int space_seen = 0;
6836 int cmd_state;
6837 enum lex_state_e last_state;
6838 rb_encoding *enc;
6839 int mb;
6840 #ifdef RIPPER
6841 int fallthru = FALSE;
6842 #endif
6843
6844 if (lex_strterm) {
6845 int token;
6846 if (nd_type(lex_strterm) == NODE_HEREDOC) {
6847 token = here_document(lex_strterm);
6848 if (token == tSTRING_END) {
6849 lex_strterm = 0;
6850 lex_state = EXPR_END;
6851 }
6852 }
6853 else {
6854 token = parse_string(lex_strterm);
6855 if (token == tSTRING_END || token == tREGEXP_END) {
6856 rb_gc_force_recycle((VALUE)lex_strterm);
6857 lex_strterm = 0;
6858 lex_state = EXPR_END;
6859 }
6860 }
6861 return token;
6862 }
6863 cmd_state = command_start;
6864 command_start = FALSE;
6865 retry:
6866 last_state = lex_state;
6867 switch (c = nextc()) {
6868 case '\0': /* NUL */
6869 case '\004': /* ^D */
6870 case '\032': /* ^Z */
6871 case -1: /* end of script. */
6872 return 0;
6873
6874 /* white spaces */
6875 case ' ': case '\t': case '\f': case '\r':
6876 case '\13': /* '\v' */
6877 space_seen = 1;
6878 #ifdef RIPPER
6879 while ((c = nextc())) {
6880 switch (c) {
6881 case ' ': case '\t': case '\f': case '\r':
6882 case '\13': /* '\v' */
6883 break;
6884 default:
6885 goto outofloop;
6886 }
6887 }
6888 outofloop:
6889 pushback(c);
6890 ripper_dispatch_scan_event(parser, tSP);
6891 #endif
6892 goto retry;
6893
6894 case '#': /* it's a comment */
6895 /* no magic_comment in shebang line */
6896 if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
6897 if (comment_at_top(parser)) {
6898 set_file_encoding(parser, lex_p, lex_pend);
6899 }
6900 }
6901 lex_p = lex_pend;
6902 #ifdef RIPPER
6903 ripper_dispatch_scan_event(parser, tCOMMENT);
6904 fallthru = TRUE;
6905 #endif
6906 /* fall through */
6907 case '\n':
6908 if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
6909 #ifdef RIPPER
6910 if (!fallthru) {
6911 ripper_dispatch_scan_event(parser, tIGNORED_NL);
6912 }
6913 fallthru = FALSE;
6914 #endif
6915 goto retry;
6916 }
6917 while ((c = nextc())) {
6918 switch (c) {
6919 case ' ': case '\t': case '\f': case '\r':
6920 case '\13': /* '\v' */
6921 space_seen = 1;
6922 break;
6923 case '.': {
6924 if ((c = nextc()) != '.') {
6925 pushback(c);
6926 pushback('.');
6927 goto retry;
6928 }
6929 }
6930 default:
6931 --ruby_sourceline;
6932 lex_nextline = lex_lastline;
6933 case -1: /* EOF no decrement*/
6934 lex_goto_eol(parser);
6935 #ifdef RIPPER
6936 if (c != -1) {
6937 parser->tokp = lex_p;
6938 }
6939 #endif
6940 goto normal_newline;
6941 }
6942 }
6943 normal_newline:
6944 command_start = TRUE;
6945 lex_state = EXPR_BEG;
6946 return '\n';
6947
6948 case '*':
6949 if ((c = nextc()) == '*') {
6950 if ((c = nextc()) == '=') {
6951 set_yylval_id(tPOW);
6952 lex_state = EXPR_BEG;
6953 return tOP_ASGN;
6954 }
6955 pushback(c);
6956 if (IS_SPCARG(c)) {
6957 rb_warning0("`**' interpreted as argument prefix");
6958 c = tDSTAR;
6959 }
6960 else if (IS_BEG()) {
6961 c = tDSTAR;
6962 }
6963 else {
6964 warn_balanced("**", "argument prefix");
6965 c = tPOW;
6966 }
6967 }
6968 else {
6969 if (c == '=') {
6970 set_yylval_id('*');
6971 lex_state = EXPR_BEG;
6972 return tOP_ASGN;
6973 }
6974 pushback(c);
6975 if (IS_SPCARG(c)) {
6976 rb_warning0("`*' interpreted as argument prefix");
6977 c = tSTAR;
6978 }
6979 else if (IS_BEG()) {
6980 c = tSTAR;
6981 }
6982 else {
6983 warn_balanced("*", "argument prefix");
6984 c = '*';
6985 }
6986 }
6987 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
6988 return c;
6989
6990 case '!':
6991 c = nextc();
6992 if (IS_AFTER_OPERATOR()) {
6993 lex_state = EXPR_ARG;
6994 if (c == '@') {
6995 return '!';
6996 }
6997 }
6998 else {
6999 lex_state = EXPR_BEG;
7000 }
7001 if (c == '=') {
7002 return tNEQ;
7003 }
7004 if (c == '~') {
7005 return tNMATCH;
7006 }
7007 pushback(c);
7008 return '!';
7009
7010 case '=':
7011 if (was_bol()) {
7012 /* skip embedded rd document */
7013 if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
7014 #ifdef RIPPER
7015 int first_p = TRUE;
7016
7017 lex_goto_eol(parser);
7018 ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
7019 #endif
7020 for (;;) {
7021 lex_goto_eol(parser);
7022 #ifdef RIPPER
7023 if (!first_p) {
7024 ripper_dispatch_scan_event(parser, tEMBDOC);
7025 }
7026 first_p = FALSE;
7027 #endif
7028 c = nextc();
7029 if (c == -1) {
7030 compile_error(PARSER_ARG "embedded document meets end of file");
7031 return 0;
7032 }
7033 if (c != '=') continue;
7034 if (strncmp(lex_p, "end", 3) == 0 &&
7035 (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
7036 break;
7037 }
7038 }
7039 lex_goto_eol(parser);
7040 #ifdef RIPPER
7041 ripper_dispatch_scan_event(parser, tEMBDOC_END);
7042 #endif
7043 goto retry;
7044 }
7045 }
7046
7047 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7048 if ((c = nextc()) == '=') {
7049 if ((c = nextc()) == '=') {
7050 return tEQQ;
7051 }
7052 pushback(c);
7053 return tEQ;
7054 }
7055 if (c == '~') {
7056 return tMATCH;
7057 }
7058 else if (c == '>') {
7059 return tASSOC;
7060 }
7061 pushback(c);
7062 return '=';
7063
7064 case '<':
7065 last_state = lex_state;
7066 c = nextc();
7067 if (c == '<' &&
7068 !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
7069 !IS_END() &&
7070 (!IS_ARG() || space_seen)) {
7071 int token = heredoc_identifier();
7072 if (token) return token;
7073 }
7074 if (IS_AFTER_OPERATOR()) {
7075 lex_state = EXPR_ARG;
7076 }
7077 else {
7078 if (IS_lex_state(EXPR_CLASS))
7079 command_start = TRUE;
7080 lex_state = EXPR_BEG;
7081 }
7082 if (c == '=') {
7083 if ((c = nextc()) == '>') {
7084 return tCMP;
7085 }
7086 pushback(c);
7087 return tLEQ;
7088 }
7089 if (c == '<') {
7090 if ((c = nextc()) == '=') {
7091 set_yylval_id(tLSHFT);
7092 lex_state = EXPR_BEG;
7093 return tOP_ASGN;
7094 }
7095 pushback(c);
7096 warn_balanced("<<", "here document");
7097 return tLSHFT;
7098 }
7099 pushback(c);
7100 return '<';
7101
7102 case '>':
7103 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7104 if ((c = nextc()) == '=') {
7105 return tGEQ;
7106 }
7107 if (c == '>') {
7108 if ((c = nextc()) == '=') {
7109 set_yylval_id(tRSHFT);
7110 lex_state = EXPR_BEG;
7111 return tOP_ASGN;
7112 }
7113 pushback(c);
7114 return tRSHFT;
7115 }
7116 pushback(c);
7117 return '>';
7118
7119 case '"':
7120 lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
7121 return tSTRING_BEG;
7122
7123 case '`':
7124 if (IS_lex_state(EXPR_FNAME)) {
7125 lex_state = EXPR_ENDFN;
7126 return c;
7127 }
7128 if (IS_lex_state(EXPR_DOT)) {
7129 if (cmd_state)
7130 lex_state = EXPR_CMDARG;
7131 else
7132 lex_state = EXPR_ARG;
7133 return c;
7134 }
7135 lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
7136 return tXSTRING_BEG;
7137
7138 case '\'':
7139 lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
7140 return tSTRING_BEG;
7141
7142 case '?':
7143 if (IS_END()) {
7144 lex_state = EXPR_VALUE;
7145 return '?';
7146 }
7147 c = nextc();
7148 if (c == -1) {
7149 compile_error(PARSER_ARG "incomplete character syntax");
7150 return 0;
7151 }
7152 if (rb_enc_isspace(c, current_enc)) {
7153 if (!IS_ARG()) {
7154 int c2 = 0;
7155 switch (c) {
7156 case ' ':
7157 c2 = 's';
7158 break;
7159 case '\n':
7160 c2 = 'n';
7161 break;
7162 case '\t':
7163 c2 = 't';
7164 break;
7165 case '\v':
7166 c2 = 'v';
7167 break;
7168 case '\r':
7169 c2 = 'r';
7170 break;
7171 case '\f':
7172 c2 = 'f';
7173 break;
7174 }
7175 if (c2) {
7176 rb_warnI("invalid character syntax; use ?\\%c", c2);
7177 }
7178 }
7179 ternary:
7180 pushback(c);
7181 lex_state = EXPR_VALUE;
7182 return '?';
7183 }
7184 newtok();
7185 enc = current_enc;
7186 if (!parser_isascii()) {
7187 if (tokadd_mbchar(c) == -1) return 0;
7188 }
7189 else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
7190 lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
7191 goto ternary;
7192 }
7193 else if (c == '\\') {
7194 if (peek('u')) {
7195 nextc();
7196 c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
7197 if (0x80 <= c) {
7198 tokaddmbc(c, enc);
7199 }
7200 else {
7201 tokadd(c);
7202 }
7203 }
7204 else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
7205 nextc();
7206 if (tokadd_mbchar(c) == -1) return 0;
7207 }
7208 else {
7209 c = read_escape(0, &enc);
7210 tokadd(c);
7211 }
7212 }
7213 else {
7214 tokadd(c);
7215 }
7216 tokfix();
7217 set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
7218 lex_state = EXPR_END;
7219 return tCHAR;
7220
7221 case '&':
7222 if ((c = nextc()) == '&') {
7223 lex_state = EXPR_BEG;
7224 if ((c = nextc()) == '=') {
7225 set_yylval_id(tANDOP);
7226 lex_state = EXPR_BEG;
7227 return tOP_ASGN;
7228 }
7229 pushback(c);
7230 return tANDOP;
7231 }
7232 else if (c == '=') {
7233 set_yylval_id('&');
7234 lex_state = EXPR_BEG;
7235 return tOP_ASGN;
7236 }
7237 pushback(c);
7238 if (IS_SPCARG(c)) {
7239 rb_warning0("`&' interpreted as argument prefix");
7240 c = tAMPER;
7241 }
7242 else if (IS_BEG()) {
7243 c = tAMPER;
7244 }
7245 else {
7246 warn_balanced("&", "argument prefix");
7247 c = '&';
7248 }
7249 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7250 return c;
7251
7252 case '|':
7253 if ((c = nextc()) == '|') {
7254 lex_state = EXPR_BEG;
7255 if ((c = nextc()) == '=') {
7256 set_yylval_id(tOROP);
7257 lex_state = EXPR_BEG;
7258 return tOP_ASGN;
7259 }
7260 pushback(c);
7261 return tOROP;
7262 }
7263 if (c == '=') {
7264 set_yylval_id('|');
7265 lex_state = EXPR_BEG;
7266 return tOP_ASGN;
7267 }
7268 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7269 pushback(c);
7270 return '|';
7271
7272 case '+':
7273 c = nextc();
7274 if (IS_AFTER_OPERATOR()) {
7275 lex_state = EXPR_ARG;
7276 if (c == '@') {
7277 return tUPLUS;
7278 }
7279 pushback(c);
7280 return '+';
7281 }
7282 if (c == '=') {
7283 set_yylval_id('+');
7284 lex_state = EXPR_BEG;
7285 return tOP_ASGN;
7286 }
7287 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7288 lex_state = EXPR_BEG;
7289 pushback(c);
7290 if (c != -1 && ISDIGIT(c)) {
7291 c = '+';
7292 goto start_num;
7293 }
7294 return tUPLUS;
7295 }
7296 lex_state = EXPR_BEG;
7297 pushback(c);
7298 warn_balanced("+", "unary operator");
7299 return '+';
7300
7301 case '-':
7302 c = nextc();
7303 if (IS_AFTER_OPERATOR()) {
7304 lex_state = EXPR_ARG;
7305 if (c == '@') {
7306 return tUMINUS;
7307 }
7308 pushback(c);
7309 return '-';
7310 }
7311 if (c == '=') {
7312 set_yylval_id('-');
7313 lex_state = EXPR_BEG;
7314 return tOP_ASGN;
7315 }
7316 if (c == '>') {
7317 lex_state = EXPR_ENDFN;
7318 return tLAMBDA;
7319 }
7320 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7321 lex_state = EXPR_BEG;
7322 pushback(c);
7323 if (c != -1 && ISDIGIT(c)) {
7324 return tUMINUS_NUM;
7325 }
7326 return tUMINUS;
7327 }
7328 lex_state = EXPR_BEG;
7329 pushback(c);
7330 warn_balanced("-", "unary operator");
7331 return '-';
7332
7333 case '.':
7334 lex_state = EXPR_BEG;
7335 if ((c = nextc()) == '.') {
7336 if ((c = nextc()) == '.') {
7337 return tDOT3;
7338 }
7339 pushback(c);
7340 return tDOT2;
7341 }
7342 pushback(c);
7343 if (c != -1 && ISDIGIT(c)) {
7344 yyerror("no .<digit> floating literal anymore; put 0 before dot");
7345 }
7346 lex_state = EXPR_DOT;
7347 return '.';
7348
7349 start_num:
7350 case '0': case '1': case '2': case '3': case '4':
7351 case '5': case '6': case '7': case '8': case '9':
7352 {
7353 int is_float, seen_point, seen_e, nondigit;
7354
7355 is_float = seen_point = seen_e = nondigit = 0;
7356 lex_state = EXPR_END;
7357 newtok();
7358 if (c == '-' || c == '+') {
7359 tokadd(c);
7360 c = nextc();
7361 }
7362 if (c == '0') {
7363 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
7364 int start = toklen();
7365 c = nextc();
7366 if (c == 'x' || c == 'X') {
7367 /* hexadecimal */
7368 c = nextc();
7369 if (c != -1 && ISXDIGIT(c)) {
7370 do {
7371 if (c == '_') {
7372 if (nondigit) break;
7373 nondigit = c;
7374 continue;
7375 }
7376 if (!ISXDIGIT(c)) break;
7377 nondigit = 0;
7378 tokadd(c);
7379 } while ((c = nextc()) != -1);
7380 }
7381 pushback(c);
7382 tokfix();
7383 if (toklen() == start) {
7384 no_digits();
7385 }
7386 else if (nondigit) goto trailing_uc;
7387 set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
7388 return tINTEGER;
7389 }
7390 if (c == 'b' || c == 'B') {
7391 /* binary */
7392 c = nextc();
7393 if (c == '0' || c == '1') {
7394 do {
7395 if (c == '_') {
7396 if (nondigit) break;
7397 nondigit = c;
7398 continue;
7399 }
7400 if (c != '0' && c != '1') break;
7401 nondigit = 0;
7402 tokadd(c);
7403 } while ((c = nextc()) != -1);
7404 }
7405 pushback(c);
7406 tokfix();
7407 if (toklen() == start) {
7408 no_digits();
7409 }
7410 else if (nondigit) goto trailing_uc;
7411 set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
7412 return tINTEGER;
7413 }
7414 if (c == 'd' || c == 'D') {
7415 /* decimal */
7416 c = nextc();
7417 if (c != -1 && ISDIGIT(c)) {
7418 do {
7419 if (c == '_') {
7420 if (nondigit) break;
7421 nondigit = c;
7422 continue;
7423 }
7424 if (!ISDIGIT(c)) break;
7425 nondigit = 0;
7426 tokadd(c);
7427 } while ((c = nextc()) != -1);
7428 }
7429 pushback(c);
7430 tokfix();
7431 if (toklen() == start) {
7432 no_digits();
7433 }
7434 else if (nondigit) goto trailing_uc;
7435 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7436 return tINTEGER;
7437 }
7438 if (c == '_') {
7439 /* 0_0 */
7440 goto octal_number;
7441 }
7442 if (c == 'o' || c == 'O') {
7443 /* prefixed octal */
7444 c = nextc();
7445 if (c == -1 || c == '_' || !ISDIGIT(c)) {
7446 no_digits();
7447 }
7448 }
7449 if (c >= '0' && c <= '7') {
7450 /* octal */
7451 octal_number:
7452 do {
7453 if (c == '_') {
7454 if (nondigit) break;
7455 nondigit = c;
7456 continue;
7457 }
7458 if (c < '0' || c > '9') break;
7459 if (c > '7') goto invalid_octal;
7460 nondigit = 0;
7461 tokadd(c);
7462 } while ((c = nextc()) != -1);
7463 if (toklen() > start) {
7464 pushback(c);
7465 tokfix();
7466 if (nondigit) goto trailing_uc;
7467 set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
7468 return tINTEGER;
7469 }
7470 if (nondigit) {
7471 pushback(c);
7472 goto trailing_uc;
7473 }
7474 }
7475 if (c > '7' && c <= '9') {
7476 invalid_octal:
7477 yyerror("Invalid octal digit");
7478 }
7479 else if (c == '.' || c == 'e' || c == 'E') {
7480 tokadd('0');
7481 }
7482 else {
7483 pushback(c);
7484 set_yylval_literal(INT2FIX(0));
7485 return tINTEGER;
7486 }
7487 }
7488
7489 for (;;) {
7490 switch (c) {
7491 case '0': case '1': case '2': case '3': case '4':
7492 case '5': case '6': case '7': case '8': case '9':
7493 nondigit = 0;
7494 tokadd(c);
7495 break;
7496
7497 case '.':
7498 if (nondigit) goto trailing_uc;
7499 if (seen_point || seen_e) {
7500 goto decode_num;
7501 }
7502 else {
7503 int c0 = nextc();
7504 if (c0 == -1 || !ISDIGIT(c0)) {
7505 pushback(c0);
7506 goto decode_num;
7507 }
7508 c = c0;
7509 }
7510 tokadd('.');
7511 tokadd(c);
7512 is_float++;
7513 seen_point++;
7514 nondigit = 0;
7515 break;
7516
7517 case 'e':
7518 case 'E':
7519 if (nondigit) {
7520 pushback(c);
7521 c = nondigit;
7522 goto decode_num;
7523 }
7524 if (seen_e) {
7525 goto decode_num;
7526 }
7527 tokadd(c);
7528 seen_e++;
7529 is_float++;
7530 nondigit = c;
7531 c = nextc();
7532 if (c != '-' && c != '+') continue;
7533 tokadd(c);
7534 nondigit = c;
7535 break;
7536
7537 case '_': /* `_' in number just ignored */
7538 if (nondigit) goto decode_num;
7539 nondigit = c;
7540 break;
7541
7542 default:
7543 goto decode_num;
7544 }
7545 c = nextc();
7546 }
7547
7548 decode_num:
7549 pushback(c);
7550 if (nondigit) {
7551 char tmp[30];
7552 trailing_uc:
7553 snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
7554 yyerror(tmp);
7555 }
7556 tokfix();
7557 if (is_float) {
7558 double d = strtod(tok(), 0);
7559 if (errno == ERANGE) {
7560 rb_warningS("Float %s out of range", tok());
7561 errno = 0;
7562 }
7563 set_yylval_literal(DBL2NUM(d));
7564 return tFLOAT;
7565 }
7566 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7567 return tINTEGER;
7568 }
7569
7570 case ')':
7571 case ']':
7572 paren_nest--;
7573 case '}':
7574 COND_LEXPOP();
7575 CMDARG_LEXPOP();
7576 if (c == ')')
7577 lex_state = EXPR_ENDFN;
7578 else
7579 lex_state = EXPR_ENDARG;
7580 if (c == '}') {
7581 if (!brace_nest--) c = tSTRING_DEND;
7582 }
7583 return c;
7584
7585 case ':':
7586 c = nextc();
7587 if (c == ':') {
7588 if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
7589 lex_state = EXPR_BEG;
7590 return tCOLON3;
7591 }
7592 lex_state = EXPR_DOT;
7593 return tCOLON2;
7594 }
7595 if (IS_END() || ISSPACE(c)) {
7596 pushback(c);
7597 warn_balanced(":", "symbol literal");
7598 lex_state = EXPR_BEG;
7599 return ':';
7600 }
7601 switch (c) {
7602 case '\'':
7603 lex_strterm = NEW_STRTERM(str_ssym, c, 0);
7604 break;
7605 case '"':
7606 lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7607 break;
7608 default:
7609 pushback(c);
7610 break;
7611 }
7612 lex_state = EXPR_FNAME;
7613 return tSYMBEG;
7614
7615 case '/':
7616 if (IS_lex_state(EXPR_BEG_ANY)) {
7617 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7618 return tREGEXP_BEG;
7619 }
7620 if ((c = nextc()) == '=') {
7621 set_yylval_id('/');
7622 lex_state = EXPR_BEG;
7623 return tOP_ASGN;
7624 }
7625 pushback(c);
7626 if (IS_SPCARG(c)) {
7627 (void)arg_ambiguous();
7628 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7629 return tREGEXP_BEG;
7630 }
7631 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7632 warn_balanced("/", "regexp literal");
7633 return '/';
7634
7635 case '^':
7636 if ((c = nextc()) == '=') {
7637 set_yylval_id('^');
7638 lex_state = EXPR_BEG;
7639 return tOP_ASGN;
7640 }
7641 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7642 pushback(c);
7643 return '^';
7644
7645 case ';':
7646 lex_state = EXPR_BEG;
7647 command_start = TRUE;
7648 return ';';
7649
7650 case ',':
7651 lex_state = EXPR_BEG;
7652 return ',';
7653
7654 case '~':
7655 if (IS_AFTER_OPERATOR()) {
7656 if ((c = nextc()) != '@') {
7657 pushback(c);
7658 }
7659 lex_state = EXPR_ARG;
7660 }
7661 else {
7662 lex_state = EXPR_BEG;
7663 }
7664 return '~';
7665
7666 case '(':
7667 if (IS_BEG()) {
7668 c = tLPAREN;
7669 }
7670 else if (IS_SPCARG(-1)) {
7671 c = tLPAREN_ARG;
7672 }
7673 paren_nest++;
7674 COND_PUSH(0);
7675 CMDARG_PUSH(0);
7676 lex_state = EXPR_BEG;
7677 return c;
7678
7679 case '[':
7680 paren_nest++;
7681 if (IS_AFTER_OPERATOR()) {
7682 lex_state = EXPR_ARG;
7683 if ((c = nextc()) == ']') {
7684 if ((c = nextc()) == '=') {
7685 return tASET;
7686 }
7687 pushback(c);
7688 return tAREF;
7689 }
7690 pushback(c);
7691 return '[';
7692 }
7693 else if (IS_BEG()) {
7694 c = tLBRACK;
7695 }
7696 else if (IS_ARG() && space_seen) {
7697 c = tLBRACK;
7698 }
7699 lex_state = EXPR_BEG;
7700 COND_PUSH(0);
7701 CMDARG_PUSH(0);
7702 return c;
7703
7704 case '{':
7705 ++brace_nest;
7706 if (lpar_beg && lpar_beg == paren_nest) {
7707 lex_state = EXPR_BEG;
7708 lpar_beg = 0;
7709 --paren_nest;
7710 COND_PUSH(0);
7711 CMDARG_PUSH(0);
7712 return tLAMBEG;
7713 }
7714 if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
7715 c = '{'; /* block (primary) */
7716 else if (IS_lex_state(EXPR_ENDARG))
7717 c = tLBRACE_ARG; /* block (expr) */
7718 else
7719 c = tLBRACE; /* hash */
7720 COND_PUSH(0);
7721 CMDARG_PUSH(0);
7722 lex_state = EXPR_BEG;
7723 if (c != tLBRACE) command_start = TRUE;
7724 return c;
7725
7726 case '\\':
7727 c = nextc();
7728 if (c == '\n') {
7729 space_seen = 1;
7730 #ifdef RIPPER
7731 ripper_dispatch_scan_event(parser, tSP);
7732 #endif
7733 goto retry; /* skip \\n */
7734 }
7735 pushback(c);
7736 return '\\';
7737
7738 case '%':
7739 if (IS_lex_state(EXPR_BEG_ANY)) {
7740 int term;
7741 int paren;
7742
7743 c = nextc();
7744 quotation:
7745 if (c == -1 || !ISALNUM(c)) {
7746 term = c;
7747 c = 'Q';
7748 }
7749 else {
7750 term = nextc();
7751 if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
7752 yyerror("unknown type of %string");
7753 return 0;
7754 }
7755 }
7756 if (c == -1 || term == -1) {
7757 compile_error(PARSER_ARG "unterminated quoted string meets end of file");
7758 return 0;
7759 }
7760 paren = term;
7761 if (term == '(') term = ')';
7762 else if (term == '[') term = ']';
7763 else if (term == '{') term = '}';
7764 else if (term == '<') term = '>';
7765 else paren = 0;
7766
7767 switch (c) {
7768 case 'Q':
7769 lex_strterm = NEW_STRTERM(str_dquote, term, paren);
7770 return tSTRING_BEG;
7771
7772 case 'q':
7773 lex_strterm = NEW_STRTERM(str_squote, term, paren);
7774 return tSTRING_BEG;
7775
7776 case 'W':
7777 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7778 do {c = nextc();} while (ISSPACE(c));
7779 pushback(c);
7780 return tWORDS_BEG;
7781
7782 case 'w':
7783 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7784 do {c = nextc();} while (ISSPACE(c));
7785 pushback(c);
7786 return tQWORDS_BEG;
7787
7788 case 'I':
7789 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7790 do {c = nextc();} while (ISSPACE(c));
7791 pushback(c);
7792 return tSYMBOLS_BEG;
7793
7794 case 'i':
7795 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7796 do {c = nextc();} while (ISSPACE(c));
7797 pushback(c);
7798 return tQSYMBOLS_BEG;
7799
7800 case 'x':
7801 lex_strterm = NEW_STRTERM(str_xquote, term, paren);
7802 return tXSTRING_BEG;
7803
7804 case 'r':
7805 lex_strterm = NEW_STRTERM(str_regexp, term, paren);
7806 return tREGEXP_BEG;
7807
7808 case 's':
7809 lex_strterm = NEW_STRTERM(str_ssym, term, paren);
7810 lex_state = EXPR_FNAME;
7811 return tSYMBEG;
7812
7813 default:
7814 yyerror("unknown type of %string");
7815 return 0;
7816 }
7817 }
7818 if ((c = nextc()) == '=') {
7819 set_yylval_id('%');
7820 lex_state = EXPR_BEG;
7821 return tOP_ASGN;
7822 }
7823 if (IS_SPCARG(c)) {
7824 goto quotation;
7825 }
7826 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7827 pushback(c);
7828 warn_balanced("%%", "string literal");
7829 return '%';
7830
7831 case '$':
7832 lex_state = EXPR_END;
7833 newtok();
7834 c = nextc();
7835 switch (c) {
7836 case '_': /* $_: last read line string */
7837 c = nextc();
7838 if (parser_is_identchar()) {
7839 tokadd('$');
7840 tokadd('_');
7841 break;
7842 }
7843 pushback(c);
7844 c = '_';
7845 /* fall through */
7846 case '~': /* $~: match-data */
7847 case '*': /* $*: argv */
7848 case '$': /* $$: pid */
7849 case '?': /* $?: last status */
7850 case '!': /* $!: error string */
7851 case '@': /* $@: error position */
7852 case '/': /* $/: input record separator */
7853 case '\\': /* $\: output record separator */
7854 case ';': /* $;: field separator */
7855 case ',': /* $,: output field separator */
7856 case '.': /* $.: last read line number */
7857 case '=': /* $=: ignorecase */
7858 case ':': /* $:: load path */
7859 case '<': /* $<: reading filename */
7860 case '>': /* $>: default output handle */
7861 case '\"': /* $": already loaded files */
7862 tokadd('$');
7863 tokadd(c);
7864 tokfix();
7865 set_yylval_name(rb_intern(tok()));
7866 return tGVAR;
7867
7868 case '-':
7869 tokadd('$');
7870 tokadd(c);
7871 c = nextc();
7872 if (parser_is_identchar()) {
7873 if (tokadd_mbchar(c) == -1) return 0;
7874 }
7875 else {
7876 pushback(c);
7877 }
7878 gvar:
7879 tokfix();
7880 set_yylval_name(rb_intern(tok()));
7881 return tGVAR;
7882
7883 case '&': /* $&: last match */
7884 case '`': /* $`: string before last match */
7885 case '\'': /* $': string after last match */
7886 case '+': /* $+: string matches last paren. */
7887 if (IS_lex_state_for(last_state, EXPR_FNAME)) {
7888 tokadd('$');
7889 tokadd(c);
7890 goto gvar;
7891 }
7892 set_yylval_node(NEW_BACK_REF(c));
7893 return tBACK_REF;
7894
7895 case '1': case '2': case '3':
7896 case '4': case '5': case '6':
7897 case '7': case '8': case '9':
7898 tokadd('$');
7899 do {
7900 tokadd(c);
7901 c = nextc();
7902 } while (c != -1 && ISDIGIT(c));
7903 pushback(c);
7904 if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
7905 tokfix();
7906 set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
7907 return tNTH_REF;
7908
7909 default:
7910 if (!parser_is_identchar()) {
7911 pushback(c);
7912 compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
7913 return 0;
7914 }
7915 case '0':
7916 tokadd('$');
7917 }
7918 break;
7919
7920 case '@':
7921 c = nextc();
7922 newtok();
7923 tokadd('@');
7924 if (c == '@') {
7925 tokadd('@');
7926 c = nextc();
7927 }
7928 if (c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
7929 pushback(c);
7930 if (tokidx == 1) {
7931 compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
7932 }
7933 else {
7934 compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
7935 }
7936 return 0;
7937 }
7938 break;
7939
7940 case '_':
7941 if (was_bol() && whole_match_p("__END__", 7, 0)) {
7942 ruby__end__seen = 1;
7943 parser->eofp = Qtrue;
7944 #ifndef RIPPER
7945 return -1;
7946 #else
7947 lex_goto_eol(parser);
7948 ripper_dispatch_scan_event(parser, k__END__);
7949 return 0;
7950 #endif
7951 }
7952 newtok();
7953 break;
7954
7955 default:
7956 if (!parser_is_identchar()) {
7957 rb_compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
7958 goto retry;
7959 }
7960
7961 newtok();
7962 break;
7963 }
7964
7965 mb = ENC_CODERANGE_7BIT;
7966 do {
7967 if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
7968 if (tokadd_mbchar(c) == -1) return 0;
7969 c = nextc();
7970 } while (parser_is_identchar());
7971 switch (tok()[0]) {
7972 case '@': case '$':
7973 pushback(c);
7974 break;
7975 default:
7976 if ((c == '!' || c == '?') && !peek('=')) {
7977 tokadd(c);
7978 }
7979 else {
7980 pushback(c);
7981 }
7982 }
7983 tokfix();
7984
7985 {
7986 int result = 0;
7987
7988 last_state = lex_state;
7989 switch (tok()[0]) {
7990 case '$':
7991 lex_state = EXPR_END;
7992 result = tGVAR;
7993 break;
7994 case '@':
7995 lex_state = EXPR_END;
7996 if (tok()[1] == '@')
7997 result = tCVAR;
7998 else
7999 result = tIVAR;
8000 break;
8001
8002 default:
8003 if (toklast() == '!' || toklast() == '?') {
8004 result = tFID;
8005 }
8006 else {
8007 if (IS_lex_state(EXPR_FNAME)) {
8008 if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
8009 (!peek('=') || (peek_n('>', 1)))) {
8010 result = tIDENTIFIER;
8011 tokadd(c);
8012 tokfix();
8013 }
8014 else {
8015 pushback(c);
8016 }
8017 }
8018 if (result == 0 && ISUPPER(tok()[0])) {
8019 result = tCONSTANT;
8020 }
8021 else {
8022 result = tIDENTIFIER;
8023 }
8024 }
8025
8026 if (IS_LABEL_POSSIBLE()) {
8027 if (IS_LABEL_SUFFIX(0)) {
8028 lex_state = EXPR_BEG;
8029 nextc();
8030 set_yylval_name(TOK_INTERN(!ENC_SINGLE(mb)));
8031 return tLABEL;
8032 }
8033 }
8034 if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
8035 const struct kwtable *kw;
8036
8037 /* See if it is a reserved word. */
8038 kw = rb_reserved_word(tok(), toklen());
8039 if (kw) {
8040 enum lex_state_e state = lex_state;
8041 lex_state = kw->state;
8042 if (state == EXPR_FNAME) {
8043 set_yylval_name(rb_intern(kw->name));
8044 return kw->id[0];
8045 }
8046 if (lex_state == EXPR_BEG) {
8047 command_start = TRUE;
8048 }
8049 if (kw->id[0] == keyword_do) {
8050 if (lpar_beg && lpar_beg == paren_nest) {
8051 lpar_beg = 0;
8052 --paren_nest;
8053 return keyword_do_LAMBDA;
8054 }
8055 if (COND_P()) return keyword_do_cond;
8056 if (CMDARG_P() && state != EXPR_CMDARG)
8057 return keyword_do_block;
8058 if (state & (EXPR_BEG | EXPR_ENDARG))
8059 return keyword_do_block;
8060 return keyword_do;
8061 }
8062 if (state & (EXPR_BEG | EXPR_VALUE))
8063 return kw->id[0];
8064 else {
8065 if (kw->id[0] != kw->id[1])
8066 lex_state = EXPR_BEG;
8067 return kw->id[1];
8068 }
8069 }
8070 }
8071
8072 if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
8073 if (cmd_state) {
8074 lex_state = EXPR_CMDARG;
8075 }
8076 else {
8077 lex_state = EXPR_ARG;
8078 }
8079 }
8080 else if (lex_state == EXPR_FNAME) {
8081 lex_state = EXPR_ENDFN;
8082 }
8083 else {
8084 lex_state = EXPR_END;
8085 }
8086 }
8087 {
8088 ID ident = TOK_INTERN(!ENC_SINGLE(mb));
8089
8090 set_yylval_name(ident);
8091 if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
8092 is_local_id(ident) && lvar_defined(ident)) {
8093 lex_state = EXPR_END;
8094 }
8095 }
8096 return result;
8097 }
8098 }
8099
8100 #if YYPURE
8101 static int
8102 yylex(void *lval, void *p)
8103 #else
8104 yylex(void *p)
8105 #endif
8106 {
8107 struct parser_params *parser = (struct parser_params*)p;
8108 int t;
8109
8110 #if YYPURE
8111 parser->parser_yylval = lval;
8112 parser->parser_yylval->val = Qundef;
8113 #endif
8114 t = parser_yylex(parser);
8115 #ifdef RIPPER
8116 if (!NIL_P(parser->delayed)) {
8117 ripper_dispatch_delayed_token(parser, t);
8118 return t;
8119 }
8120 if (t != 0)
8121 ripper_dispatch_scan_event(parser, t);
8122 #endif
8123
8124 return t;
8125 }
8126
8127 #ifndef RIPPER
8128 static NODE*
8129 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
8130 {
8131 NODE *n = (rb_node_newnode)(type, a0, a1, a2);
8132 nd_set_line(n, ruby_sourceline);
8133 return n;
8134 }
8135
8136 static enum node_type
8137 nodetype(NODE *node) /* for debug */
8138 {
8139 return (enum node_type)nd_type(node);
8140 }
8141
8142 static int
8143 nodeline(NODE *node)
8144 {
8145 return nd_line(node);
8146 }
8147
8148 static NODE*
8149 newline_node(NODE *node)
8150 {
8151 if (node) {
8152 node = remove_begin(node);
8153 node->flags |= NODE_FL_NEWLINE;
8154 }
8155 return node;
8156 }
8157
8158 static void
8159 fixpos(NODE *node, NODE *orig)
8160 {
8161 if (!node) return;
8162 if (!orig) return;
8163 if (orig == (NODE*)1) return;
8164 nd_set_line(node, nd_line(orig));
8165 }
8166
8167 static void
8168 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
8169 {
8170 rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
8171 }
8172 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
8173
8174 static void
8175 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
8176 {
8177 rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
8178 }
8179 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
8180
8181 static NODE*
8182 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
8183 {
8184 NODE *end, *h = head, *nd;
8185
8186 if (tail == 0) return head;
8187
8188 if (h == 0) return tail;
8189 switch (nd_type(h)) {
8190 case NODE_LIT:
8191 case NODE_STR:
8192 case NODE_SELF:
8193 case NODE_TRUE:
8194 case NODE_FALSE:
8195 case NODE_NIL:
8196 parser_warning(h, "unused literal ignored");
8197 return tail;
8198 default:
8199 h = end = NEW_BLOCK(head);
8200 end->nd_end = end;
8201 fixpos(end, head);
8202 head = end;
8203 break;
8204 case NODE_BLOCK:
8205 end = h->nd_end;
8206 break;
8207 }
8208
8209 nd = end->nd_head;
8210 switch (nd_type(nd)) {
8211 case NODE_RETURN:
8212 case NODE_BREAK:
8213 case NODE_NEXT:
8214 case NODE_REDO:
8215 case NODE_RETRY:
8216 if (RTEST(ruby_verbose)) {
8217 parser_warning(tail, "statement not reached");
8218 }
8219 break;
8220
8221 default:
8222 break;
8223 }
8224
8225 if (nd_type(tail) != NODE_BLOCK) {
8226 tail = NEW_BLOCK(tail);
8227 tail->nd_end = tail;
8228 }
8229 end->nd_next = tail;
8230 h->nd_end = tail->nd_end;
8231 return head;
8232 }
8233
8234 /* append item to the list */
8235 static NODE*
8236 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
8237 {
8238 NODE *last;
8239
8240 if (list == 0) return NEW_LIST(item);
8241 if (list->nd_next) {
8242 last = list->nd_next->nd_end;
8243 }
8244 else {
8245 last = list;
8246 }
8247
8248 list->nd_alen += 1;
8249 last->nd_next = NEW_LIST(item);
8250 list->nd_next->nd_end = last->nd_next;
8251 return list;
8252 }
8253
8254 /* concat two lists */
8255 static NODE*
8256 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8257 {
8258 NODE *last;
8259
8260 if (head->nd_next) {
8261 last = head->nd_next->nd_end;
8262 }
8263 else {
8264 last = head;
8265 }
8266
8267 head->nd_alen += tail->nd_alen;
8268 last->nd_next = tail;
8269 if (tail->nd_next) {
8270 head->nd_next->nd_end = tail->nd_next->nd_end;
8271 }
8272 else {
8273 head->nd_next->nd_end = tail;
8274 }
8275
8276 return head;
8277 }
8278
8279 static int
8280 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
8281 {
8282 if (NIL_P(tail)) return 1;
8283 if (!rb_enc_compatible(head, tail)) {
8284 compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
8285 rb_enc_name(rb_enc_get(head)),
8286 rb_enc_name(rb_enc_get(tail)));
8287 rb_str_resize(head, 0);
8288 rb_str_resize(tail, 0);
8289 return 0;
8290 }
8291 rb_str_buf_append(head, tail);
8292 return 1;
8293 }
8294
8295 /* concat two string literals */
8296 static NODE *
8297 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8298 {
8299 enum node_type htype;
8300 NODE *headlast;
8301 VALUE lit;
8302
8303 if (!head) return tail;
8304 if (!tail) return head;
8305
8306 htype = nd_type(head);
8307 if (htype == NODE_EVSTR) {
8308 NODE *node = NEW_DSTR(Qnil);
8309 head = list_append(node, head);
8310 htype = NODE_DSTR;
8311 }
8312 switch (nd_type(tail)) {
8313 case NODE_STR:
8314 if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8315 nd_type(headlast) == NODE_STR) {
8316 htype = NODE_STR;
8317 lit = headlast->nd_lit;
8318 }
8319 else {
8320 lit = head->nd_lit;
8321 }
8322 if (htype == NODE_STR) {
8323 if (!literal_concat0(parser, lit, tail->nd_lit)) {
8324 error:
8325 rb_gc_force_recycle((VALUE)head);
8326 rb_gc_force_recycle((VALUE)tail);
8327 return 0;
8328 }
8329 rb_gc_force_recycle((VALUE)tail);
8330 }
8331 else {
8332 list_append(head, tail);
8333 }
8334 break;
8335
8336 case NODE_DSTR:
8337 if (htype == NODE_STR) {
8338 if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
8339 goto error;
8340 tail->nd_lit = head->nd_lit;
8341 rb_gc_force_recycle((VALUE)head);
8342 head = tail;
8343 }
8344 else if (NIL_P(tail->nd_lit)) {
8345 append:
8346 head->nd_alen += tail->nd_alen - 1;
8347 head->nd_next->nd_end->nd_next = tail->nd_next;
8348 head->nd_next->nd_end = tail->nd_next->nd_end;
8349 rb_gc_force_recycle((VALUE)tail);
8350 }
8351 else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8352 nd_type(headlast) == NODE_STR) {
8353 lit = headlast->nd_lit;
8354 if (!literal_concat0(parser, lit, tail->nd_lit))
8355 goto error;
8356 tail->nd_lit = Qnil;
8357 goto append;
8358 }
8359 else {
8360 nd_set_type(tail, NODE_ARRAY);
8361 tail->nd_head = NEW_STR(tail->nd_lit);
8362 list_concat(head, tail);
8363 }
8364 break;
8365
8366 case NODE_EVSTR:
8367 if (htype == NODE_STR) {
8368 nd_set_type(head, NODE_DSTR);
8369 head->nd_alen = 1;
8370 }
8371 list_append(head, tail);
8372 break;
8373 }
8374 return head;
8375 }
8376
8377 static NODE *
8378 evstr2dstr_gen(struct parser_params *parser, NODE *node)
8379 {
8380 if (nd_type(node) == NODE_EVSTR) {
8381 node = list_append(NEW_DSTR(Qnil), node);
8382 }
8383 return node;
8384 }
8385
8386 static NODE *
8387 new_evstr_gen(struct parser_params *parser, NODE *node)
8388 {
8389 NODE *head = node;
8390
8391 if (node) {
8392 switch (nd_type(node)) {
8393 case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
8394 return node;
8395 }
8396 }
8397 return NEW_EVSTR(head);
8398 }
8399
8400 static NODE *
8401 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
8402 {
8403 value_expr(recv);
8404 value_expr(arg1);
8405 return NEW_CALL(recv, id, NEW_LIST(arg1));
8406 }
8407
8408 static NODE *
8409 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
8410 {
8411 value_expr(recv);
8412 return NEW_CALL(recv, id, 0);
8413 }
8414
8415 static NODE*
8416 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8417 {
8418 value_expr(node1);
8419 value_expr(node2);
8420 if (node1) {
8421 switch (nd_type(node1)) {
8422 case NODE_DREGX:
8423 case NODE_DREGX_ONCE:
8424 return NEW_MATCH2(node1, node2);
8425
8426 case NODE_LIT:
8427 if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
8428 return NEW_MATCH2(node1, node2);
8429 }
8430 }
8431 }
8432
8433 if (node2) {
8434 switch (nd_type(node2)) {
8435 case NODE_DREGX:
8436 case NODE_DREGX_ONCE:
8437 return NEW_MATCH3(node2, node1);
8438
8439 case NODE_LIT:
8440 if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
8441 return NEW_MATCH3(node2, node1);
8442 }
8443 }
8444 }
8445
8446 return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
8447 }
8448
8449 static NODE*
8450 gettable_gen(struct parser_params *parser, ID id)
8451 {
8452 switch (id) {
8453 case keyword_self:
8454 return NEW_SELF();
8455 case keyword_nil:
8456 return NEW_NIL();
8457 case keyword_true:
8458 return NEW_TRUE();
8459 case keyword_false:
8460 return NEW_FALSE();
8461 case keyword__FILE__:
8462 return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
8463 rb_filesystem_encoding()));
8464 case keyword__LINE__:
8465 return NEW_LIT(INT2FIX(tokline));
8466 case keyword__ENCODING__:
8467 return NEW_LIT(rb_enc_from_encoding(current_enc));
8468 }
8469 switch (id_type(id)) {
8470 case ID_LOCAL:
8471 if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
8472 if (local_id(id)) return NEW_LVAR(id);
8473 /* method call without arguments */
8474 return NEW_VCALL(id);
8475 case ID_GLOBAL:
8476 return NEW_GVAR(id);
8477 case ID_INSTANCE:
8478 return NEW_IVAR(id);
8479 case ID_CONST:
8480 return NEW_CONST(id);
8481 case ID_CLASS:
8482 return NEW_CVAR(id);
8483 }
8484 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8485 return 0;
8486 }
8487 #else /* !RIPPER */
8488 static int
8489 id_is_var_gen(struct parser_params *parser, ID id)
8490 {
8491 if (is_notop_id(id)) {
8492 switch (id & ID_SCOPE_MASK) {
8493 case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
8494 return 1;
8495 case ID_LOCAL:
8496 if (dyna_in_block() && dvar_defined(id)) return 1;
8497 if (local_id(id)) return 1;
8498 /* method call without arguments */
8499 return 0;
8500 }
8501 }
8502 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8503 return 0;
8504 }
8505 #endif /* !RIPPER */
8506
8507 #if PARSER_DEBUG
8508 static const char *
8509 lex_state_name(enum lex_state_e state)
8510 {
8511 static const char names[][12] = {
8512 "EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
8513 "EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
8514 "EXPR_VALUE",
8515 };
8516
8517 if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
8518 return names[ffs(state)];
8519 return NULL;
8520 }
8521 #endif
8522
8523 #ifdef RIPPER
8524 static VALUE
8525 assignable_gen(struct parser_params *parser, VALUE lhs)
8526 #else
8527 static NODE*
8528 assignable_gen(struct parser_params *parser, ID id, NODE *val)
8529 #endif
8530 {
8531 #ifdef RIPPER
8532 ID id = get_id(lhs);
8533 # define assignable_result(x) get_value(lhs)
8534 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
8535 #else
8536 # define assignable_result(x) (x)
8537 #endif
8538 if (!id) return assignable_result(0);
8539 switch (id) {
8540 case keyword_self:
8541 yyerror("Can't change the value of self");
8542 goto error;
8543 case keyword_nil:
8544 yyerror("Can't assign to nil");
8545 goto error;
8546 case keyword_true:
8547 yyerror("Can't assign to true");
8548 goto error;
8549 case keyword_false:
8550 yyerror("Can't assign to false");
8551 goto error;
8552 case keyword__FILE__:
8553 yyerror("Can't assign to __FILE__");
8554 goto error;
8555 case keyword__LINE__:
8556 yyerror("Can't assign to __LINE__");
8557 goto error;
8558 case keyword__ENCODING__:
8559 yyerror("Can't assign to __ENCODING__");
8560 goto error;
8561 }
8562 switch (id_type(id)) {
8563 case ID_LOCAL:
8564 if (dyna_in_block()) {
8565 if (dvar_curr(id)) {
8566 return assignable_result(NEW_DASGN_CURR(id, val));
8567 }
8568 else if (dvar_defined(id)) {
8569 return assignable_result(NEW_DASGN(id, val));
8570 }
8571 else if (local_id(id)) {
8572 return assignable_result(NEW_LASGN(id, val));
8573 }
8574 else {
8575 dyna_var(id);
8576 return assignable_result(NEW_DASGN_CURR(id, val));
8577 }
8578 }
8579 else {
8580 if (!local_id(id)) {
8581 local_var(id);
8582 }
8583 return assignable_result(NEW_LASGN(id, val));
8584 }
8585 break;
8586 case ID_GLOBAL:
8587 return assignable_result(NEW_GASGN(id, val));
8588 case ID_INSTANCE:
8589 return assignable_result(NEW_IASGN(id, val));
8590 case ID_CONST:
8591 if (!in_def && !in_single)
8592 return assignable_result(NEW_CDECL(id, val, 0));
8593 yyerror("dynamic constant assignment");
8594 break;
8595 case ID_CLASS:
8596 return assignable_result(NEW_CVASGN(id, val));
8597 default:
8598 compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
8599 }
8600 error:
8601 return assignable_result(0);
8602 #undef assignable_result
8603 #undef parser_yyerror
8604 }
8605
8606 static int
8607 is_private_local_id(ID name)
8608 {
8609 VALUE s;
8610 if (name == idUScore) return 1;
8611 if (!is_local_id(name)) return 0;
8612 s = rb_id2str(name);
8613 if (!s) return 0;
8614 return RSTRING_PTR(s)[0] == '_';
8615 }
8616
8617 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
8618
8619 static ID
8620 shadowing_lvar_gen(struct parser_params *parser, ID name)
8621 {
8622 if (is_private_local_id(name)) return name;
8623 if (dyna_in_block()) {
8624 if (dvar_curr(name)) {
8625 yyerror("duplicated argument name");
8626 }
8627 else if (dvar_defined_get(name) || local_id(name)) {
8628 rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
8629 vtable_add(lvtbl->vars, name);
8630 if (lvtbl->used) {
8631 vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
8632 }
8633 }
8634 }
8635 else {
8636 if (local_id(name)) {
8637 yyerror("duplicated argument name");
8638 }
8639 }
8640 return name;
8641 }
8642
8643 static void
8644 new_bv_gen(struct parser_params *parser, ID name)
8645 {
8646 if (!name) return;
8647 if (!is_local_id(name)) {
8648 compile_error(PARSER_ARG "invalid local variable - %s",
8649 rb_id2name(name));
8650 return;
8651 }
8652 shadowing_lvar(name);
8653 dyna_var(name);
8654 }
8655
8656 #ifndef RIPPER
8657 static NODE *
8658 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
8659 {
8660 if (recv && nd_type(recv) == NODE_SELF)
8661 recv = (NODE *)1;
8662 return NEW_ATTRASGN(recv, tASET, idx);
8663 }
8664
8665 static void
8666 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8667 {
8668 if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
8669 compile_error(PARSER_ARG "both block arg and actual block given");
8670 }
8671 }
8672
8673 ID
8674 rb_id_attrset(ID id)
8675 {
8676 id &= ~ID_SCOPE_MASK;
8677 id |= ID_ATTRSET;
8678 return id;
8679 }
8680
8681 static NODE *
8682 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
8683 {
8684 if (recv && nd_type(recv) == NODE_SELF)
8685 recv = (NODE *)1;
8686 return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
8687 }
8688
8689 static void
8690 rb_backref_error_gen(struct parser_params *parser, NODE *node)
8691 {
8692 switch (nd_type(node)) {
8693 case NODE_NTH_REF:
8694 compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
8695 break;
8696 case NODE_BACK_REF:
8697 compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
8698 break;
8699 }
8700 }
8701
8702 static NODE *
8703 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8704 {
8705 if (!node2) return node1;
8706 switch (nd_type(node1)) {
8707 case NODE_BLOCK_PASS:
8708 if (node1->nd_head)
8709 node1->nd_head = arg_concat(node1->nd_head, node2);
8710 else
8711 node1->nd_head = NEW_LIST(node2);
8712 return node1;
8713 case NODE_ARGSPUSH:
8714 if (nd_type(node2) != NODE_ARRAY) break;
8715 node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
8716 nd_set_type(node1, NODE_ARGSCAT);
8717 return node1;
8718 case NODE_ARGSCAT:
8719 if (nd_type(node2) != NODE_ARRAY ||
8720 nd_type(node1->nd_body) != NODE_ARRAY) break;
8721 node1->nd_body = list_concat(node1->nd_body, node2);
8722 return node1;
8723 }
8724 return NEW_ARGSCAT(node1, node2);
8725 }
8726
8727 static NODE *
8728 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8729 {
8730 if (!node1) return NEW_LIST(node2);
8731 switch (nd_type(node1)) {
8732 case NODE_ARRAY:
8733 return list_append(node1, node2);
8734 case NODE_BLOCK_PASS:
8735 node1->nd_head = arg_append(node1->nd_head, node2);
8736 return node1;
8737 case NODE_ARGSPUSH:
8738 node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
8739 nd_set_type(node1, NODE_ARGSCAT);
8740 return node1;
8741 }
8742 return NEW_ARGSPUSH(node1, node2);
8743 }
8744
8745 static NODE *
8746 splat_array(NODE* node)
8747 {
8748 if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
8749 if (nd_type(node) == NODE_ARRAY) return node;
8750 return 0;
8751 }
8752
8753 static NODE *
8754 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
8755 {
8756 if (!lhs) return 0;
8757
8758 switch (nd_type(lhs)) {
8759 case NODE_GASGN:
8760 case NODE_IASGN:
8761 case NODE_IASGN2:
8762 case NODE_LASGN:
8763 case NODE_DASGN:
8764 case NODE_DASGN_CURR:
8765 case NODE_MASGN:
8766 case NODE_CDECL:
8767 case NODE_CVASGN:
8768 lhs->nd_value = rhs;
8769 break;
8770
8771 case NODE_ATTRASGN:
8772 case NODE_CALL:
8773 lhs->nd_args = arg_append(lhs->nd_args, rhs);
8774 break;
8775
8776 default:
8777 /* should not happen */
8778 break;
8779 }
8780
8781 return lhs;
8782 }
8783
8784 static int
8785 value_expr_gen(struct parser_params *parser, NODE *node)
8786 {
8787 int cond = 0;
8788
8789 if (!node) {
8790 rb_warning0("empty expression");
8791 }
8792 while (node) {
8793 switch (nd_type(node)) {
8794 case NODE_DEFN:
8795 case NODE_DEFS:
8796 parser_warning(node, "void value expression");
8797 return FALSE;
8798
8799 case NODE_RETURN:
8800 case NODE_BREAK:
8801 case NODE_NEXT:
8802 case NODE_REDO:
8803 case NODE_RETRY:
8804 if (!cond) yyerror("void value expression");
8805 /* or "control never reach"? */
8806 return FALSE;
8807
8808 case NODE_BLOCK:
8809 while (node->nd_next) {
8810 node = node->nd_next;
8811 }
8812 node = node->nd_head;
8813 break;
8814
8815 case NODE_BEGIN:
8816 node = node->nd_body;
8817 break;
8818
8819 case NODE_IF:
8820 if (!node->nd_body) {
8821 node = node->nd_else;
8822 break;
8823 }
8824 else if (!node->nd_else) {
8825 node = node->nd_body;
8826 break;
8827 }
8828 if (!value_expr(node->nd_body)) return FALSE;
8829 node = node->nd_else;
8830 break;
8831
8832 case NODE_AND:
8833 case NODE_OR:
8834 cond = 1;
8835 node = node->nd_2nd;
8836 break;
8837
8838 default:
8839 return TRUE;
8840 }
8841 }
8842
8843 return TRUE;
8844 }
8845
8846 static void
8847 void_expr_gen(struct parser_params *parser, NODE *node)
8848 {
8849 const char *useless = 0;
8850
8851 if (!RTEST(ruby_verbose)) return;
8852
8853 if (!node) return;
8854 switch (nd_type(node)) {
8855 case NODE_CALL:
8856 switch (node->nd_mid) {
8857 case '+':
8858 case '-':
8859 case '*':
8860 case '/':
8861 case '%':
8862 case tPOW:
8863 case tUPLUS:
8864 case tUMINUS:
8865 case '|':
8866 case '^':
8867 case '&':
8868 case tCMP:
8869 case '>':
8870 case tGEQ:
8871 case '<':
8872 case tLEQ:
8873 case tEQ:
8874 case tNEQ:
8875 useless = rb_id2name(node->nd_mid);
8876 break;
8877 }
8878 break;
8879
8880 case NODE_LVAR:
8881 case NODE_DVAR:
8882 case NODE_GVAR:
8883 case NODE_IVAR:
8884 case NODE_CVAR:
8885 case NODE_NTH_REF:
8886 case NODE_BACK_REF:
8887 useless = "a variable";
8888 break;
8889 case NODE_CONST:
8890 useless = "a constant";
8891 break;
8892 case NODE_LIT:
8893 case NODE_STR:
8894 case NODE_DSTR:
8895 case NODE_DREGX:
8896 case NODE_DREGX_ONCE:
8897 useless = "a literal";
8898 break;
8899 case NODE_COLON2:
8900 case NODE_COLON3:
8901 useless = "::";
8902 break;
8903 case NODE_DOT2:
8904 useless = "..";
8905 break;
8906 case NODE_DOT3:
8907 useless = "...";
8908 break;
8909 case NODE_SELF:
8910 useless = "self";
8911 break;
8912 case NODE_NIL:
8913 useless = "nil";
8914 break;
8915 case NODE_TRUE:
8916 useless = "true";
8917 break;
8918 case NODE_FALSE:
8919 useless = "false";
8920 break;
8921 case NODE_DEFINED:
8922 useless = "defined?";
8923 break;
8924 }
8925
8926 if (useless) {
8927 int line = ruby_sourceline;
8928
8929 ruby_sourceline = nd_line(node);
8930 rb_warnS("possibly useless use of %s in void context", useless);
8931 ruby_sourceline = line;
8932 }
8933 }
8934
8935 static void
8936 void_stmts_gen(struct parser_params *parser, NODE *node)
8937 {
8938 if (!RTEST(ruby_verbose)) return;
8939 if (!node) return;
8940 if (nd_type(node) != NODE_BLOCK) return;
8941
8942 for (;;) {
8943 if (!node->nd_next) return;
8944 void_expr0(node->nd_head);
8945 node = node->nd_next;
8946 }
8947 }
8948
8949 static NODE *
8950 remove_begin(NODE *node)
8951 {
8952 NODE **n = &node, *n1 = node;
8953 while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
8954 *n = n1 = n1->nd_body;
8955 }
8956 return node;
8957 }
8958
8959 static void
8960 reduce_nodes_gen(struct parser_params *parser, NODE **body)
8961 {
8962 NODE *node = *body;
8963
8964 if (!node) {
8965 *body = NEW_NIL();
8966 return;
8967 }
8968 #define subnodes(n1, n2) \
8969 ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
8970 (!node->n2) ? (body = &node->n1, 1) : \
8971 (reduce_nodes(&node->n1), body = &node->n2, 1))
8972
8973 while (node) {
8974 int newline = (int)(node->flags & NODE_FL_NEWLINE);
8975 switch (nd_type(node)) {
8976 end:
8977 case NODE_NIL:
8978 *body = 0;
8979 return;
8980 case NODE_RETURN:
8981 *body = node = node->nd_stts;
8982 if (newline && node) node->flags |= NODE_FL_NEWLINE;
8983 continue;
8984 case NODE_BEGIN:
8985 *body = node = node->nd_body;
8986 if (newline && node) node->flags |= NODE_FL_NEWLINE;
8987 continue;
8988 case NODE_BLOCK:
8989 body = &node->nd_end->nd_head;
8990 break;
8991 case NODE_IF:
8992 if (subnodes(nd_body, nd_else)) break;
8993 return;
8994 case NODE_CASE:
8995 body = &node->nd_body;
8996 break;
8997 case NODE_WHEN:
8998 if (!subnodes(nd_body, nd_next)) goto end;
8999 break;
9000 case NODE_ENSURE:
9001 if (!subnodes(nd_head, nd_resq)) goto end;
9002 break;
9003 case NODE_RESCUE:
9004 if (node->nd_else) {
9005 body = &node->nd_resq;
9006 break;
9007 }
9008 if (!subnodes(nd_head, nd_resq)) goto end;
9009 break;
9010 default:
9011 return;
9012 }
9013 node = *body;
9014 if (newline && node) node->flags |= NODE_FL_NEWLINE;
9015 }
9016
9017 #undef subnodes
9018 }
9019
9020 static int
9021 is_static_content(NODE *node)
9022 {
9023 if (!node) return 1;
9024 switch (nd_type(node)) {
9025 case NODE_HASH:
9026 if (!(node = node->nd_head)) break;
9027 case NODE_ARRAY:
9028 do {
9029 if (!is_static_content(node->nd_head)) return 0;
9030 } while ((node = node->nd_next) != 0);
9031 case NODE_LIT:
9032 case NODE_STR:
9033 case NODE_NIL:
9034 case NODE_TRUE:
9035 case NODE_FALSE:
9036 case NODE_ZARRAY:
9037 break;
9038 default:
9039 return 0;
9040 }
9041 return 1;
9042 }
9043
9044 static int
9045 assign_in_cond(struct parser_params *parser, NODE *node)
9046 {
9047 switch (nd_type(node)) {
9048 case NODE_MASGN:
9049 yyerror("multiple assignment in conditional");
9050 return 1;
9051
9052 case NODE_LASGN:
9053 case NODE_DASGN:
9054 case NODE_DASGN_CURR:
9055 case NODE_GASGN:
9056 case NODE_IASGN:
9057 break;
9058
9059 default:
9060 return 0;
9061 }
9062
9063 if (!node->nd_value) return 1;
9064 if (is_static_content(node->nd_value)) {
9065 /* reports always */
9066 parser_warn(node->nd_value, "found = in conditional, should be ==");
9067 }
9068 return 1;
9069 }
9070
9071 static void
9072 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9073 {
9074 if (!e_option_supplied(parser)) parser_warn(node, str);
9075 }
9076
9077 static void
9078 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9079 {
9080 if (!e_option_supplied(parser)) parser_warning(node, str);
9081 }
9082
9083 static void
9084 fixup_nodes(NODE **rootnode)
9085 {
9086 NODE *node, *next, *head;
9087
9088 for (node = *rootnode; node; node = next) {
9089 enum node_type type;
9090 VALUE val;
9091
9092 next = node->nd_next;
9093 head = node->nd_head;
9094 rb_gc_force_recycle((VALUE)node);
9095 *rootnode = next;
9096 switch (type = nd_type(head)) {
9097 case NODE_DOT2:
9098 case NODE_DOT3:
9099 val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
9100 type == NODE_DOT3);
9101 rb_gc_force_recycle((VALUE)head->nd_beg);
9102 rb_gc_force_recycle((VALUE)head->nd_end);
9103 nd_set_type(head, NODE_LIT);
9104 head->nd_lit = val;
9105 break;
9106 default:
9107 break;
9108 }
9109 }
9110 }
9111
9112 static NODE *cond0(struct parser_params*,NODE*);
9113
9114 static NODE*
9115 range_op(struct parser_params *parser, NODE *node)
9116 {
9117 enum node_type type;
9118
9119 if (node == 0) return 0;
9120
9121 type = nd_type(node);
9122 value_expr(node);
9123 if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
9124 warn_unless_e_option(parser, node, "integer literal in conditional range");
9125 return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
9126 }
9127 return cond0(parser, node);
9128 }
9129
9130 static int
9131 literal_node(NODE *node)
9132 {
9133 if (!node) return 1; /* same as NODE_NIL */
9134 switch (nd_type(node)) {
9135 case NODE_LIT:
9136 case NODE_STR:
9137 case NODE_DSTR:
9138 case NODE_EVSTR:
9139 case NODE_DREGX:
9140 case NODE_DREGX_ONCE:
9141 case NODE_DSYM:
9142 return 2;
9143 case NODE_TRUE:
9144 case NODE_FALSE:
9145 case NODE_NIL:
9146 return 1;
9147 }
9148 return 0;
9149 }
9150
9151 static NODE*
9152 cond0(struct parser_params *parser, NODE *node)
9153 {
9154 if (node == 0) return 0;
9155 assign_in_cond(parser, node);
9156
9157 switch (nd_type(node)) {
9158 case NODE_DSTR:
9159 case NODE_EVSTR:
9160 case NODE_STR:
9161 rb_warn0("string literal in condition");
9162 break;
9163
9164 case NODE_DREGX:
9165 case NODE_DREGX_ONCE:
9166 warning_unless_e_option(parser, node, "regex literal in condition");
9167 return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
9168
9169 case NODE_AND:
9170 case NODE_OR:
9171 node->nd_1st = cond0(parser, node->nd_1st);
9172 node->nd_2nd = cond0(parser, node->nd_2nd);
9173 break;
9174
9175 case NODE_DOT2:
9176 case NODE_DOT3:
9177 node->nd_beg = range_op(parser, node->nd_beg);
9178 node->nd_end = range_op(parser, node->nd_end);
9179 if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
9180 else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
9181 if (!e_option_supplied(parser)) {
9182 int b = literal_node(node->nd_beg);
9183 int e = literal_node(node->nd_end);
9184 if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
9185 parser_warn(node, "range literal in condition");
9186 }
9187 }
9188 break;
9189
9190 case NODE_DSYM:
9191 parser_warning(node, "literal in condition");
9192 break;
9193
9194 case NODE_LIT:
9195 if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
9196 warn_unless_e_option(parser, node, "regex literal in condition");
9197 nd_set_type(node, NODE_MATCH);
9198 }
9199 else {
9200 parser_warning(node, "literal in condition");
9201 }
9202 default:
9203 break;
9204 }
9205 return node;
9206 }
9207
9208 static NODE*
9209 cond_gen(struct parser_params *parser, NODE *node)
9210 {
9211 if (node == 0) return 0;
9212 return cond0(parser, node);
9213 }
9214
9215 static NODE*
9216 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
9217 {
9218 value_expr(left);
9219 if (left && (enum node_type)nd_type(left) == type) {
9220 NODE *node = left, *second;
9221 while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
9222 node = second;
9223 }
9224 node->nd_2nd = NEW_NODE(type, second, right, 0);
9225 return left;
9226 }
9227 return NEW_NODE(type, left, right, 0);
9228 }
9229
9230 static void
9231 no_blockarg(struct parser_params *parser, NODE *node)
9232 {
9233 if (node && nd_type(node) == NODE_BLOCK_PASS) {
9234 compile_error(PARSER_ARG "block argument should not be given");
9235 }
9236 }
9237
9238 static NODE *
9239 ret_args_gen(struct parser_params *parser, NODE *node)
9240 {
9241 if (node) {
9242 no_blockarg(parser, node);
9243 if (nd_type(node) == NODE_ARRAY) {
9244 if (node->nd_next == 0) {
9245 node = node->nd_head;
9246 }
9247 else {
9248 nd_set_type(node, NODE_VALUES);
9249 }
9250 }
9251 }
9252 return node;
9253 }
9254
9255 static NODE *
9256 new_yield_gen(struct parser_params *parser, NODE *node)
9257 {
9258 if (node) no_blockarg(parser, node);
9259
9260 return NEW_YIELD(node);
9261 }
9262
9263 static NODE*
9264 negate_lit(NODE *node)
9265 {
9266 switch (TYPE(node->nd_lit)) {
9267 case T_FIXNUM:
9268 node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
9269 break;
9270 case T_BIGNUM:
9271 node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
9272 break;
9273 case T_FLOAT:
9274 #if USE_FLONUM
9275 if (FLONUM_P(node->nd_lit)) {
9276 node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
9277 }
9278 else {
9279 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9280 }
9281 #else
9282 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9283 #endif
9284 break;
9285 default:
9286 break;
9287 }
9288 return node;
9289 }
9290
9291 static NODE *
9292 arg_blk_pass(NODE *node1, NODE *node2)
9293 {
9294 if (node2) {
9295 node2->nd_head = node1;
9296 return node2;
9297 }
9298 return node1;
9299 }
9300
9301
9302 static NODE*
9303 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
9304 {
9305 int saved_line = ruby_sourceline;
9306 struct rb_args_info *args = tail->nd_ainfo;
9307
9308 args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
9309 args->pre_init = m ? m->nd_next : 0;
9310
9311 args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
9312 args->post_init = p ? p->nd_next : 0;
9313 args->first_post_arg = p ? p->nd_pid : 0;
9314
9315 args->rest_arg = r;
9316
9317 args->opt_args = o;
9318
9319 ruby_sourceline = saved_line;
9320
9321 return tail;
9322 }
9323
9324 static NODE*
9325 new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
9326 {
9327 int saved_line = ruby_sourceline;
9328 struct rb_args_info *args;
9329 NODE *kw_rest_arg = 0;
9330 NODE *node;
9331
9332 args = ALLOC(struct rb_args_info);
9333 MEMZERO(args, struct rb_args_info, 1);
9334 node = NEW_NODE(NODE_ARGS, 0, 0, args);
9335
9336 args->block_arg = b;
9337 args->kw_args = k;
9338 if (k && !kr) kr = internal_id();
9339 if (kr) {
9340 arg_var(kr);
9341 kw_rest_arg = NEW_DVAR(kr);
9342 }
9343 args->kw_rest_arg = kw_rest_arg;
9344
9345 ruby_sourceline = saved_line;
9346 return node;
9347 }
9348
9349 static NODE*
9350 dsym_node_gen(struct parser_params *parser, NODE *node)
9351 {
9352 VALUE lit;
9353
9354 if (!node) {
9355 return NEW_LIT(ID2SYM(idNULL));
9356 }
9357
9358 switch (nd_type(node)) {
9359 case NODE_DSTR:
9360 nd_set_type(node, NODE_DSYM);
9361 break;
9362 case NODE_STR:
9363 lit = node->nd_lit;
9364 node->nd_lit = ID2SYM(rb_intern_str(lit));
9365 nd_set_type(node, NODE_LIT);
9366 break;
9367 default:
9368 node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
9369 break;
9370 }
9371 return node;
9372 }
9373 #endif /* !RIPPER */
9374
9375 #ifndef RIPPER
9376 static NODE *
9377 new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9378 {
9379 NODE *asgn;
9380
9381 if (lhs) {
9382 ID vid = lhs->nd_vid;
9383 if (op == tOROP) {
9384 lhs->nd_value = rhs;
9385 asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
9386 if (is_asgn_or_id(vid)) {
9387 asgn->nd_aid = vid;
9388 }
9389 }
9390 else if (op == tANDOP) {
9391 lhs->nd_value = rhs;
9392 asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
9393 }
9394 else {
9395 asgn = lhs;
9396 asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
9397 }
9398 }
9399 else {
9400 asgn = NEW_BEGIN(0);
9401 }
9402 return asgn;
9403 }
9404
9405 static NODE *
9406 new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
9407 {
9408 NODE *asgn;
9409
9410 if (op == tOROP) {
9411 op = 0;
9412 }
9413 else if (op == tANDOP) {
9414 op = 1;
9415 }
9416 asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
9417 fixpos(asgn, lhs);
9418 return asgn;
9419 }
9420
9421 static NODE *
9422 new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9423 {
9424 NODE *asgn;
9425
9426 if (op == tOROP) {
9427 op = 0;
9428 }
9429 else if (op == tANDOP) {
9430 op = 1;
9431 }
9432 if (lhs) {
9433 asgn = NEW_OP_CDECL(lhs, op, rhs);
9434 }
9435 else {
9436 asgn = NEW_BEGIN(0);
9437 }
9438 fixpos(asgn, lhs);
9439 return asgn;
9440 }
9441 #else
9442 static VALUE
9443 new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
9444 {
9445 return dispatch3(opassign, lhs, op, rhs);
9446 }
9447
9448 static VALUE
9449 new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
9450 {
9451 VALUE recv = dispatch3(field, lhs, type, attr);
9452 return dispatch3(opassign, recv, op, rhs);
9453 }
9454 #endif
9455
9456 static void
9457 warn_unused_var(struct parser_params *parser, struct local_vars *local)
9458 {
9459 int i, cnt;
9460 ID *v, *u;
9461
9462 if (!local->used) return;
9463 v = local->vars->tbl;
9464 u = local->used->tbl;
9465 cnt = local->used->pos;
9466 if (cnt != local->vars->pos) {
9467 rb_bug("local->used->pos != local->vars->pos");
9468 }
9469 for (i = 0; i < cnt; ++i) {
9470 if (!v[i] || (u[i] & LVAR_USED)) continue;
9471 if (is_private_local_id(v[i])) continue;
9472 rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
9473 }
9474 }
9475
9476 static void
9477 local_push_gen(struct parser_params *parser, int inherit_dvars)
9478 {
9479 struct local_vars *local;
9480
9481 local = ALLOC(struct local_vars);
9482 local->prev = lvtbl;
9483 local->args = vtable_alloc(0);
9484 local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
9485 local->used = !(inherit_dvars &&
9486 (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
9487 RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
9488 lvtbl = local;
9489 }
9490
9491 static void
9492 local_pop_gen(struct parser_params *parser)
9493 {
9494 struct local_vars *local = lvtbl->prev;
9495 if (lvtbl->used) {
9496 warn_unused_var(parser, lvtbl);
9497 vtable_free(lvtbl->used);
9498 }
9499 vtable_free(lvtbl->args);
9500 vtable_free(lvtbl->vars);
9501 xfree(lvtbl);
9502 lvtbl = local;
9503 }
9504
9505 #ifndef RIPPER
9506 static ID*
9507 vtable_tblcpy(ID *buf, const struct vtable *src)
9508 {
9509 int i, cnt = vtable_size(src);
9510
9511 if (cnt > 0) {
9512 buf[0] = cnt;
9513 for (i = 0; i < cnt; i++) {
9514 buf[i] = src->tbl[i];
9515 }
9516 return buf;
9517 }
9518 return 0;
9519 }
9520
9521 static ID*
9522 local_tbl_gen(struct parser_params *parser)
9523 {
9524 int cnt = vtable_size(lvtbl->args) + vtable_size(lvtbl->vars);
9525 ID *buf;
9526
9527 if (cnt <= 0) return 0;
9528 buf = ALLOC_N(ID, cnt + 1);
9529 vtable_tblcpy(buf+1, lvtbl->args);
9530 vtable_tblcpy(buf+vtable_size(lvtbl->args)+1, lvtbl->vars);
9531 buf[0] = cnt;
9532 return buf;
9533 }
9534 #endif
9535
9536 static int
9537 arg_var_gen(struct parser_params *parser, ID id)
9538 {
9539 vtable_add(lvtbl->args, id);
9540 return vtable_size(lvtbl->args) - 1;
9541 }
9542
9543 static int
9544 local_var_gen(struct parser_params *parser, ID id)
9545 {
9546 vtable_add(lvtbl->vars, id);
9547 if (lvtbl->used) {
9548 vtable_add(lvtbl->used, (ID)ruby_sourceline);
9549 }
9550 return vtable_size(lvtbl->vars) - 1;
9551 }
9552
9553 static int
9554 local_id_gen(struct parser_params *parser, ID id)
9555 {
9556 struct vtable *vars, *args, *used;
9557
9558 vars = lvtbl->vars;
9559 args = lvtbl->args;
9560 used = lvtbl->used;
9561
9562 while (vars && POINTER_P(vars->prev)) {
9563 vars = vars->prev;
9564 args = args->prev;
9565 if (used) used = used->prev;
9566 }
9567
9568 if (vars && vars->prev == DVARS_INHERIT) {
9569 return rb_local_defined(id);
9570 }
9571 else if (vtable_included(args, id)) {
9572 return 1;
9573 }
9574 else {
9575 int i = vtable_included(vars, id);
9576 if (i && used) used->tbl[i-1] |= LVAR_USED;
9577 return i != 0;
9578 }
9579 }
9580
9581 static const struct vtable *
9582 dyna_push_gen(struct parser_params *parser)
9583 {
9584 lvtbl->args = vtable_alloc(lvtbl->args);
9585 lvtbl->vars = vtable_alloc(lvtbl->vars);
9586 if (lvtbl->used) {
9587 lvtbl->used = vtable_alloc(lvtbl->used);
9588 }
9589 return lvtbl->args;
9590 }
9591
9592 static void
9593 dyna_pop_1(struct parser_params *parser)
9594 {
9595 struct vtable *tmp;
9596
9597 if ((tmp = lvtbl->used) != 0) {
9598 warn_unused_var(parser, lvtbl);
9599 lvtbl->used = lvtbl->used->prev;
9600 vtable_free(tmp);
9601 }
9602 tmp = lvtbl->args;
9603 lvtbl->args = lvtbl->args->prev;
9604 vtable_free(tmp);
9605 tmp = lvtbl->vars;
9606 lvtbl->vars = lvtbl->vars->prev;
9607 vtable_free(tmp);
9608 }
9609
9610 static void
9611 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
9612 {
9613 while (lvtbl->args != lvargs) {
9614 dyna_pop_1(parser);
9615 if (!lvtbl->args) {
9616 struct local_vars *local = lvtbl->prev;
9617 xfree(lvtbl);
9618 lvtbl = local;
9619 }
9620 }
9621 dyna_pop_1(parser);
9622 }
9623
9624 static int
9625 dyna_in_block_gen(struct parser_params *parser)
9626 {
9627 return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
9628 }
9629
9630 static int
9631 dvar_defined_gen(struct parser_params *parser, ID id, int get)
9632 {
9633 struct vtable *vars, *args, *used;
9634 int i;
9635
9636 args = lvtbl->args;
9637 vars = lvtbl->vars;
9638 used = lvtbl->used;
9639
9640 while (POINTER_P(vars)) {
9641 if (vtable_included(args, id)) {
9642 return 1;
9643 }
9644 if ((i = vtable_included(vars, id)) != 0) {
9645 if (used) used->tbl[i-1] |= LVAR_USED;
9646 return 1;
9647 }
9648 args = args->prev;
9649 vars = vars->prev;
9650 if (get) used = 0;
9651 if (used) used = used->prev;
9652 }
9653
9654 if (vars == DVARS_INHERIT) {
9655 return rb_dvar_defined(id);
9656 }
9657
9658 return 0;
9659 }
9660
9661 static int
9662 dvar_curr_gen(struct parser_params *parser, ID id)
9663 {
9664 return (vtable_included(lvtbl->args, id) ||
9665 vtable_included(lvtbl->vars, id));
9666 }
9667
9668 #ifndef RIPPER
9669 static void
9670 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
9671 {
9672 int c = RE_OPTION_ENCODING_IDX(options);
9673
9674 if (c) {
9675 int opt, idx;
9676 rb_char_to_option_kcode(c, &opt, &idx);
9677 if (idx != ENCODING_GET(str) &&
9678 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9679 goto error;
9680 }
9681 ENCODING_SET(str, idx);
9682 }
9683 else if (RE_OPTION_ENCODING_NONE(options)) {
9684 if (!ENCODING_IS_ASCII8BIT(str) &&
9685 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9686 c = 'n';
9687 goto error;
9688 }
9689 rb_enc_associate(str, rb_ascii8bit_encoding());
9690 }
9691 else if (current_enc == rb_usascii_encoding()) {
9692 if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9693 /* raise in re.c */
9694 rb_enc_associate(str, rb_usascii_encoding());
9695 }
9696 else {
9697 rb_enc_associate(str, rb_ascii8bit_encoding());
9698 }
9699 }
9700 return;
9701
9702 error:
9703 compile_error(PARSER_ARG
9704 "regexp encoding option '%c' differs from source encoding '%s'",
9705 c, rb_enc_name(rb_enc_get(str)));
9706 }
9707
9708 static int
9709 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
9710 {
9711 VALUE err;
9712 reg_fragment_setenc(str, options);
9713 err = rb_reg_check_preprocess(str);
9714 if (err != Qnil) {
9715 err = rb_obj_as_string(err);
9716 compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
9717 RB_GC_GUARD(err);
9718 return 0;
9719 }
9720 return 1;
9721 }
9722
9723 typedef struct {
9724 struct parser_params* parser;
9725 rb_encoding *enc;
9726 NODE *succ_block;
9727 NODE *fail_block;
9728 int num;
9729 } reg_named_capture_assign_t;
9730
9731 static int
9732 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
9733 int back_num, int *back_refs, OnigRegex regex, void *arg0)
9734 {
9735 reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
9736 struct parser_params* parser = arg->parser;
9737 rb_encoding *enc = arg->enc;
9738 long len = name_end - name;
9739 const char *s = (const char *)name;
9740 ID var;
9741
9742 arg->num++;
9743
9744 if (arg->succ_block == 0) {
9745 arg->succ_block = NEW_BEGIN(0);
9746 arg->fail_block = NEW_BEGIN(0);
9747 }
9748
9749 if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
9750 (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
9751 !rb_enc_symname2_p(s, len, enc)) {
9752 return ST_CONTINUE;
9753 }
9754 var = rb_intern3(s, len, enc);
9755 if (dvar_defined(var) || local_id(var)) {
9756 rb_warningS("named capture conflicts a local variable - %s",
9757 rb_id2name(var));
9758 }
9759 arg->succ_block = block_append(arg->succ_block,
9760 newline_node(node_assign(assignable(var,0),
9761 NEW_CALL(
9762 gettable(rb_intern("$~")),
9763 idAREF,
9764 NEW_LIST(NEW_LIT(ID2SYM(var))))
9765 )));
9766 arg->fail_block = block_append(arg->fail_block,
9767 newline_node(node_assign(assignable(var,0), NEW_LIT(Qnil))));
9768 return ST_CONTINUE;
9769 }
9770
9771 static NODE *
9772 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
9773 {
9774 reg_named_capture_assign_t arg;
9775
9776 arg.parser = parser;
9777 arg.enc = rb_enc_get(regexp);
9778 arg.succ_block = 0;
9779 arg.fail_block = 0;
9780 arg.num = 0;
9781 onig_foreach_name(RREGEXP(regexp)->ptr, reg_named_capture_assign_iter, (void*)&arg);
9782
9783 if (arg.num == 0)
9784 return match;
9785
9786 return
9787 block_append(
9788 newline_node(match),
9789 NEW_IF(gettable(rb_intern("$~")),
9790 block_append(
9791 newline_node(arg.succ_block),
9792 newline_node(
9793 NEW_CALL(
9794 gettable(rb_intern("$~")),
9795 rb_intern("begin"),
9796 NEW_LIST(NEW_LIT(INT2FIX(0)))))),
9797 block_append(
9798 newline_node(arg.fail_block),
9799 newline_node(
9800 NEW_LIT(Qnil)))));
9801 }
9802
9803 static VALUE
9804 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
9805 {
9806 VALUE re;
9807 VALUE err;
9808
9809 reg_fragment_setenc(str, options);
9810 err = rb_errinfo();
9811 re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
9812 if (NIL_P(re)) {
9813 ID mesg = rb_intern("mesg");
9814 VALUE m = rb_attr_get(rb_errinfo(), mesg);
9815 rb_set_errinfo(err);
9816 if (!NIL_P(err)) {
9817 rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
9818 }
9819 else {
9820 compile_error(PARSER_ARG "%s", RSTRING_PTR(m));
9821 }
9822 return Qnil;
9823 }
9824 return re;
9825 }
9826
9827 void
9828 rb_gc_mark_parser(void)
9829 {
9830 }
9831
9832 NODE*
9833 rb_parser_append_print(VALUE vparser, NODE *node)
9834 {
9835 NODE *prelude = 0;
9836 NODE *scope = node;
9837 struct parser_params *parser;
9838
9839 if (!node) return node;
9840
9841 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9842
9843 node = node->nd_body;
9844
9845 if (nd_type(node) == NODE_PRELUDE) {
9846 prelude = node;
9847 node = node->nd_body;
9848 }
9849
9850 node = block_append(node,
9851 NEW_FCALL(rb_intern("print"),
9852 NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
9853 if (prelude) {
9854 prelude->nd_body = node;
9855 scope->nd_body = prelude;
9856 }
9857 else {
9858 scope->nd_body = node;
9859 }
9860
9861 return scope;
9862 }
9863
9864 NODE *
9865 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
9866 {
9867 NODE *prelude = 0;
9868 NODE *scope = node;
9869 struct parser_params *parser;
9870
9871 if (!node) return node;
9872
9873 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9874
9875 node = node->nd_body;
9876
9877 if (nd_type(node) == NODE_PRELUDE) {
9878 prelude = node;
9879 node = node->nd_body;
9880 }
9881 if (split) {
9882 node = block_append(NEW_GASGN(rb_intern("$F"),
9883 NEW_CALL(NEW_GVAR(rb_intern("$_")),
9884 rb_intern("split"), 0)),
9885 node);
9886 }
9887 if (chop) {
9888 node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
9889 rb_intern("chop!"), 0), node);
9890 }
9891
9892 node = NEW_OPT_N(node);
9893
9894 if (prelude) {
9895 prelude->nd_body = node;
9896 scope->nd_body = prelude;
9897 }
9898 else {
9899 scope->nd_body = node;
9900 }
9901
9902 return scope;
9903 }
9904
9905 static const struct {
9906 ID token;
9907 const char *name;
9908 } op_tbl[] = {
9909 {tDOT2, ".."},
9910 {tDOT3, "..."},
9911 {'+', "+(binary)"},
9912 {'-', "-(binary)"},
9913 {tPOW, "**"},
9914 {tDSTAR, "**"},
9915 {tUPLUS, "+@"},
9916 {tUMINUS, "-@"},
9917 {tCMP, "<=>"},
9918 {tGEQ, ">="},
9919 {tLEQ, "<="},
9920 {tEQ, "=="},
9921 {tEQQ, "==="},
9922 {tNEQ, "!="},
9923 {tMATCH, "=~"},
9924 {tNMATCH, "!~"},
9925 {tAREF, "[]"},
9926 {tASET, "[]="},
9927 {tLSHFT, "<<"},
9928 {tRSHFT, ">>"},
9929 {tCOLON2, "::"},
9930 };
9931
9932 #define op_tbl_count numberof(op_tbl)
9933
9934 #ifndef ENABLE_SELECTOR_NAMESPACE
9935 #define ENABLE_SELECTOR_NAMESPACE 0
9936 #endif
9937
9938 static struct symbols {
9939 ID last_id;
9940 st_table *sym_id;
9941 st_table *id_str;
9942 #if ENABLE_SELECTOR_NAMESPACE
9943 st_table *ivar2_id;
9944 st_table *id_ivar2;
9945 #endif
9946 VALUE op_sym[tLAST_OP_ID];
9947 } global_symbols = {tLAST_TOKEN};
9948
9949 static const struct st_hash_type symhash = {
9950 rb_str_hash_cmp,
9951 rb_str_hash,
9952 };
9953
9954 #if ENABLE_SELECTOR_NAMESPACE
9955 struct ivar2_key {
9956 ID id;
9957 VALUE klass;
9958 };
9959
9960 static int
9961 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
9962 {
9963 if (key1->id == key2->id && key1->klass == key2->klass) {
9964 return 0;
9965 }
9966 return 1;
9967 }
9968
9969 static int
9970 ivar2_hash(struct ivar2_key *key)
9971 {
9972 return (key->id << 8) ^ (key->klass >> 2);
9973 }
9974
9975 static const struct st_hash_type ivar2_hash_type = {
9976 ivar2_cmp,
9977 ivar2_hash,
9978 };
9979 #endif
9980
9981 void
9982 Init_sym(void)
9983 {
9984 global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
9985 global_symbols.id_str = st_init_numtable_with_size(1000);
9986 #if ENABLE_SELECTOR_NAMESPACE
9987 global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
9988 global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
9989 #endif
9990
9991 (void)nodetype;
9992 (void)nodeline;
9993 #if PARSER_DEBUG
9994 (void)lex_state_name(-1);
9995 #endif
9996
9997 Init_id();
9998 }
9999
10000 void
10001 rb_gc_mark_symbols(void)
10002 {
10003 rb_mark_tbl(global_symbols.id_str);
10004 rb_gc_mark_locations(global_symbols.op_sym,
10005 global_symbols.op_sym + numberof(global_symbols.op_sym));
10006 }
10007 #endif /* !RIPPER */
10008
10009 static ID
10010 internal_id_gen(struct parser_params *parser)
10011 {
10012 ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
10013 id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
10014 return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
10015 }
10016
10017 #ifndef RIPPER
10018 static int
10019 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
10020 {
10021 int mb = 0;
10022
10023 if (m >= e) return 0;
10024 if (is_global_name_punct(*m)) {
10025 ++m;
10026 }
10027 else if (*m == '-') {
10028 ++m;
10029 if (m < e && is_identchar(m, e, enc)) {
10030 if (!ISASCII(*m)) mb = 1;
10031 m += rb_enc_mbclen(m, e, enc);
10032 }
10033 }
10034 else {
10035 if (!rb_enc_isdigit(*m, enc)) return 0;
10036 do {
10037 if (!ISASCII(*m)) mb = 1;
10038 ++m;
10039 } while (m < e && rb_enc_isdigit(*m, enc));
10040 }
10041 return m == e ? mb + 1 : 0;
10042 }
10043
10044 int
10045 rb_symname_p(const char *name)
10046 {
10047 return rb_enc_symname_p(name, rb_ascii8bit_encoding());
10048 }
10049
10050 int
10051 rb_enc_symname_p(const char *name, rb_encoding *enc)
10052 {
10053 return rb_enc_symname2_p(name, strlen(name), enc);
10054 }
10055
10056 static int
10057 rb_enc_symname_type(const char *name, long len, rb_encoding *enc)
10058 {
10059 const char *m = name;
10060 const char *e = m + len;
10061 int type = ID_JUNK;
10062
10063 if (!m || len <= 0) return -1;
10064 switch (*m) {
10065 case '\0':
10066 return -1;
10067
10068 case '$':
10069 type = ID_GLOBAL;
10070 if (is_special_global_name(++m, e, enc)) return type;
10071 goto id;
10072
10073 case '@':
10074 type = ID_INSTANCE;
10075 if (*++m == '@') {
10076 ++m;
10077 type = ID_CLASS;
10078 }
10079 goto id;
10080
10081 case '<':
10082 switch (*++m) {
10083 case '<': ++m; break;
10084 case '=': if (*++m == '>') ++m; break;
10085 default: break;
10086 }
10087 break;
10088
10089 case '>':
10090 switch (*++m) {
10091 case '>': case '=': ++m; break;
10092 }
10093 break;
10094
10095 case '=':
10096 switch (*++m) {
10097 case '~': ++m; break;
10098 case '=': if (*++m == '=') ++m; break;
10099 default: return -1;
10100 }
10101 break;
10102
10103 case '*':
10104 if (*++m == '*') ++m;
10105 break;
10106
10107 case '+': case '-':
10108 if (*++m == '@') ++m;
10109 break;
10110
10111 case '|': case '^': case '&': case '/': case '%': case '~': case '`':
10112 ++m;
10113 break;
10114
10115 case '[':
10116 if (*++m != ']') return -1;
10117 if (*++m == '=') ++m;
10118 break;
10119
10120 case '!':
10121 if (len == 1) return ID_JUNK;
10122 switch (*++m) {
10123 case '=': case '~': ++m; break;
10124 default: return -1;
10125 }
10126 break;
10127
10128 default:
10129 type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
10130 id:
10131 if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
10132 return -1;
10133 while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
10134 switch (*m) {
10135 case '!': case '?':
10136 if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
10137 type = ID_JUNK;
10138 ++m;
10139 break;
10140 case '=':
10141 if (type != ID_CONST && type != ID_LOCAL) return -1;
10142 type = ID_ATTRSET;
10143 ++m;
10144 break;
10145 }
10146 break;
10147 }
10148 return m == e ? type : -1;
10149 }
10150
10151 int
10152 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
10153 {
10154 return rb_enc_symname_type(name, len, enc) != -1;
10155 }
10156
10157 static int
10158 rb_str_symname_type(VALUE name)
10159 {
10160 const char *ptr = StringValuePtr(name);
10161 long len = RSTRING_LEN(name);
10162 int type = rb_enc_symname_type(ptr, len, rb_enc_get(name));
10163 RB_GC_GUARD(name);
10164 return type;
10165 }
10166
10167 static ID
10168 register_symid(ID id, const char *name, long len, rb_encoding *enc)
10169 {
10170 VALUE str = rb_enc_str_new(name, len, enc);
10171 return register_symid_str(id, str);
10172 }
10173
10174 static ID
10175 register_symid_str(ID id, VALUE str)
10176 {
10177 OBJ_FREEZE(str);
10178 st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
10179 st_add_direct(global_symbols.id_str, id, (st_data_t)str);
10180 return id;
10181 }
10182
10183 static int
10184 sym_check_asciionly(VALUE str)
10185 {
10186 if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
10187 switch (rb_enc_str_coderange(str)) {
10188 case ENC_CODERANGE_BROKEN:
10189 rb_raise(rb_eEncodingError, "invalid encoding symbol");
10190 case ENC_CODERANGE_7BIT:
10191 return TRUE;
10192 }
10193 return FALSE;
10194 }
10195
10196 /*
10197 * _str_ itself will be registered at the global symbol table. _str_
10198 * can be modified before the registration, since the encoding will be
10199 * set to ASCII-8BIT if it is a special global name.
10200 */
10201 static ID intern_str(VALUE str);
10202
10203 ID
10204 rb_intern3(const char *name, long len, rb_encoding *enc)
10205 {
10206 VALUE str;
10207 st_data_t data;
10208 struct RString fake_str;
10209 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10210 fake_str.basic.klass = rb_cString;
10211 fake_str.as.heap.len = len;
10212 fake_str.as.heap.ptr = (char *)name;
10213 fake_str.as.heap.aux.capa = len;
10214 str = (VALUE)&fake_str;
10215 rb_enc_associate(str, enc);
10216 OBJ_FREEZE(str);
10217
10218 if (st_lookup(global_symbols.sym_id, str, &data))
10219 return (ID)data;
10220
10221 str = rb_enc_str_new(name, len, enc); /* make true string */
10222 return intern_str(str);
10223 }
10224
10225 static ID
10226 intern_str(VALUE str)
10227 {
10228 const char *name, *m, *e;
10229 long len, last;
10230 rb_encoding *enc, *symenc;
10231 unsigned char c;
10232 ID id;
10233 int mb;
10234
10235 RSTRING_GETMEM(str, name, len);
10236 m = name;
10237 e = m + len;
10238 enc = rb_enc_get(str);
10239 symenc = enc;
10240
10241 if (rb_cString && !rb_enc_asciicompat(enc)) {
10242 id = ID_JUNK;
10243 goto new_id;
10244 }
10245 last = len-1;
10246 id = 0;
10247 switch (*m) {
10248 case '$':
10249 id |= ID_GLOBAL;
10250 if ((mb = is_special_global_name(++m, e, enc)) != 0) {
10251 if (!--mb) symenc = rb_usascii_encoding();
10252 goto new_id;
10253 }
10254 break;
10255 case '@':
10256 if (m[1] == '@') {
10257 m++;
10258 id |= ID_CLASS;
10259 }
10260 else {
10261 id |= ID_INSTANCE;
10262 }
10263 m++;
10264 break;
10265 default:
10266 c = m[0];
10267 if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
10268 /* operators */
10269 int i;
10270
10271 if (len == 1) {
10272 id = c;
10273 goto id_register;
10274 }
10275 for (i = 0; i < op_tbl_count; i++) {
10276 if (*op_tbl[i].name == *m &&
10277 strcmp(op_tbl[i].name, m) == 0) {
10278 id = op_tbl[i].token;
10279 goto id_register;
10280 }
10281 }
10282 }
10283
10284 if (m[last] == '=') {
10285 /* attribute assignment */
10286 id = rb_intern3(name, last, enc);
10287 if (id > tLAST_OP_ID && !is_attrset_id(id)) {
10288 enc = rb_enc_get(rb_id2str(id));
10289 id = rb_id_attrset(id);
10290 goto id_register;
10291 }
10292 id = ID_ATTRSET;
10293 }
10294 else if (rb_enc_isupper(m[0], enc)) {
10295 id = ID_CONST;
10296 }
10297 else {
10298 id = ID_LOCAL;
10299 }
10300 break;
10301 }
10302 if (!rb_enc_isdigit(*m, enc)) {
10303 while (m <= name + last && is_identchar(m, e, enc)) {
10304 if (ISASCII(*m)) {
10305 m++;
10306 }
10307 else {
10308 m += rb_enc_mbclen(m, e, enc);
10309 }
10310 }
10311 }
10312 if (m - name < len) id = ID_JUNK;
10313 if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
10314 new_id:
10315 if (symenc != enc) rb_enc_associate(str, symenc);
10316 if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
10317 if (len > 20) {
10318 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
10319 name);
10320 }
10321 else {
10322 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
10323 (int)len, name);
10324 }
10325 }
10326 id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
10327 id_register:
10328 return register_symid_str(id, str);
10329 }
10330
10331 ID
10332 rb_intern2(const char *name, long len)
10333 {
10334 return rb_intern3(name, len, rb_usascii_encoding());
10335 }
10336
10337 #undef rb_intern
10338 ID
10339 rb_intern(const char *name)
10340 {
10341 return rb_intern2(name, strlen(name));
10342 }
10343
10344 ID
10345 rb_intern_str(VALUE str)
10346 {
10347 st_data_t id;
10348
10349 if (st_lookup(global_symbols.sym_id, str, &id))
10350 return (ID)id;
10351 return intern_str(rb_str_dup(str));
10352 }
10353
10354 VALUE
10355 rb_id2str(ID id)
10356 {
10357 st_data_t data;
10358
10359 if (id < tLAST_TOKEN) {
10360 int i = 0;
10361
10362 if (id < INT_MAX && rb_ispunct((int)id)) {
10363 VALUE str = global_symbols.op_sym[i = (int)id];
10364 if (!str) {
10365 char name[2];
10366 name[0] = (char)id;
10367 name[1] = 0;
10368 str = rb_usascii_str_new(name, 1);
10369 OBJ_FREEZE(str);
10370 global_symbols.op_sym[i] = str;
10371 }
10372 return str;
10373 }
10374 for (i = 0; i < op_tbl_count; i++) {
10375 if (op_tbl[i].token == id) {
10376 VALUE str = global_symbols.op_sym[i];
10377 if (!str) {
10378 str = rb_usascii_str_new2(op_tbl[i].name);
10379 OBJ_FREEZE(str);
10380 global_symbols.op_sym[i] = str;
10381 }
10382 return str;
10383 }
10384 }
10385 }
10386
10387 if (st_lookup(global_symbols.id_str, id, &data)) {
10388 VALUE str = (VALUE)data;
10389 if (RBASIC(str)->klass == 0)
10390 RBASIC(str)->klass = rb_cString;
10391 return str;
10392 }
10393
10394 if (is_attrset_id(id)) {
10395 ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
10396 VALUE str;
10397
10398 while (!(str = rb_id2str(id2))) {
10399 if (!is_local_id(id2)) return 0;
10400 id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
10401 }
10402 str = rb_str_dup(str);
10403 rb_str_cat(str, "=", 1);
10404 rb_intern_str(str);
10405 if (st_lookup(global_symbols.id_str, id, &data)) {
10406 VALUE str = (VALUE)data;
10407 if (RBASIC(str)->klass == 0)
10408 RBASIC(str)->klass = rb_cString;
10409 return str;
10410 }
10411 }
10412 return 0;
10413 }
10414
10415 const char *
10416 rb_id2name(ID id)
10417 {
10418 VALUE str = rb_id2str(id);
10419
10420 if (!str) return 0;
10421 return RSTRING_PTR(str);
10422 }
10423
10424 static int
10425 symbols_i(VALUE sym, ID value, VALUE ary)
10426 {
10427 rb_ary_push(ary, ID2SYM(value));
10428 return ST_CONTINUE;
10429 }
10430
10431 /*
10432 * call-seq:
10433 * Symbol.all_symbols => array
10434 *
10435 * Returns an array of all the symbols currently in Ruby's symbol
10436 * table.
10437 *
10438 * Symbol.all_symbols.size #=> 903
10439 * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
10440 * :chown, :EOFError, :$;, :String,
10441 * :LOCK_SH, :"setuid?", :$<,
10442 * :default_proc, :compact, :extend,
10443 * :Tms, :getwd, :$=, :ThreadGroup,
10444 * :wait2, :$>]
10445 */
10446
10447 VALUE
10448 rb_sym_all_symbols(void)
10449 {
10450 VALUE ary = rb_ary_new2(global_symbols.sym_id->num_entries);
10451
10452 st_foreach(global_symbols.sym_id, symbols_i, ary);
10453 return ary;
10454 }
10455
10456 int
10457 rb_is_const_id(ID id)
10458 {
10459 return is_const_id(id);
10460 }
10461
10462 int
10463 rb_is_class_id(ID id)
10464 {
10465 return is_class_id(id);
10466 }
10467
10468 int
10469 rb_is_global_id(ID id)
10470 {
10471 return is_global_id(id);
10472 }
10473
10474 int
10475 rb_is_instance_id(ID id)
10476 {
10477 return is_instance_id(id);
10478 }
10479
10480 int
10481 rb_is_attrset_id(ID id)
10482 {
10483 return is_attrset_id(id);
10484 }
10485
10486 int
10487 rb_is_local_id(ID id)
10488 {
10489 return is_local_id(id);
10490 }
10491
10492 int
10493 rb_is_junk_id(ID id)
10494 {
10495 return is_junk_id(id);
10496 }
10497
10509 ID
10510 rb_check_id(volatile VALUE *namep)
10511 {
10512 st_data_t id;
10513 VALUE tmp;
10514 VALUE name = *namep;
10515
10516 if (SYMBOL_P(name)) {
10517 return SYM2ID(name);
10518 }
10519 else if (!RB_TYPE_P(name, T_STRING)) {
10520 tmp = rb_check_string_type(name);
10521 if (NIL_P(tmp)) {
10522 tmp = rb_inspect(name);
10523 rb_raise(rb_eTypeError, "%s is not a symbol",
10524 RSTRING_PTR(tmp));
10525 }
10526 name = tmp;
10527 *namep = name;
10528 }
10529
10530 sym_check_asciionly(name);
10531
10532 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10533 return (ID)id;
10534
10535 if (rb_is_attrset_name(name)) {
10536 struct RString fake_str;
10537 const VALUE localname = (VALUE)&fake_str;
10538 /* make local name by chopping '=' */
10539 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10540 fake_str.basic.klass = rb_cString;
10541 fake_str.as.heap.len = RSTRING_LEN(name) - 1;
10542 fake_str.as.heap.ptr = RSTRING_PTR(name);
10543 fake_str.as.heap.aux.capa = fake_str.as.heap.len;
10544 rb_enc_copy(localname, name);
10545 OBJ_FREEZE(localname);
10546
10547 if (st_lookup(global_symbols.sym_id, (st_data_t)localname, &id)) {
10548 return rb_id_attrset((ID)id);
10549 }
10550 RB_GC_GUARD(name);
10551 }
10552
10553 return (ID)0;
10554 }
10555
10556 ID
10557 rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
10558 {
10559 st_data_t id;
10560 struct RString fake_str;
10561 const VALUE name = (VALUE)&fake_str;
10562 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10563 fake_str.basic.klass = rb_cString;
10564 fake_str.as.heap.len = len;
10565 fake_str.as.heap.ptr = (char *)ptr;
10566 fake_str.as.heap.aux.capa = len;
10567 rb_enc_associate(name, enc);
10568
10569 sym_check_asciionly(name);
10570
10571 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10572 return (ID)id;
10573
10574 if (rb_is_attrset_name(name)) {
10575 fake_str.as.heap.len = len - 1;
10576 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id)) {
10577 return rb_id_attrset((ID)id);
10578 }
10579 }
10580
10581 return (ID)0;
10582 }
10583
10584 int
10585 rb_is_const_name(VALUE name)
10586 {
10587 return rb_str_symname_type(name) == ID_CONST;
10588 }
10589
10590 int
10591 rb_is_class_name(VALUE name)
10592 {
10593 return rb_str_symname_type(name) == ID_CLASS;
10594 }
10595
10596 int
10597 rb_is_global_name(VALUE name)
10598 {
10599 return rb_str_symname_type(name) == ID_GLOBAL;
10600 }
10601
10602 int
10603 rb_is_instance_name(VALUE name)
10604 {
10605 return rb_str_symname_type(name) == ID_INSTANCE;
10606 }
10607
10608 int
10609 rb_is_attrset_name(VALUE name)
10610 {
10611 return rb_str_symname_type(name) == ID_ATTRSET;
10612 }
10613
10614 int
10615 rb_is_local_name(VALUE name)
10616 {
10617 return rb_str_symname_type(name) == ID_LOCAL;
10618 }
10619
10620 int
10621 rb_is_method_name(VALUE name)
10622 {
10623 switch (rb_str_symname_type(name)) {
10624 case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
10625 return TRUE;
10626 }
10627 return FALSE;
10628 }
10629
10630 int
10631 rb_is_junk_name(VALUE name)
10632 {
10633 return rb_str_symname_type(name) == -1;
10634 }
10635
10636 #endif /* !RIPPER */
10637
10638 static void
10639 parser_initialize(struct parser_params *parser)
10640 {
10641 parser->eofp = Qfalse;
10642
10643 parser->parser_lex_strterm = 0;
10644 parser->parser_cond_stack = 0;
10645 parser->parser_cmdarg_stack = 0;
10646 parser->parser_class_nest = 0;
10647 parser->parser_paren_nest = 0;
10648 parser->parser_lpar_beg = 0;
10649 parser->parser_brace_nest = 0;
10650 parser->parser_in_single = 0;
10651 parser->parser_in_def = 0;
10652 parser->parser_in_defined = 0;
10653 parser->parser_compile_for_eval = 0;
10654 parser->parser_cur_mid = 0;
10655 parser->parser_tokenbuf = NULL;
10656 parser->parser_tokidx = 0;
10657 parser->parser_toksiz = 0;
10658 parser->parser_heredoc_end = 0;
10659 parser->parser_command_start = TRUE;
10660 parser->parser_deferred_nodes = 0;
10661 parser->parser_lex_pbeg = 0;
10662 parser->parser_lex_p = 0;
10663 parser->parser_lex_pend = 0;
10664 parser->parser_lvtbl = 0;
10665 parser->parser_ruby__end__seen = 0;
10666 parser->parser_ruby_sourcefile = 0;
10667 #ifndef RIPPER
10668 parser->is_ripper = 0;
10669 parser->parser_eval_tree_begin = 0;
10670 parser->parser_eval_tree = 0;
10671 #else
10672 parser->is_ripper = 1;
10673 parser->parser_ruby_sourcefile_string = Qnil;
10674 parser->delayed = Qnil;
10675
10676 parser->result = Qnil;
10677 parser->parsing_thread = Qnil;
10678 parser->toplevel_p = TRUE;
10679 #endif
10680 #ifdef YYMALLOC
10681 parser->heap = NULL;
10682 #endif
10683 parser->enc = rb_utf8_encoding();
10684 }
10685
10686 #ifdef RIPPER
10687 #define parser_mark ripper_parser_mark
10688 #define parser_free ripper_parser_free
10689 #endif
10690
10691 static void
10692 parser_mark(void *ptr)
10693 {
10694 struct parser_params *p = (struct parser_params*)ptr;
10695
10696 rb_gc_mark((VALUE)p->parser_lex_strterm);
10697 rb_gc_mark((VALUE)p->parser_deferred_nodes);
10698 rb_gc_mark(p->parser_lex_input);
10699 rb_gc_mark(p->parser_lex_lastline);
10700 rb_gc_mark(p->parser_lex_nextline);
10701 #ifndef RIPPER
10702 rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
10703 rb_gc_mark((VALUE)p->parser_eval_tree) ;
10704 rb_gc_mark(p->debug_lines);
10705 #else
10706 rb_gc_mark(p->parser_ruby_sourcefile_string);
10707 rb_gc_mark(p->delayed);
10708 rb_gc_mark(p->value);
10709 rb_gc_mark(p->result);
10710 rb_gc_mark(p->parsing_thread);
10711 #endif
10712 #ifdef YYMALLOC
10713 rb_gc_mark((VALUE)p->heap);
10714 #endif
10715 }
10716
10717 static void
10718 parser_free(void *ptr)
10719 {
10720 struct parser_params *p = (struct parser_params*)ptr;
10721 struct local_vars *local, *prev;
10722
10723 if (p->parser_tokenbuf) {
10724 xfree(p->parser_tokenbuf);
10725 }
10726 for (local = p->parser_lvtbl; local; local = prev) {
10727 if (local->vars) xfree(local->vars);
10728 prev = local->prev;
10729 xfree(local);
10730 }
10731 #ifndef RIPPER
10732 xfree(p->parser_ruby_sourcefile);
10733 #endif
10734 xfree(p);
10735 }
10736
10737 static size_t
10738 parser_memsize(const void *ptr)
10739 {
10740 struct parser_params *p = (struct parser_params*)ptr;
10741 struct local_vars *local;
10742 size_t size = sizeof(*p);
10743
10744 if (!ptr) return 0;
10745 size += p->parser_toksiz;
10746 for (local = p->parser_lvtbl; local; local = local->prev) {
10747 size += sizeof(*local);
10748 if (local->vars) size += local->vars->capa * sizeof(ID);
10749 }
10750 #ifndef RIPPER
10751 if (p->parser_ruby_sourcefile) {
10752 size += strlen(p->parser_ruby_sourcefile) + 1;
10753 }
10754 #endif
10755 return size;
10756 }
10757
10758 static
10759 #ifndef RIPPER
10760 const
10761 #endif
10762 rb_data_type_t parser_data_type = {
10763 "parser",
10764 {
10765 parser_mark,
10766 parser_free,
10767 parser_memsize,
10768 },
10769 };
10770
10771 #ifndef RIPPER
10772 #undef rb_reserved_word
10773
10774 const struct kwtable *
10775 rb_reserved_word(const char *str, unsigned int len)
10776 {
10777 return reserved_word(str, len);
10778 }
10779
10780 static struct parser_params *
10781 parser_new(void)
10782 {
10783 struct parser_params *p;
10784
10785 p = ALLOC_N(struct parser_params, 1);
10786 MEMZERO(p, struct parser_params, 1);
10787 parser_initialize(p);
10788 return p;
10789 }
10790
10791 VALUE
10792 rb_parser_new(void)
10793 {
10794 struct parser_params *p = parser_new();
10795
10796 return TypedData_Wrap_Struct(0, &parser_data_type, p);
10797 }
10798
10799 /*
10800 * call-seq:
10801 * ripper#end_seen? -> Boolean
10802 *
10803 * Return true if parsed source ended by +\_\_END\_\_+.
10804 */
10805 VALUE
10806 rb_parser_end_seen_p(VALUE vparser)
10807 {
10808 struct parser_params *parser;
10809
10810 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10811 return ruby__end__seen ? Qtrue : Qfalse;
10812 }
10813
10814 /*
10815 * call-seq:
10816 * ripper#encoding -> encoding
10817 *
10818 * Return encoding of the source.
10819 */
10820 VALUE
10821 rb_parser_encoding(VALUE vparser)
10822 {
10823 struct parser_params *parser;
10824
10825 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10826 return rb_enc_from_encoding(current_enc);
10827 }
10828
10829 /*
10830 * call-seq:
10831 * ripper.yydebug -> true or false
10832 *
10833 * Get yydebug.
10834 */
10835 VALUE
10836 rb_parser_get_yydebug(VALUE self)
10837 {
10838 struct parser_params *parser;
10839
10840 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10841 return yydebug ? Qtrue : Qfalse;
10842 }
10843
10844 /*
10845 * call-seq:
10846 * ripper.yydebug = flag
10847 *
10848 * Set yydebug.
10849 */
10850 VALUE
10851 rb_parser_set_yydebug(VALUE self, VALUE flag)
10852 {
10853 struct parser_params *parser;
10854
10855 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10856 yydebug = RTEST(flag);
10857 return flag;
10858 }
10859
10860 #ifdef YYMALLOC
10861 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10862 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10863 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10864 (n)->u3.cnt = (c), (p))
10865
10866 void *
10867 rb_parser_malloc(struct parser_params *parser, size_t size)
10868 {
10869 size_t cnt = HEAPCNT(1, size);
10870 NODE *n = NEWHEAP();
10871 void *ptr = xmalloc(size);
10872
10873 return ADD2HEAP(n, cnt, ptr);
10874 }
10875
10876 void *
10877 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10878 {
10879 size_t cnt = HEAPCNT(nelem, size);
10880 NODE *n = NEWHEAP();
10881 void *ptr = xcalloc(nelem, size);
10882
10883 return ADD2HEAP(n, cnt, ptr);
10884 }
10885
10886 void *
10887 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10888 {
10889 NODE *n;
10890 size_t cnt = HEAPCNT(1, size);
10891
10892 if (ptr && (n = parser->heap) != NULL) {
10893 do {
10894 if (n->u1.node == ptr) {
10895 n->u1.node = ptr = xrealloc(ptr, size);
10896 if (n->u3.cnt) n->u3.cnt = cnt;
10897 return ptr;
10898 }
10899 } while ((n = n->u2.node) != NULL);
10900 }
10901 n = NEWHEAP();
10902 ptr = xrealloc(ptr, size);
10903 return ADD2HEAP(n, cnt, ptr);
10904 }
10905
10906 void
10907 rb_parser_free(struct parser_params *parser, void *ptr)
10908 {
10909 NODE **prev = &parser->heap, *n;
10910
10911 while ((n = *prev) != NULL) {
10912 if (n->u1.node == ptr) {
10913 *prev = n->u2.node;
10914 rb_gc_force_recycle((VALUE)n);
10915 break;
10916 }
10917 prev = &n->u2.node;
10918 }
10919 xfree(ptr);
10920 }
10921 #endif
10922 #endif
10923
10924 #ifdef RIPPER
10925 #ifdef RIPPER_DEBUG
10926 extern int rb_is_pointer_to_heap(VALUE);
10927
10928 /* :nodoc: */
10929 static VALUE
10930 ripper_validate_object(VALUE self, VALUE x)
10931 {
10932 if (x == Qfalse) return x;
10933 if (x == Qtrue) return x;
10934 if (x == Qnil) return x;
10935 if (x == Qundef)
10936 rb_raise(rb_eArgError, "Qundef given");
10937 if (FIXNUM_P(x)) return x;
10938 if (SYMBOL_P(x)) return x;
10939 if (!rb_is_pointer_to_heap(x))
10940 rb_raise(rb_eArgError, "invalid pointer: %p", x);
10941 switch (TYPE(x)) {
10942 case T_STRING:
10943 case T_OBJECT:
10944 case T_ARRAY:
10945 case T_BIGNUM:
10946 case T_FLOAT:
10947 return x;
10948 case T_NODE:
10949 if (nd_type(x) != NODE_LASGN) {
10950 rb_raise(rb_eArgError, "NODE given: %p", x);
10951 }
10952 return ((NODE *)x)->nd_rval;
10953 default:
10954 rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
10955 x, rb_obj_classname(x));
10956 }
10957 return x;
10958 }
10959 #endif
10960
10961 #define validate(x) ((x) = get_value(x))
10962
10963 static VALUE
10964 ripper_dispatch0(struct parser_params *parser, ID mid)
10965 {
10966 return rb_funcall(parser->value, mid, 0);
10967 }
10968
10969 static VALUE
10970 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
10971 {
10972 validate(a);
10973 return rb_funcall(parser->value, mid, 1, a);
10974 }
10975
10976 static VALUE
10977 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
10978 {
10979 validate(a);
10980 validate(b);
10981 return rb_funcall(parser->value, mid, 2, a, b);
10982 }
10983
10984 static VALUE
10985 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
10986 {
10987 validate(a);
10988 validate(b);
10989 validate(c);
10990 return rb_funcall(parser->value, mid, 3, a, b, c);
10991 }
10992
10993 static VALUE
10994 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
10995 {
10996 validate(a);
10997 validate(b);
10998 validate(c);
10999 validate(d);
11000 return rb_funcall(parser->value, mid, 4, a, b, c, d);
11001 }
11002
11003 static VALUE
11004 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
11005 {
11006 validate(a);
11007 validate(b);
11008 validate(c);
11009 validate(d);
11010 validate(e);
11011 return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
11012 }
11013
11014 static VALUE
11015 ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
11016 {
11017 validate(a);
11018 validate(b);
11019 validate(c);
11020 validate(d);
11021 validate(e);
11022 validate(f);
11023 validate(g);
11024 return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
11025 }
11026
11027 static const struct kw_assoc {
11028 ID id;
11029 const char *name;
11030 } keyword_to_name[] = {
11031 {keyword_class, "class"},
11032 {keyword_module, "module"},
11033 {keyword_def, "def"},
11034 {keyword_undef, "undef"},
11035 {keyword_begin, "begin"},
11036 {keyword_rescue, "rescue"},
11037 {keyword_ensure, "ensure"},
11038 {keyword_end, "end"},
11039 {keyword_if, "if"},
11040 {keyword_unless, "unless"},
11041 {keyword_then, "then"},
11042 {keyword_elsif, "elsif"},
11043 {keyword_else, "else"},
11044 {keyword_case, "case"},
11045 {keyword_when, "when"},
11046 {keyword_while, "while"},
11047 {keyword_until, "until"},
11048 {keyword_for, "for"},
11049 {keyword_break, "break"},
11050 {keyword_next, "next"},
11051 {keyword_redo, "redo"},
11052 {keyword_retry, "retry"},
11053 {keyword_in, "in"},
11054 {keyword_do, "do"},
11055 {keyword_do_cond, "do"},
11056 {keyword_do_block, "do"},
11057 {keyword_return, "return"},
11058 {keyword_yield, "yield"},
11059 {keyword_super, "super"},
11060 {keyword_self, "self"},
11061 {keyword_nil, "nil"},
11062 {keyword_true, "true"},
11063 {keyword_false, "false"},
11064 {keyword_and, "and"},
11065 {keyword_or, "or"},
11066 {keyword_not, "not"},
11067 {modifier_if, "if"},
11068 {modifier_unless, "unless"},
11069 {modifier_while, "while"},
11070 {modifier_until, "until"},
11071 {modifier_rescue, "rescue"},
11072 {keyword_alias, "alias"},
11073 {keyword_defined, "defined?"},
11074 {keyword_BEGIN, "BEGIN"},
11075 {keyword_END, "END"},
11076 {keyword__LINE__, "__LINE__"},
11077 {keyword__FILE__, "__FILE__"},
11078 {keyword__ENCODING__, "__ENCODING__"},
11079 {0, NULL}
11080 };
11081
11082 static const char*
11083 keyword_id_to_str(ID id)
11084 {
11085 const struct kw_assoc *a;
11086
11087 for (a = keyword_to_name; a->id; a++) {
11088 if (a->id == id)
11089 return a->name;
11090 }
11091 return NULL;
11092 }
11093
11094 #undef ripper_id2sym
11095 static VALUE
11096 ripper_id2sym(ID id)
11097 {
11098 const char *name;
11099 char buf[8];
11100
11101 if (id <= 256) {
11102 buf[0] = (char)id;
11103 buf[1] = '\0';
11104 return ID2SYM(rb_intern2(buf, 1));
11105 }
11106 if ((name = keyword_id_to_str(id))) {
11107 return ID2SYM(rb_intern(name));
11108 }
11109 switch (id) {
11110 case tOROP:
11111 name = "||";
11112 break;
11113 case tANDOP:
11114 name = "&&";
11115 break;
11116 default:
11117 name = rb_id2name(id);
11118 if (!name) {
11119 rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
11120 }
11121 return ID2SYM(id);
11122 }
11123 return ID2SYM(rb_intern(name));
11124 }
11125
11126 static ID
11127 ripper_get_id(VALUE v)
11128 {
11129 NODE *nd;
11130 if (!RB_TYPE_P(v, T_NODE)) return 0;
11131 nd = (NODE *)v;
11132 if (nd_type(nd) != NODE_LASGN) return 0;
11133 return nd->nd_vid;
11134 }
11135
11136 static VALUE
11137 ripper_get_value(VALUE v)
11138 {
11139 NODE *nd;
11140 if (v == Qundef) return Qnil;
11141 if (!RB_TYPE_P(v, T_NODE)) return v;
11142 nd = (NODE *)v;
11143 if (nd_type(nd) != NODE_LASGN) return Qnil;
11144 return nd->nd_rval;
11145 }
11146
11147 static void
11148 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
11149 {
11150 VALUE str;
11151 va_list args;
11152
11153 va_start(args, fmt);
11154 str = rb_vsprintf(fmt, args);
11155 va_end(args);
11156 rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
11157 }
11158
11159 static void
11160 ripper_warn0(struct parser_params *parser, const char *fmt)
11161 {
11162 rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
11163 }
11164
11165 static void
11166 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
11167 {
11168 rb_funcall(parser->value, rb_intern("warn"), 2,
11169 STR_NEW2(fmt), INT2NUM(a));
11170 }
11171
11172 static void
11173 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
11174 {
11175 rb_funcall(parser->value, rb_intern("warn"), 2,
11176 STR_NEW2(fmt), STR_NEW2(str));
11177 }
11178
11179 static void
11180 ripper_warning0(struct parser_params *parser, const char *fmt)
11181 {
11182 rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
11183 }
11184
11185 static void
11186 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
11187 {
11188 rb_funcall(parser->value, rb_intern("warning"), 2,
11189 STR_NEW2(fmt), STR_NEW2(str));
11190 }
11191
11192 static VALUE
11193 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
11194 {
11195 return rb_io_gets(src);
11196 }
11197
11198 static VALUE
11199 ripper_s_allocate(VALUE klass)
11200 {
11201 struct parser_params *p;
11202 VALUE self;
11203
11204 p = ALLOC_N(struct parser_params, 1);
11205 MEMZERO(p, struct parser_params, 1);
11206 self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
11207 p->value = self;
11208 return self;
11209 }
11210
11211 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
11212
11213 /*
11214 * call-seq:
11215 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
11216 *
11217 * Create a new Ripper object.
11218 * _src_ must be a String, an IO, or an Object which has #gets method.
11219 *
11220 * This method does not starts parsing.
11221 * See also Ripper#parse and Ripper.parse.
11222 */
11223 static VALUE
11224 ripper_initialize(int argc, VALUE *argv, VALUE self)
11225 {
11226 struct parser_params *parser;
11227 VALUE src, fname, lineno;
11228
11229 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11230 rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
11231 if (RB_TYPE_P(src, T_FILE)) {
11232 parser->parser_lex_gets = ripper_lex_get_generic;
11233 }
11234 else {
11235 StringValue(src);
11236 parser->parser_lex_gets = lex_get_str;
11237 }
11238 parser->parser_lex_input = src;
11239 parser->eofp = Qfalse;
11240 if (NIL_P(fname)) {
11241 fname = STR_NEW2("(ripper)");
11242 }
11243 else {
11244 StringValue(fname);
11245 }
11246 parser_initialize(parser);
11247
11248 parser->parser_ruby_sourcefile_string = fname;
11249 parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
11250 parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
11251
11252 return Qnil;
11253 }
11254
11255 struct ripper_args {
11256 struct parser_params *parser;
11257 int argc;
11258 VALUE *argv;
11259 };
11260
11261 static VALUE
11262 ripper_parse0(VALUE parser_v)
11263 {
11264 struct parser_params *parser;
11265
11266 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11267 parser_prepare(parser);
11268 ripper_yyparse((void*)parser);
11269 return parser->result;
11270 }
11271
11272 static VALUE
11273 ripper_ensure(VALUE parser_v)
11274 {
11275 struct parser_params *parser;
11276
11277 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11278 parser->parsing_thread = Qnil;
11279 return Qnil;
11280 }
11281
11282 /*
11283 * call-seq:
11284 * ripper#parse
11285 *
11286 * Start parsing and returns the value of the root action.
11287 */
11288 static VALUE
11289 ripper_parse(VALUE self)
11290 {
11291 struct parser_params *parser;
11292
11293 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11294 if (!ripper_initialized_p(parser)) {
11295 rb_raise(rb_eArgError, "method called for uninitialized object");
11296 }
11297 if (!NIL_P(parser->parsing_thread)) {
11298 if (parser->parsing_thread == rb_thread_current())
11299 rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
11300 else
11301 rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
11302 }
11303 parser->parsing_thread = rb_thread_current();
11304 rb_ensure(ripper_parse0, self, ripper_ensure, self);
11305
11306 return parser->result;
11307 }
11308
11309 /*
11310 * call-seq:
11311 * ripper#column -> Integer
11312 *
11313 * Return column number of current parsing line.
11314 * This number starts from 0.
11315 */
11316 static VALUE
11317 ripper_column(VALUE self)
11318 {
11319 struct parser_params *parser;
11320 long col;
11321
11322 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11323 if (!ripper_initialized_p(parser)) {
11324 rb_raise(rb_eArgError, "method called for uninitialized object");
11325 }
11326 if (NIL_P(parser->parsing_thread)) return Qnil;
11327 col = parser->tokp - parser->parser_lex_pbeg;
11328 return LONG2NUM(col);
11329 }
11330
11331 /*
11332 * call-seq:
11333 * ripper#filename -> String
11334 *
11335 * Return current parsing filename.
11336 */
11337 static VALUE
11338 ripper_filename(VALUE self)
11339 {
11340 struct parser_params *parser;
11341
11342 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11343 if (!ripper_initialized_p(parser)) {
11344 rb_raise(rb_eArgError, "method called for uninitialized object");
11345 }
11346 return parser->parser_ruby_sourcefile_string;
11347 }
11348
11349 /*
11350 * call-seq:
11351 * ripper#lineno -> Integer
11352 *
11353 * Return line number of current parsing line.
11354 * This number starts from 1.
11355 */
11356 static VALUE
11357 ripper_lineno(VALUE self)
11358 {
11359 struct parser_params *parser;
11360
11361 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11362 if (!ripper_initialized_p(parser)) {
11363 rb_raise(rb_eArgError, "method called for uninitialized object");
11364 }
11365 if (NIL_P(parser->parsing_thread)) return Qnil;
11366 return INT2NUM(parser->parser_ruby_sourceline);
11367 }
11368
11369 #ifdef RIPPER_DEBUG
11370 /* :nodoc: */
11371 static VALUE
11372 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
11373 {
11374 StringValue(msg);
11375 if (obj == Qundef) {
11376 rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
11377 }
11378 return Qnil;
11379 }
11380
11381 /* :nodoc: */
11382 static VALUE
11383 ripper_value(VALUE self, VALUE obj)
11384 {
11385 return ULONG2NUM(obj);
11386 }
11387 #endif
11388
11389
11390 void
11391 Init_ripper(void)
11392 {
11393 parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
11394
11395 ripper_init_eventids1();
11396 ripper_init_eventids2();
11397 /* ensure existing in symbol table */
11398 (void)rb_intern("||");
11399 (void)rb_intern("&&");
11400
11401 InitVM(ripper);
11402 }
11403
11404 void
11405 InitVM_ripper(void)
11406 {
11407 VALUE Ripper;
11408
11409 Ripper = rb_define_class("Ripper", rb_cObject);
11410 rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
11411 rb_define_alloc_func(Ripper, ripper_s_allocate);
11412 rb_define_method(Ripper, "initialize", ripper_initialize, -1);
11413 rb_define_method(Ripper, "parse", ripper_parse, 0);
11414 rb_define_method(Ripper, "column", ripper_column, 0);
11415 rb_define_method(Ripper, "filename", ripper_filename, 0);
11416 rb_define_method(Ripper, "lineno", ripper_lineno, 0);
11417 rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
11418 rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
11419 rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
11420 rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
11421 #ifdef RIPPER_DEBUG
11422 rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
11423 rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
11424 rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
11425 #endif
11426
11427 ripper_init_eventids1_table(Ripper);
11428 ripper_init_eventids2_table(Ripper);
11429
11430 # if 0
11431 /* Hack to let RDoc document SCRIPT_LINES__ */
11432
11433 /*
11434 * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
11435 * after the assignment will be added as an Array of lines with the file
11436 * name as the key.
11437 */
11438 rb_define_global_const("SCRIPT_LINES__", Qnil);
11439 #endif
11440
11441 }
11442 #endif /* RIPPER */
11443