2 ** parse.y - mruby parser
4 ** See Copyright Notice in mruby.h
12 #define YYSTACK_USE_ALLOCA 1
19 #include <mruby/compile.h>
20 #include <mruby/proc.h>
21 #include <mruby/error.h>
22 #include <mruby/throw.h>
23 #include <mruby/string.h>
28 typedef mrb_ast_node node;
29 typedef struct mrb_parser_state parser_state;
30 typedef struct mrb_parser_heredoc_info parser_heredoc_info;
32 static int yyparse(parser_state *p);
33 static int yylex(void *lval, parser_state *p);
34 static void yyerror(parser_state *p, const char *s);
35 static void yywarn(parser_state *p, const char *s);
36 static void yywarning(parser_state *p, const char *s);
37 static void backref_error(parser_state *p, node *n);
38 static void void_expr_error(parser_state *p, node *n);
39 static void tokadd(parser_state *p, int32_t c);
41 #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
43 typedef unsigned int stack_type;
45 #define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
46 #define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
47 #define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
48 #define BITSTACK_SET_P(stack) ((stack)&1)
50 #define COND_PUSH(n) BITSTACK_PUSH(p->cond_stack, (n))
51 #define COND_POP() BITSTACK_POP(p->cond_stack)
52 #define COND_LEXPOP() BITSTACK_LEXPOP(p->cond_stack)
53 #define COND_P() BITSTACK_SET_P(p->cond_stack)
55 #define CMDARG_PUSH(n) BITSTACK_PUSH(p->cmdarg_stack, (n))
56 #define CMDARG_POP() BITSTACK_POP(p->cmdarg_stack)
57 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
58 #define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack)
60 #define SET_LINENO(c,n) ((c)->lineno = (n))
61 #define NODE_LINENO(c,n) do {\
63 (c)->filename_index = (n)->filename_index;\
64 (c)->lineno = (n)->lineno;\
68 #define sym(x) ((mrb_sym)(intptr_t)(x))
69 #define nsym(x) ((node*)(intptr_t)(x))
70 #define nint(x) ((node*)(intptr_t)(x))
71 #define intn(x) ((int)(intptr_t)(x))
73 #define NUM_SUFFIX_R (1<<0)
74 #define NUM_SUFFIX_I (1<<1)
77 intern_cstr_gen(parser_state *p, const char *s)
79 return mrb_intern_cstr(p->mrb, s);
81 #define intern_cstr(s) intern_cstr_gen(p,(s))
84 intern_gen(parser_state *p, const char *s, size_t len)
86 return mrb_intern(p->mrb, s, len);
88 #define intern(s,len) intern_gen(p,(s),(len))
90 #define intern_lit(s) mrb_intern_lit(p->mrb, s)
93 cons_free_gen(parser_state *p, node *cons)
98 #define cons_free(c) cons_free_gen(p, (c))
101 parser_palloc(parser_state *p, size_t size)
103 void *m = mrb_pool_alloc(p->pool, size);
112 cons_gen(parser_state *p, node *car, node *cdr)
118 p->cells = p->cells->cdr;
121 c = (node *)parser_palloc(p, sizeof(mrb_ast_node));
126 c->lineno = p->lineno;
127 c->filename_index = p->current_filename_index;
128 /* beginning of next partial file; need to point the previous file */
129 if (p->lineno == 0 && p->current_filename_index > 0) {
130 c->filename_index-- ;
134 #define cons(a,b) cons_gen(p,(a),(b))
137 list1_gen(parser_state *p, node *a)
141 #define list1(a) list1_gen(p, (a))
144 list2_gen(parser_state *p, node *a, node *b)
146 return cons(a, cons(b,0));
148 #define list2(a,b) list2_gen(p, (a),(b))
151 list3_gen(parser_state *p, node *a, node *b, node *c)
153 return cons(a, cons(b, cons(c,0)));
155 #define list3(a,b,c) list3_gen(p, (a),(b),(c))
158 list4_gen(parser_state *p, node *a, node *b, node *c, node *d)
160 return cons(a, cons(b, cons(c, cons(d, 0))));
162 #define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
165 list5_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e)
167 return cons(a, cons(b, cons(c, cons(d, cons(e, 0)))));
169 #define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
172 list6_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e, node *f)
174 return cons(a, cons(b, cons(c, cons(d, cons(e, cons(f, 0))))));
176 #define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
179 append_gen(parser_state *p, node *a, node *b)
191 #define append(a,b) append_gen(p,(a),(b))
192 #define push(a,b) append_gen(p,(a),list1(b))
195 parser_strndup(parser_state *p, const char *s, size_t len)
197 char *b = (char *)parser_palloc(p, len+1);
204 #define strndup(s,len) parser_strndup(p, s, len)
207 parser_strdup(parser_state *p, const char *s)
209 return parser_strndup(p, s, strlen(s));
212 #define strdup(s) parser_strdup(p, s)
215 dump_int(uint16_t i, char *s)
224 if (p == s) *p++ = '0';
226 p--; /* point the last char */
234 /* xxx ----------------------------- */
237 local_switch(parser_state *p)
239 node *prev = p->locals;
241 p->locals = cons(0, 0);
246 local_resume(parser_state *p, node *prev)
252 local_nest(parser_state *p)
254 p->locals = cons(0, p->locals);
258 local_unnest(parser_state *p)
261 p->locals = p->locals->cdr;
266 local_var_p(parser_state *p, mrb_sym sym)
274 if (sym(n->car) == sym) return TRUE;
281 while (u && !MRB_PROC_CFUNC_P(u)) {
282 struct mrb_irep *ir = u->body.irep;
283 uint_fast16_t n = ir->nlocals;
284 const struct mrb_locals *v = ir->lv;
285 for (; n > 1; n --, v ++) {
286 if (v->name == sym) return TRUE;
288 if (MRB_PROC_SCOPE_P(u)) break;
295 local_add_f(parser_state *p, mrb_sym sym)
298 p->locals->car = push(p->locals->car, nsym(sym));
303 local_add(parser_state *p, mrb_sym sym)
305 if (!local_var_p(p, sym)) {
311 local_add_blk(parser_state *p, mrb_sym blk)
313 /* allocate register for block */
314 local_add_f(p, blk ? blk : mrb_intern_lit(p->mrb, "&"));
318 local_add_kw(parser_state *p, mrb_sym kwd)
320 /* allocate register for keywords hash */
321 local_add_f(p, kwd ? kwd : mrb_intern_lit(p->mrb, "**"));
325 locals_node(parser_state *p)
327 return p->locals ? p->locals->car : NULL;
331 nvars_nest(parser_state *p)
333 p->nvars = cons(nint(0), p->nvars);
337 nvars_block(parser_state *p)
339 p->nvars = cons(nint(-2), p->nvars);
343 nvars_unnest(parser_state *p)
345 p->nvars = p->nvars->cdr;
348 /* (:scope (vars..) (prog...)) */
350 new_scope(parser_state *p, node *body)
352 return cons((node*)NODE_SCOPE, cons(locals_node(p), body));
355 /* (:begin prog...) */
357 new_begin(parser_state *p, node *body)
360 return list2((node*)NODE_BEGIN, body);
362 return cons((node*)NODE_BEGIN, 0);
365 #define newline_node(n) (n)
367 /* (:rescue body rescue else) */
369 new_rescue(parser_state *p, node *body, node *resq, node *els)
371 return list4((node*)NODE_RESCUE, body, resq, els);
375 new_mod_rescue(parser_state *p, node *body, node *resq)
377 return new_rescue(p, body, list1(list3(0, 0, resq)), 0);
380 /* (:ensure body ensure) */
382 new_ensure(parser_state *p, node *a, node *b)
384 return cons((node*)NODE_ENSURE, cons(a, cons(0, b)));
389 new_nil(parser_state *p)
391 return list1((node*)NODE_NIL);
396 new_true(parser_state *p)
398 return list1((node*)NODE_TRUE);
403 new_false(parser_state *p)
405 return list1((node*)NODE_FALSE);
408 /* (:alias new old) */
410 new_alias(parser_state *p, mrb_sym a, mrb_sym b)
412 return cons((node*)NODE_ALIAS, cons(nsym(a), nsym(b)));
415 /* (:if cond then else) */
417 new_if(parser_state *p, node *a, node *b, node *c)
419 void_expr_error(p, a);
420 return list4((node*)NODE_IF, a, b, c);
423 /* (:unless cond then else) */
425 new_unless(parser_state *p, node *a, node *b, node *c)
427 void_expr_error(p, a);
428 return list4((node*)NODE_IF, a, c, b);
431 /* (:while cond body) */
433 new_while(parser_state *p, node *a, node *b)
435 void_expr_error(p, a);
436 return cons((node*)NODE_WHILE, cons(a, b));
439 /* (:until cond body) */
441 new_until(parser_state *p, node *a, node *b)
443 void_expr_error(p, a);
444 return cons((node*)NODE_UNTIL, cons(a, b));
447 /* (:for var obj body) */
449 new_for(parser_state *p, node *v, node *o, node *b)
451 void_expr_error(p, o);
452 return list4((node*)NODE_FOR, v, o, b);
455 /* (:case a ((when ...) body) ((when...) body)) */
457 new_case(parser_state *p, node *a, node *b)
459 node *n = list2((node*)NODE_CASE, a);
462 void_expr_error(p, a);
472 new_postexe(parser_state *p, node *a)
474 return cons((node*)NODE_POSTEXE, a);
479 new_self(parser_state *p)
481 return list1((node*)NODE_SELF);
486 new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass)
488 node *n = list4(nint(pass?NODE_CALL:NODE_SCALL), a, nsym(b), c);
489 void_expr_error(p, a);
494 /* (:fcall self mid args) */
496 new_fcall(parser_state *p, mrb_sym b, node *c)
498 node *n = new_self(p);
500 n = list4((node*)NODE_FCALL, n, nsym(b), c);
507 new_super(parser_state *p, node *c)
509 return cons((node*)NODE_SUPER, c);
514 new_zsuper(parser_state *p)
516 return list1((node*)NODE_ZSUPER);
521 new_yield(parser_state *p, node *c)
525 yyerror(p, "both block arg and actual block given");
527 return cons((node*)NODE_YIELD, c->car);
529 return cons((node*)NODE_YIELD, 0);
534 new_return(parser_state *p, node *c)
536 return cons((node*)NODE_RETURN, c);
541 new_break(parser_state *p, node *c)
543 return cons((node*)NODE_BREAK, c);
548 new_next(parser_state *p, node *c)
550 return cons((node*)NODE_NEXT, c);
555 new_redo(parser_state *p)
557 return list1((node*)NODE_REDO);
562 new_retry(parser_state *p)
564 return list1((node*)NODE_RETRY);
569 new_dot2(parser_state *p, node *a, node *b)
571 return cons((node*)NODE_DOT2, cons(a, b));
576 new_dot3(parser_state *p, node *a, node *b)
578 return cons((node*)NODE_DOT3, cons(a, b));
583 new_colon2(parser_state *p, node *b, mrb_sym c)
585 void_expr_error(p, b);
586 return cons((node*)NODE_COLON2, cons(b, nsym(c)));
591 new_colon3(parser_state *p, mrb_sym c)
593 return cons((node*)NODE_COLON3, nsym(c));
598 new_and(parser_state *p, node *a, node *b)
600 return cons((node*)NODE_AND, cons(a, b));
605 new_or(parser_state *p, node *a, node *b)
607 return cons((node*)NODE_OR, cons(a, b));
612 new_array(parser_state *p, node *a)
614 return cons((node*)NODE_ARRAY, a);
619 new_splat(parser_state *p, node *a)
621 return cons((node*)NODE_SPLAT, a);
624 /* (:hash (k . v) (k . v)...) */
626 new_hash(parser_state *p, node *a)
628 return cons((node*)NODE_HASH, a);
631 /* (:kw_hash (k . v) (k . v)...) */
633 new_kw_hash(parser_state *p, node *a)
635 return cons((node*)NODE_KW_HASH, a);
640 new_sym(parser_state *p, mrb_sym sym)
642 return cons((node*)NODE_SYM, nsym(sym));
646 new_strsym(parser_state *p, node* str)
648 const char *s = (const char*)str->cdr->car;
649 size_t len = (size_t)str->cdr->cdr;
651 return mrb_intern(p->mrb, s, len);
656 new_lvar(parser_state *p, mrb_sym sym)
658 return cons((node*)NODE_LVAR, nsym(sym));
663 new_gvar(parser_state *p, mrb_sym sym)
665 return cons((node*)NODE_GVAR, nsym(sym));
670 new_ivar(parser_state *p, mrb_sym sym)
672 return cons((node*)NODE_IVAR, nsym(sym));
677 new_cvar(parser_state *p, mrb_sym sym)
679 return cons((node*)NODE_CVAR, nsym(sym));
684 new_nvar(parser_state *p, int num)
686 int nvars = intn(p->nvars->car);
688 p->nvars->car = nint(nvars > num ? nvars : num);
689 return cons((node*)NODE_NVAR, nint(num));
694 new_const(parser_state *p, mrb_sym sym)
696 return cons((node*)NODE_CONST, nsym(sym));
701 new_undef(parser_state *p, mrb_sym sym)
703 return list2((node*)NODE_UNDEF, nsym(sym));
706 /* (:class class super body) */
708 new_class(parser_state *p, node *c, node *s, node *b)
710 void_expr_error(p, s);
711 return list4((node*)NODE_CLASS, c, s, cons(locals_node(p), b));
714 /* (:sclass obj body) */
716 new_sclass(parser_state *p, node *o, node *b)
718 void_expr_error(p, o);
719 return list3((node*)NODE_SCLASS, o, cons(locals_node(p), b));
722 /* (:module module body) */
724 new_module(parser_state *p, node *m, node *b)
726 return list3((node*)NODE_MODULE, m, cons(locals_node(p), b));
729 /* (:def m lv (arg . body)) */
731 new_def(parser_state *p, mrb_sym m, node *a, node *b)
733 return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b);
736 /* (:sdef obj m lv (arg . body)) */
738 new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
740 void_expr_error(p, o);
741 return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b);
746 new_arg(parser_state *p, mrb_sym sym)
748 return cons((node*)NODE_ARG, nsym(sym));
752 local_add_margs(parser_state *p, node *n)
755 if (n->car->car == (node*)NODE_MASGN) {
756 node *t = n->car->cdr->cdr;
758 n->car->cdr->cdr = NULL;
760 local_add_f(p, sym(t->car));
763 local_add_margs(p, n->car->cdr->car->car);
764 local_add_margs(p, n->car->cdr->car->cdr->cdr->car);
771 local_add_lv(parser_state *p, node *lv)
774 local_add_f(p, sym(lv->car));
779 /* (m o r m2 tail) */
781 /* o: ((a . e1) (b . e2)) */
786 new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail)
790 local_add_margs(p, m);
791 local_add_margs(p, m2);
793 n = cons(nsym(rest), n);
796 /* opt: (sym . (opt . lv)) -> (sym . opt) */
797 local_add_lv(p, opt->car->cdr->cdr);
798 opt->car->cdr = opt->car->cdr->car;
804 /* (:args_tail keywords rest_keywords_sym block_sym) */
806 new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk)
811 local_add_kw(p, (kwrest && kwrest->cdr)? sym(kwrest->cdr) : 0);
814 local_add_blk(p, blk);
816 /* allocate register for keywords arguments */
817 /* order is for Proc#parameters */
818 for (k = kws; k; k = k->cdr) {
819 if (!k->car->cdr->cdr->car) { /* allocate required keywords */
820 local_add_f(p, sym(k->car->cdr->car));
823 for (k = kws; k; k = k->cdr) {
824 if (k->car->cdr->cdr->car) { /* allocate keywords with default */
825 local_add_lv(p, k->car->cdr->cdr->car->cdr);
826 k->car->cdr->cdr->car = k->car->cdr->cdr->car->car;
827 local_add_f(p, sym(k->car->cdr->car));
831 return list4((node*)NODE_ARGS_TAIL, kws, kwrest, nsym(blk));
834 /* (:kw_arg kw_sym def_arg) */
836 new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg)
839 return list3((node*)NODE_KW_ARG, nsym(kw), def_arg);
842 /* (:kw_rest_args . a) */
844 new_kw_rest_args(parser_state *p, node *a)
846 return cons((node*)NODE_KW_REST_ARGS, a);
849 /* (:block_arg . a) */
851 new_block_arg(parser_state *p, node *a)
853 return cons((node*)NODE_BLOCK_ARG, a);
857 setup_numparams(parser_state *p, node *a)
859 int nvars = intn(p->nvars->car);
863 // m || opt || rest || tail
864 if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) {
865 yyerror(p, "ordinary parameter is defined");
867 else if (p->locals) {
868 /* p->locals should not be NULL unless error happens before the point */
870 for (i = nvars; i > 0; i--) {
876 sym = intern_cstr(buf);
877 args = cons(new_arg(p, sym), args);
878 p->locals->car = cons(nsym(sym), p->locals->car);
880 a = new_args(p, args, 0, 0, 0, 0);
886 /* (:block arg body) */
888 new_block(parser_state *p, node *a, node *b)
890 a = setup_numparams(p, a);
891 return list4((node*)NODE_BLOCK, locals_node(p), a, b);
894 /* (:lambda arg body) */
896 new_lambda(parser_state *p, node *a, node *b)
898 return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
901 /* (:asgn lhs rhs) */
903 new_asgn(parser_state *p, node *a, node *b)
905 void_expr_error(p, b);
906 return cons((node*)NODE_ASGN, cons(a, b));
909 /* (:masgn mlhs=(pre rest post) mrhs) */
911 new_masgn(parser_state *p, node *a, node *b)
913 void_expr_error(p, b);
914 return cons((node*)NODE_MASGN, cons(a, b));
917 /* (:masgn mlhs mrhs) no check */
919 new_masgn_param(parser_state *p, node *a, node *b)
921 return cons((node*)NODE_MASGN, cons(a, b));
924 /* (:asgn lhs rhs) */
926 new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
928 void_expr_error(p, b);
929 return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
933 new_imaginary(parser_state *p, node *imaginary)
935 return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
939 new_rational(parser_state *p, node *rational)
941 return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1);
946 new_int(parser_state *p, const char *s, int base, int suffix)
948 node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
949 if (suffix & NUM_SUFFIX_R) {
950 result = new_rational(p, result);
952 if (suffix & NUM_SUFFIX_I) {
953 result = new_imaginary(p, result);
958 #ifndef MRB_WITHOUT_FLOAT
961 new_float(parser_state *p, const char *s, int suffix)
963 node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
964 if (suffix & NUM_SUFFIX_R) {
965 result = new_rational(p, result);
967 if (suffix & NUM_SUFFIX_I) {
968 result = new_imaginary(p, result);
974 /* (:str . (s . len)) */
976 new_str(parser_state *p, const char *s, size_t len)
978 return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len)));
983 new_dstr(parser_state *p, node *a)
985 return cons((node*)NODE_DSTR, a);
989 string_node_p(node *n)
991 return (int)((enum node_type)(intptr_t)n->car == NODE_STR);
995 composite_string_node(parser_state *p, node *a, node *b)
997 size_t newlen = (size_t)a->cdr + (size_t)b->cdr;
998 char *str = (char*)mrb_pool_realloc(p->pool, a->car, (size_t)a->cdr + 1, newlen + 1);
999 memcpy(str + (size_t)a->cdr, b->car, (size_t)b->cdr);
1001 a->car = (node*)str;
1002 a->cdr = (node*)newlen;
1008 concat_string(parser_state *p, node *a, node *b)
1010 if (string_node_p(a)) {
1011 if (string_node_p(b)) {
1012 /* a == NODE_STR && b == NODE_STR */
1013 composite_string_node(p, a->cdr, b->cdr);
1018 /* a == NODE_STR && b == NODE_DSTR */
1020 if (string_node_p(b->cdr->car)) {
1021 /* a == NODE_STR && b->[NODE_STR, ...] */
1022 composite_string_node(p, a->cdr, b->cdr->car->cdr);
1023 cons_free(b->cdr->car);
1030 node *c; /* last node of a */
1031 for (c = a; c->cdr != NULL; c = c->cdr) ;
1033 if (string_node_p(b)) {
1034 /* a == NODE_DSTR && b == NODE_STR */
1035 if (string_node_p(c->car)) {
1036 /* a->[..., NODE_STR] && b == NODE_STR */
1037 composite_string_node(p, c->car->cdr, b->cdr);
1046 /* a == NODE_DSTR && b == NODE_DSTR */
1047 if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
1048 /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
1051 composite_string_node(p, c->car->cdr, d->car->cdr);
1065 return new_dstr(p, list2(a, b));
1068 /* (:str . (s . len)) */
1070 new_xstr(parser_state *p, const char *s, int len)
1072 return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), nint(len)));
1077 new_dxstr(parser_state *p, node *a)
1079 return cons((node*)NODE_DXSTR, a);
1084 new_dsym(parser_state *p, node *a)
1086 return cons((node*)NODE_DSYM, a);
1089 /* (:regx . (s . (opt . enc))) */
1091 new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
1093 return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
1096 /* (:dregx . (a . b)) */
1098 new_dregx(parser_state *p, node *a, node *b)
1100 return cons((node*)NODE_DREGX, cons(a, b));
1103 /* (:backref . n) */
1105 new_back_ref(parser_state *p, int n)
1107 return cons((node*)NODE_BACK_REF, nint(n));
1112 new_nth_ref(parser_state *p, int n)
1114 return cons((node*)NODE_NTH_REF, nint(n));
1117 /* (:heredoc . a) */
1119 new_heredoc(parser_state *p)
1121 parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info));
1122 return cons((node*)NODE_HEREDOC, (node*)inf);
1126 new_bv(parser_state *p, mrb_sym id)
1131 new_literal_delim(parser_state *p)
1133 return cons((node*)NODE_LITERAL_DELIM, 0);
1138 new_words(parser_state *p, node *a)
1140 return cons((node*)NODE_WORDS, a);
1143 /* (:symbols . a) */
1145 new_symbols(parser_state *p, node *a)
1147 return cons((node*)NODE_SYMBOLS, a);
1150 /* xxx ----------------------------- */
1154 call_uni_op(parser_state *p, node *recv, const char *m)
1156 void_expr_error(p, recv);
1157 return new_call(p, recv, intern_cstr(m), 0, 1);
1160 /* (:call a op b) */
1162 call_bin_op(parser_state *p, node *recv, const char *m, node *arg1)
1164 return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1);
1168 args_with_block(parser_state *p, node *a, node *b)
1172 yyerror(p, "both block arg and actual block given");
1179 call_with_block(parser_state *p, node *a, node *b)
1183 switch ((enum node_type)intn(a->car)) {
1186 if (!a->cdr) a->cdr = cons(0, b);
1188 args_with_block(p, a->cdr, b);
1194 n = a->cdr->cdr->cdr;
1195 if (!n->car) n->car = cons(0, b);
1197 args_with_block(p, n->car, b);
1206 negate_lit(parser_state *p, node *n)
1208 return cons((node*)NODE_NEGATE, n);
1218 ret_args(parser_state *p, node *n)
1221 yyerror(p, "block argument should not be given");
1224 if (!n->car->cdr) return n->car->car;
1225 return new_array(p, n->car);
1229 assignable(parser_state *p, node *lhs)
1231 if (intn(lhs->car) == NODE_LVAR) {
1232 local_add(p, sym(lhs->cdr));
1237 var_reference(parser_state *p, node *lhs)
1241 if (intn(lhs->car) == NODE_LVAR) {
1242 if (!local_var_p(p, sym(lhs->cdr))) {
1243 n = new_fcall(p, sym(lhs->cdr), 0);
1252 typedef enum mrb_string_type string_type;
1255 new_strterm(parser_state *p, string_type type, int term, int paren)
1257 return cons(nint(type), cons((node*)0, cons(nint(paren), nint(term))));
1261 end_strterm(parser_state *p)
1263 cons_free(p->lex_strterm->cdr->cdr);
1264 cons_free(p->lex_strterm->cdr);
1265 cons_free(p->lex_strterm);
1266 p->lex_strterm = NULL;
1269 static parser_heredoc_info *
1270 parsing_heredoc_inf(parser_state *p)
1272 node *nd = p->parsing_heredoc;
1275 /* mrb_assert(nd->car->car == NODE_HEREDOC); */
1276 return (parser_heredoc_info*)nd->car->cdr;
1280 heredoc_treat_nextline(parser_state *p)
1282 if (p->heredocs_from_nextline == NULL)
1284 if (p->parsing_heredoc == NULL) {
1286 p->parsing_heredoc = p->heredocs_from_nextline;
1287 p->lex_strterm_before_heredoc = p->lex_strterm;
1288 p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0);
1289 n = p->all_heredocs;
1293 n->cdr = p->parsing_heredoc;
1296 p->all_heredocs = p->parsing_heredoc;
1301 m = p->heredocs_from_nextline;
1304 n = p->all_heredocs;
1305 mrb_assert(n != NULL);
1306 if (n == p->parsing_heredoc) {
1308 p->all_heredocs = p->heredocs_from_nextline;
1309 p->parsing_heredoc = p->heredocs_from_nextline;
1312 while (n->cdr != p->parsing_heredoc) {
1314 mrb_assert(n != NULL);
1317 n->cdr = p->heredocs_from_nextline;
1318 p->parsing_heredoc = p->heredocs_from_nextline;
1321 p->heredocs_from_nextline = NULL;
1325 heredoc_end(parser_state *p)
1327 p->parsing_heredoc = p->parsing_heredoc->cdr;
1328 if (p->parsing_heredoc == NULL) {
1329 p->lstate = EXPR_BEG;
1331 p->lex_strterm = p->lex_strterm_before_heredoc;
1332 p->lex_strterm_before_heredoc = NULL;
1336 p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type);
1339 #define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func))
1341 /* xxx ----------------------------- */
1345 %define parse.error verbose
1347 %parse-param {parser_state *p}
1348 %lex-param {parser_state *p}
1355 const struct vtable *vars;
1410 %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL_TAG
1411 %token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
1412 %token <nd> tSTRING tSTRING_PART tSTRING_MID
1413 %token <nd> tNTH_REF tBACK_REF
1414 %token <num> tREGEXP_END
1415 %token <num> tNUMPARAM
1417 %type <nd> singleton string string_fragment string_rep string_interp xstring regexp
1418 %type <nd> literal numeric cpath symbol
1419 %type <nd> top_compstmt top_stmts top_stmt
1420 %type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
1421 %type <nd> expr_value arg_rhs primary_value
1422 %type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
1423 %type <nd> args call_args opt_call_args
1424 %type <nd> paren_args opt_paren_args variable
1425 %type <nd> command_args aref_args opt_block_arg block_arg var_ref var_lhs
1426 %type <nd> command_asgn command_rhs mrhs superclass block_call block_command
1427 %type <nd> f_block_optarg f_block_opt
1428 %type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_margs
1429 %type <nd> assoc_list assocs assoc undef_list backref for_var
1430 %type <nd> block_param opt_block_param block_param_def f_opt
1431 %type <nd> bv_decls opt_bv_decl bvar f_larglist lambda_body
1432 %type <nd> brace_block cmd_brace_block do_block lhs none f_bad_arg
1433 %type <nd> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
1434 %type <id> fsym sym basic_symbol operation operation2 operation3
1435 %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_opt_asgn
1436 %type <nd> heredoc words symbols
1437 %type <num> call_op call_op2 /* 0:'&.', 1:'.', 2:'::' */
1439 %type <nd> args_tail opt_args_tail f_kwarg f_kw f_kwrest
1440 %type <nd> f_block_kwarg f_block_kw block_args_tail opt_block_args_tail
1443 %token tUPLUS /* unary+ */
1444 %token tUMINUS /* unary- */
1445 %token tPOW /* ** */
1446 %token tCMP /* <=> */
1448 %token tEQQ /* === */
1449 %token tNEQ /* != */
1450 %token tGEQ /* >= */
1451 %token tLEQ /* <= */
1452 %token tANDOP tOROP /* && and || */
1453 %token tMATCH tNMATCH /* =~ and !~ */
1454 %token tDOT2 tDOT3 /* .. and ... */
1455 %token tAREF tASET /* [] and []= */
1456 %token tLSHFT tRSHFT /* << and >> */
1457 %token tCOLON2 /* :: */
1458 %token tCOLON3 /* :: at EXPR_BEG */
1459 %token <id> tOP_ASGN /* +=, -= etc. */
1460 %token tASSOC /* => */
1461 %token tLPAREN /* ( */
1462 %token tLPAREN_ARG /* ( */
1463 %token tRPAREN /* ) */
1464 %token tLBRACK /* [ */
1465 %token tLBRACE /* { */
1466 %token tLBRACE_ARG /* { */
1467 %token tSTAR /* * */
1468 %token tDSTAR /* ** */
1469 %token tAMPER /* & */
1470 %token tLAMBDA /* -> */
1471 %token tANDDOT /* &. */
1472 %token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
1473 %token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
1474 %token <nd> tHEREDOC_BEG /* <<, <<- */
1475 %token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM
1476 %token <nd> tHD_STRING_PART tHD_STRING_MID
1483 %nonassoc tLBRACE_ARG
1485 %nonassoc modifier_if modifier_unless modifier_while modifier_until
1486 %left keyword_or keyword_and
1489 %left modifier_rescue
1490 %right '?' ':' tLABEL_TAG
1491 %nonassoc tDOT2 tDOT3
1494 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
1495 %left '>' tGEQ '<' tLEQ
1501 %right tUMINUS_NUM tUMINUS
1503 %right '!' '~' tUPLUS
1509 p->lstate = EXPR_BEG;
1510 if (!p->locals) p->locals = cons(0,0);
1514 p->tree = new_scope(p, $2);
1515 NODE_LINENO(p->tree, $2);
1519 top_compstmt : top_stmts opt_terms
1527 $$ = new_begin(p, 0);
1531 $$ = new_begin(p, $1);
1532 NODE_LINENO($$, $1);
1534 | top_stmts terms top_stmt
1536 $$ = push($1, newline_node($3));
1540 $$ = new_begin(p, 0);
1547 $<nd>$ = local_switch(p);
1550 '{' top_compstmt '}'
1552 yyerror(p, "BEGIN not supported");
1553 local_resume(p, $<nd>2);
1565 $$ = new_rescue(p, $1, $2, $3);
1566 NODE_LINENO($$, $1);
1569 yywarn(p, "else without rescue is useless");
1577 $$ = new_ensure(p, $$, $4);
1580 $$ = push($4, new_nil(p));
1586 compstmt : stmts opt_terms
1594 $$ = new_begin(p, 0);
1598 $$ = new_begin(p, $1);
1599 NODE_LINENO($$, $1);
1603 $$ = push($1, newline_node($3));
1607 $$ = new_begin(p, $2);
1611 stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
1613 $$ = new_alias(p, $2, $4);
1615 | keyword_undef undef_list
1619 | stmt modifier_if expr_value
1621 $$ = new_if(p, cond($3), $1, 0);
1623 | stmt modifier_unless expr_value
1625 $$ = new_unless(p, cond($3), $1, 0);
1627 | stmt modifier_while expr_value
1629 $$ = new_while(p, cond($3), $1);
1631 | stmt modifier_until expr_value
1633 $$ = new_until(p, cond($3), $1);
1635 | stmt modifier_rescue stmt
1637 $$ = new_mod_rescue(p, $1, $3);
1639 | keyword_END '{' compstmt '}'
1641 yyerror(p, "END not supported");
1642 $$ = new_postexe(p, $3);
1645 | mlhs '=' command_call
1647 $$ = new_masgn(p, $1, $3);
1651 $$ = new_asgn(p, $1, new_array(p, $3));
1655 $$ = new_masgn(p, $1, $3);
1659 $$ = new_masgn(p, $1, new_array(p, $3));
1664 command_asgn : lhs '=' command_rhs
1666 $$ = new_asgn(p, $1, $3);
1668 | var_lhs tOP_ASGN command_rhs
1670 $$ = new_op_asgn(p, $1, $2, $3);
1672 | primary_value '[' opt_call_args ']' tOP_ASGN command_rhs
1674 $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
1676 | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
1678 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
1680 | primary_value call_op tCONSTANT tOP_ASGN command_rhs
1682 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
1684 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1686 yyerror(p, "constant re-assignment");
1689 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
1691 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
1693 | backref tOP_ASGN command_rhs
1695 backref_error(p, $1);
1696 $$ = new_begin(p, 0);
1700 command_rhs : command_call %prec tOP_ASGN
1701 | command_call modifier_rescue stmt
1703 $$ = new_mod_rescue(p, $1, $3);
1710 | expr keyword_and expr
1712 $$ = new_and(p, $1, $3);
1714 | expr keyword_or expr
1716 $$ = new_or(p, $1, $3);
1718 | keyword_not opt_nl expr
1720 $$ = call_uni_op(p, cond($3), "!");
1724 $$ = call_uni_op(p, cond($2), "!");
1731 if (!$1) $$ = new_nil(p);
1738 command_call : command
1742 block_command : block_call
1743 | block_call call_op2 operation2 command_args
1745 $$ = new_call(p, $1, $3, $4, $2);
1749 cmd_brace_block : tLBRACE_ARG
1758 $$ = new_block(p, $3, $4);
1764 command : operation command_args %prec tLOWEST
1766 $$ = new_fcall(p, $1, $2);
1768 | operation command_args cmd_brace_block
1770 args_with_block(p, $2, $3);
1771 $$ = new_fcall(p, $1, $2);
1773 | primary_value call_op operation2 command_args %prec tLOWEST
1775 $$ = new_call(p, $1, $3, $4, $2);
1777 | primary_value call_op operation2 command_args cmd_brace_block
1779 args_with_block(p, $4, $5);
1780 $$ = new_call(p, $1, $3, $4, $2);
1782 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1784 $$ = new_call(p, $1, $3, $4, tCOLON2);
1786 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1788 args_with_block(p, $4, $5);
1789 $$ = new_call(p, $1, $3, $4, tCOLON2);
1791 | keyword_super command_args
1793 $$ = new_super(p, $2);
1795 | keyword_yield command_args
1797 $$ = new_yield(p, $2);
1799 | keyword_return call_args
1801 $$ = new_return(p, ret_args(p, $2));
1803 | keyword_break call_args
1805 $$ = new_break(p, ret_args(p, $2));
1807 | keyword_next call_args
1809 $$ = new_next(p, ret_args(p, $2));
1817 | tLPAREN mlhs_inner rparen
1823 mlhs_inner : mlhs_basic
1824 | tLPAREN mlhs_inner rparen
1830 mlhs_basic : mlhs_list
1834 | mlhs_list mlhs_item
1836 $$ = list1(push($1,$2));
1838 | mlhs_list tSTAR mlhs_node
1842 | mlhs_list tSTAR mlhs_node ',' mlhs_post
1844 $$ = list3($1, $3, $5);
1848 $$ = list2($1, new_nil(p));
1850 | mlhs_list tSTAR ',' mlhs_post
1852 $$ = list3($1, new_nil(p), $4);
1858 | tSTAR mlhs_node ',' mlhs_post
1860 $$ = list3(0, $2, $4);
1864 $$ = list2(0, new_nil(p));
1866 | tSTAR ',' mlhs_post
1868 $$ = list3(0, new_nil(p), $3);
1872 mlhs_item : mlhs_node
1873 | tLPAREN mlhs_inner rparen
1875 $$ = new_masgn(p, $2, NULL);
1879 mlhs_list : mlhs_item ','
1883 | mlhs_list mlhs_item ','
1889 mlhs_post : mlhs_item
1893 | mlhs_list mlhs_item
1899 mlhs_node : variable
1903 | primary_value '[' opt_call_args ']'
1905 $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
1907 | primary_value call_op tIDENTIFIER
1909 $$ = new_call(p, $1, $3, 0, $2);
1911 | primary_value tCOLON2 tIDENTIFIER
1913 $$ = new_call(p, $1, $3, 0, tCOLON2);
1915 | primary_value call_op tCONSTANT
1917 $$ = new_call(p, $1, $3, 0, $2);
1919 | primary_value tCOLON2 tCONSTANT
1921 if (p->in_def || p->in_single)
1922 yyerror(p, "dynamic constant assignment");
1923 $$ = new_colon2(p, $1, $3);
1927 if (p->in_def || p->in_single)
1928 yyerror(p, "dynamic constant assignment");
1929 $$ = new_colon3(p, $2);
1933 backref_error(p, $1);
1942 | primary_value '[' opt_call_args ']'
1944 $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
1946 | primary_value call_op tIDENTIFIER
1948 $$ = new_call(p, $1, $3, 0, $2);
1950 | primary_value tCOLON2 tIDENTIFIER
1952 $$ = new_call(p, $1, $3, 0, tCOLON2);
1954 | primary_value call_op tCONSTANT
1956 $$ = new_call(p, $1, $3, 0, $2);
1958 | primary_value tCOLON2 tCONSTANT
1960 if (p->in_def || p->in_single)
1961 yyerror(p, "dynamic constant assignment");
1962 $$ = new_colon2(p, $1, $3);
1966 if (p->in_def || p->in_single)
1967 yyerror(p, "dynamic constant assignment");
1968 $$ = new_colon3(p, $2);
1972 backref_error(p, $1);
1977 yyerror(p, "can't assign to numbered parameter");
1983 yyerror(p, "class/module name must be CONSTANT");
1988 cpath : tCOLON3 cname
1990 $$ = cons((node*)1, nsym($2));
1994 $$ = cons((node*)0, nsym($1));
1996 | primary_value tCOLON2 cname
1998 void_expr_error(p, $1);
1999 $$ = cons($1, nsym($3));
2008 p->lstate = EXPR_ENDFN;
2013 p->lstate = EXPR_ENDFN;
2024 $$ = new_undef(p, $1);
2026 | undef_list ',' {p->lstate = EXPR_FNAME;} fsym
2028 $$ = push($1, nsym($4));
2032 op : '|' { $$ = intern_lit("|"); }
2033 | '^' { $$ = intern_lit("^"); }
2034 | '&' { $$ = intern_lit("&"); }
2035 | tCMP { $$ = intern_lit("<=>"); }
2036 | tEQ { $$ = intern_lit("=="); }
2037 | tEQQ { $$ = intern_lit("==="); }
2038 | tMATCH { $$ = intern_lit("=~"); }
2039 | tNMATCH { $$ = intern_lit("!~"); }
2040 | '>' { $$ = intern_lit(">"); }
2041 | tGEQ { $$ = intern_lit(">="); }
2042 | '<' { $$ = intern_lit("<"); }
2043 | tLEQ { $$ = intern_lit("<="); }
2044 | tNEQ { $$ = intern_lit("!="); }
2045 | tLSHFT { $$ = intern_lit("<<"); }
2046 | tRSHFT { $$ = intern_lit(">>"); }
2047 | '+' { $$ = intern_lit("+"); }
2048 | '-' { $$ = intern_lit("-"); }
2049 | '*' { $$ = intern_lit("*"); }
2050 | tSTAR { $$ = intern_lit("*"); }
2051 | '/' { $$ = intern_lit("/"); }
2052 | '%' { $$ = intern_lit("%"); }
2053 | tPOW { $$ = intern_lit("**"); }
2054 | tDSTAR { $$ = intern_lit("**"); }
2055 | '!' { $$ = intern_lit("!"); }
2056 | '~' { $$ = intern_lit("~"); }
2057 | tUPLUS { $$ = intern_lit("+@"); }
2058 | tUMINUS { $$ = intern_lit("-@"); }
2059 | tAREF { $$ = intern_lit("[]"); }
2060 | tASET { $$ = intern_lit("[]="); }
2061 | '`' { $$ = intern_lit("`"); }
2064 reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
2065 | keyword_BEGIN | keyword_END
2066 | keyword_alias | keyword_and | keyword_begin
2067 | keyword_break | keyword_case | keyword_class | keyword_def
2068 | keyword_do | keyword_else | keyword_elsif
2069 | keyword_end | keyword_ensure | keyword_false
2070 | keyword_for | keyword_in | keyword_module | keyword_next
2071 | keyword_nil | keyword_not | keyword_or | keyword_redo
2072 | keyword_rescue | keyword_retry | keyword_return | keyword_self
2073 | keyword_super | keyword_then | keyword_true | keyword_undef
2074 | keyword_when | keyword_yield | keyword_if | keyword_unless
2075 | keyword_while | keyword_until
2078 arg : lhs '=' arg_rhs
2080 $$ = new_asgn(p, $1, $3);
2082 | var_lhs tOP_ASGN arg_rhs
2084 $$ = new_op_asgn(p, $1, $2, $3);
2086 | primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs
2088 $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
2090 | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
2092 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
2094 | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
2096 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
2098 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
2100 $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
2102 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
2104 yyerror(p, "constant re-assignment");
2105 $$ = new_begin(p, 0);
2107 | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
2109 yyerror(p, "constant re-assignment");
2110 $$ = new_begin(p, 0);
2112 | backref tOP_ASGN arg_rhs
2114 backref_error(p, $1);
2115 $$ = new_begin(p, 0);
2119 $$ = new_dot2(p, $1, $3);
2123 $$ = new_dot3(p, $1, $3);
2127 $$ = call_bin_op(p, $1, "+", $3);
2131 $$ = call_bin_op(p, $1, "-", $3);
2135 $$ = call_bin_op(p, $1, "*", $3);
2139 $$ = call_bin_op(p, $1, "/", $3);
2143 $$ = call_bin_op(p, $1, "%", $3);
2147 $$ = call_bin_op(p, $1, "**", $3);
2149 | tUMINUS_NUM tINTEGER tPOW arg
2151 $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
2153 | tUMINUS_NUM tFLOAT tPOW arg
2155 $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
2159 $$ = call_uni_op(p, $2, "+@");
2163 $$ = call_uni_op(p, $2, "-@");
2167 $$ = call_bin_op(p, $1, "|", $3);
2171 $$ = call_bin_op(p, $1, "^", $3);
2175 $$ = call_bin_op(p, $1, "&", $3);
2179 $$ = call_bin_op(p, $1, "<=>", $3);
2183 $$ = call_bin_op(p, $1, ">", $3);
2187 $$ = call_bin_op(p, $1, ">=", $3);
2191 $$ = call_bin_op(p, $1, "<", $3);
2195 $$ = call_bin_op(p, $1, "<=", $3);
2199 $$ = call_bin_op(p, $1, "==", $3);
2203 $$ = call_bin_op(p, $1, "===", $3);
2207 $$ = call_bin_op(p, $1, "!=", $3);
2211 $$ = call_bin_op(p, $1, "=~", $3);
2215 $$ = call_bin_op(p, $1, "!~", $3);
2219 $$ = call_uni_op(p, cond($2), "!");
2223 $$ = call_uni_op(p, cond($2), "~");
2227 $$ = call_bin_op(p, $1, "<<", $3);
2231 $$ = call_bin_op(p, $1, ">>", $3);
2235 $$ = new_and(p, $1, $3);
2239 $$ = new_or(p, $1, $3);
2241 | arg '?' arg opt_nl ':' arg
2243 $$ = new_if(p, cond($1), $3, $6);
2245 | arg '?' arg opt_nl tLABEL_TAG arg
2247 $$ = new_if(p, cond($1), $3, $6);
2259 NODE_LINENO($$, $1);
2261 | args comma assocs trailer
2263 $$ = push($1, new_kw_hash(p, $3));
2267 $$ = cons(new_kw_hash(p, $1), 0);
2268 NODE_LINENO($$, $1);
2272 arg_rhs : arg %prec tOP_ASGN
2276 | arg modifier_rescue arg
2278 void_expr_error(p, $1);
2279 void_expr_error(p, $3);
2280 $$ = new_mod_rescue(p, $1, $3);
2284 paren_args : '(' opt_call_args ')'
2291 mrb_sym r = mrb_intern_lit(p->mrb, "*");
2292 mrb_sym b = mrb_intern_lit(p->mrb, "&");
2293 if (local_var_p(p, r) && local_var_p(p, b)) {
2294 $$ = cons(list1(new_splat(p, new_lvar(p, r))),
2295 new_block_arg(p, new_lvar(p, b)));
2298 mrb_sym r = mrb_intern_lit(p->mrb, "*");
2299 mrb_sym k = mrb_intern_lit(p->mrb, "**");
2300 mrb_sym b = mrb_intern_lit(p->mrb, "&");
2301 if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
2302 $$ = cons(list2(new_splat(p, new_lvar(p, r)),
2303 new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
2304 new_block_arg(p, new_lvar(p, b)));
2308 yyerror(p, "unexpected argument forwarding ...");
2314 opt_paren_args : none
2318 opt_call_args : none
2319 | call_args opt_terms
2323 NODE_LINENO($$, $1);
2325 | args comma assocs comma
2327 $$ = cons(push($1, new_kw_hash(p, $3)), 0);
2328 NODE_LINENO($$, $1);
2332 $$ = cons(list1(new_kw_hash(p, $1)), 0);
2333 NODE_LINENO($$, $1);
2339 void_expr_error(p, $1);
2340 $$ = cons(list1($1), 0);
2341 NODE_LINENO($$, $1);
2343 | args opt_block_arg
2346 NODE_LINENO($$, $1);
2348 | assocs opt_block_arg
2350 $$ = cons(list1(new_kw_hash(p, $1)), $2);
2351 NODE_LINENO($$, $1);
2353 | args comma assocs opt_block_arg
2355 $$ = cons(push($1, new_kw_hash(p, $3)), $4);
2356 NODE_LINENO($$, $1);
2361 NODE_LINENO($$, $1);
2366 $<stack>$ = p->cmdarg_stack;
2371 p->cmdarg_stack = $<stack>1;
2376 block_arg : tAMPER arg
2378 $$ = new_block_arg(p, $2);
2382 opt_block_arg : comma block_arg
2393 | ',' opt_nl heredoc_bodies
2398 void_expr_error(p, $1);
2400 NODE_LINENO($$, $1);
2404 void_expr_error(p, $2);
2405 $$ = cons(new_splat(p, $2), 0);
2406 NODE_LINENO($$, $2);
2410 void_expr_error(p, $3);
2413 | args comma tSTAR arg
2415 void_expr_error(p, $4);
2416 $$ = push($1, new_splat(p, $4));
2420 mrhs : args comma arg
2422 void_expr_error(p, $3);
2425 | args comma tSTAR arg
2427 void_expr_error(p, $4);
2428 $$ = push($1, new_splat(p, $4));
2432 void_expr_error(p, $2);
2433 $$ = list1(new_splat(p, $2));
2446 $$ = new_nvar(p, $1);
2450 $$ = new_fcall(p, $1, 0);
2454 $<stack>$ = p->cmdarg_stack;
2455 p->cmdarg_stack = 0;
2460 p->cmdarg_stack = $<stack>2;
2465 $<stack>$ = p->cmdarg_stack;
2466 p->cmdarg_stack = 0;
2468 stmt {p->lstate = EXPR_ENDARG;} rparen
2470 p->cmdarg_stack = $<stack>2;
2473 | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen
2477 | tLPAREN compstmt ')'
2481 | primary_value tCOLON2 tCONSTANT
2483 $$ = new_colon2(p, $1, $3);
2487 $$ = new_colon3(p, $2);
2489 | tLBRACK aref_args ']'
2491 $$ = new_array(p, $2);
2492 NODE_LINENO($$, $2);
2494 | tLBRACE assoc_list '}'
2496 $$ = new_hash(p, $2);
2497 NODE_LINENO($$, $2);
2501 $$ = new_return(p, 0);
2503 | keyword_yield opt_paren_args
2505 $$ = new_yield(p, $2);
2507 | keyword_not '(' expr rparen
2509 $$ = call_uni_op(p, cond($3), "!");
2511 | keyword_not '(' rparen
2513 $$ = call_uni_op(p, new_nil(p), "!");
2515 | operation brace_block
2517 $$ = new_fcall(p, $1, cons(0, $2));
2520 | method_call brace_block
2522 call_with_block(p, $1, $2);
2528 $<num>$ = p->lpar_beg;
2529 p->lpar_beg = ++p->paren_nest;
2533 $<stack>$ = p->cmdarg_stack;
2534 p->cmdarg_stack = 0;
2538 p->lpar_beg = $<num>2;
2539 $$ = new_lambda(p, $3, $5);
2541 p->cmdarg_stack = $<stack>4;
2544 | keyword_if expr_value then
2549 $$ = new_if(p, cond($2), $4, $5);
2552 | keyword_unless expr_value then
2557 $$ = new_unless(p, cond($2), $4, $5);
2560 | keyword_while {COND_PUSH(1);} expr_value do {COND_POP();}
2564 $$ = new_while(p, cond($3), $6);
2567 | keyword_until {COND_PUSH(1);} expr_value do {COND_POP();}
2571 $$ = new_until(p, cond($3), $6);
2574 | keyword_case expr_value opt_terms
2578 $$ = new_case(p, $2, $4);
2580 | keyword_case opt_terms case_body keyword_end
2582 $$ = new_case(p, 0, $3);
2584 | keyword_for for_var keyword_in
2591 $$ = new_for(p, $2, $5, $8);
2597 if (p->in_def || p->in_single)
2598 yyerror(p, "class definition in method body");
2599 $<nd>$ = local_switch(p);
2605 $$ = new_class(p, $2, $3, $5);
2607 local_resume(p, $<nd>4);
2613 $<num>$ = p->in_def;
2618 $<nd>$ = cons(local_switch(p), nint(p->in_single));
2625 $$ = new_sclass(p, $3, $7);
2627 local_resume(p, $<nd>6->car);
2629 p->in_def = $<num>4;
2630 p->in_single = intn($<nd>6->cdr);
2635 if (p->in_def || p->in_single)
2636 yyerror(p, "module definition in method body");
2637 $<nd>$ = local_switch(p);
2643 $$ = new_module(p, $2, $4);
2645 local_resume(p, $<nd>3);
2650 $<stack>$ = p->cmdarg_stack;
2651 p->cmdarg_stack = 0;
2655 $<nd>$ = local_switch(p);
2662 $$ = new_def(p, $2, $5, $6);
2664 local_resume(p, $<nd>4);
2667 p->cmdarg_stack = $<stack>3;
2669 | keyword_def singleton dot_or_colon
2671 p->lstate = EXPR_FNAME;
2672 $<stack>$ = p->cmdarg_stack;
2673 p->cmdarg_stack = 0;
2678 p->lstate = EXPR_ENDFN; /* force for args */
2679 $<nd>$ = local_switch(p);
2686 $$ = new_sdef(p, $2, $5, $7, $8);
2688 local_resume(p, $<nd>6);
2691 p->cmdarg_stack = $<stack>4;
2695 $$ = new_break(p, 0);
2699 $$ = new_next(p, 0);
2711 primary_value : primary
2714 if (!$$) $$ = new_nil(p);
2728 | keyword_elsif expr_value then
2732 $$ = new_if(p, cond($2), $4, $5);
2737 | keyword_else compstmt
2745 $$ = list1(list1($1));
2754 | f_arg ',' tSTAR f_norm_arg
2756 $$ = list3($1, new_arg(p, $4), 0);
2758 | f_arg ',' tSTAR f_norm_arg ',' f_arg
2760 $$ = list3($1, new_arg(p, $4), $6);
2765 $$ = list3($1, (node*)-1, 0);
2767 | f_arg ',' tSTAR ',' f_arg
2769 $$ = list3($1, (node*)-1, $5);
2773 $$ = list3(0, new_arg(p, $2), 0);
2775 | tSTAR f_norm_arg ',' f_arg
2777 $$ = list3(0, new_arg(p, $2), $4);
2782 $$ = list3(0, (node*)-1, 0);
2790 $$ = list3(0, (node*)-1, $4);
2794 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
2796 $$ = new_args_tail(p, $1, $3, $4);
2798 | f_block_kwarg opt_f_block_arg
2800 $$ = new_args_tail(p, $1, 0, $2);
2802 | f_kwrest opt_f_block_arg
2804 $$ = new_args_tail(p, 0, $1, $2);
2808 $$ = new_args_tail(p, 0, 0, $1);
2812 opt_block_args_tail : ',' block_args_tail
2818 $$ = new_args_tail(p, 0, 0, 0);
2822 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
2824 $$ = new_args(p, $1, $3, $5, 0, $6);
2826 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
2828 $$ = new_args(p, $1, $3, $5, $7, $8);
2830 | f_arg ',' f_block_optarg opt_block_args_tail
2832 $$ = new_args(p, $1, $3, 0, 0, $4);
2834 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
2836 $$ = new_args(p, $1, $3, 0, $5, $6);
2838 | f_arg ',' f_rest_arg opt_block_args_tail
2840 $$ = new_args(p, $1, 0, $3, 0, $4);
2842 | f_arg ',' opt_block_args_tail
2844 $$ = new_args(p, $1, 0, 0, 0, $3);
2846 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
2848 $$ = new_args(p, $1, 0, $3, $5, $6);
2850 | f_arg opt_block_args_tail
2852 $$ = new_args(p, $1, 0, 0, 0, $2);
2854 | f_block_optarg ',' f_rest_arg opt_block_args_tail
2856 $$ = new_args(p, 0, $1, $3, 0, $4);
2858 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
2860 $$ = new_args(p, 0, $1, $3, $5, $6);
2862 | f_block_optarg opt_block_args_tail
2864 $$ = new_args(p, 0, $1, 0, 0, $2);
2866 | f_block_optarg ',' f_arg opt_block_args_tail
2868 $$ = new_args(p, 0, $1, 0, $3, $4);
2870 | f_rest_arg opt_block_args_tail
2872 $$ = new_args(p, 0, 0, $1, 0, $2);
2874 | f_rest_arg ',' f_arg opt_block_args_tail
2876 $$ = new_args(p, 0, 0, $1, $3, $4);
2880 $$ = new_args(p, 0, 0, 0, 0, $1);
2884 opt_block_param : none
2886 local_add_blk(p, 0);
2891 p->cmd_start = TRUE;
2896 block_param_def : '|' {local_add_blk(p, 0);} opt_bv_decl '|'
2902 local_add_blk(p, 0);
2905 | '|' block_param opt_bv_decl '|'
2912 opt_bv_decl : opt_nl
2916 | opt_nl ';' bv_decls opt_nl
2934 f_larglist : '(' f_args opt_bv_decl ')'
2944 lambda_body : tLAMBEG compstmt '}'
2948 | keyword_do_LAMBDA bodystmt keyword_end
2954 do_block : keyword_do_block
2963 $$ = new_block(p,$3,$4);
2969 block_call : command do_block
2971 if ($1->car == (node*)NODE_YIELD) {
2972 yyerror(p, "block given to yield");
2975 call_with_block(p, $1, $2);
2979 | block_call call_op2 operation2 opt_paren_args
2981 $$ = new_call(p, $1, $3, $4, $2);
2983 | block_call call_op2 operation2 opt_paren_args brace_block
2985 $$ = new_call(p, $1, $3, $4, $2);
2986 call_with_block(p, $$, $5);
2988 | block_call call_op2 operation2 command_args do_block
2990 $$ = new_call(p, $1, $3, $4, $2);
2991 call_with_block(p, $$, $5);
2995 method_call : operation paren_args
2997 $$ = new_fcall(p, $1, $2);
2999 | primary_value call_op operation2 opt_paren_args
3001 $$ = new_call(p, $1, $3, $4, $2);
3003 | primary_value tCOLON2 operation2 paren_args
3005 $$ = new_call(p, $1, $3, $4, tCOLON2);
3007 | primary_value tCOLON2 operation3
3009 $$ = new_call(p, $1, $3, 0, tCOLON2);
3011 | primary_value call_op paren_args
3013 $$ = new_call(p, $1, intern_lit("call"), $3, $2);
3015 | primary_value tCOLON2 paren_args
3017 $$ = new_call(p, $1, intern_lit("call"), $3, tCOLON2);
3019 | keyword_super paren_args
3021 $$ = new_super(p, $2);
3027 | primary_value '[' opt_call_args ']'
3029 $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
3037 $<num>$ = p->lineno;
3042 $$ = new_block(p,$3,$4);
3043 SET_LINENO($$, $<num>2);
3051 $<num>$ = p->lineno;
3054 bodystmt keyword_end
3056 $$ = new_block(p,$3,$4);
3057 SET_LINENO($$, $<num>2);
3063 case_body : keyword_when args then
3067 $$ = cons(cons($2, $4), $5);
3074 $$ = cons(cons(0, $1), 0);
3083 opt_rescue : keyword_rescue exc_list exc_var then
3087 $$ = list1(list3($2, $3, $5));
3088 if ($6) $$ = append($$, $6);
3101 exc_var : tASSOC lhs
3108 opt_ensure : keyword_ensure compstmt
3121 string : string_fragment
3122 | string string_fragment
3124 $$ = concat_string(p, $1, $2);
3128 string_fragment : tCHAR
3130 | tSTRING_BEG tSTRING
3134 | tSTRING_BEG string_rep tSTRING
3136 $$ = new_dstr(p, push($2, $3));
3140 string_rep : string_interp
3141 | string_rep string_interp
3143 $$ = append($1, $2);
3147 string_interp : tSTRING_MID
3153 $<nd>$ = p->lex_strterm;
3154 p->lex_strterm = NULL;
3159 p->lex_strterm = $<nd>2;
3164 $$ = list1(new_literal_delim(p));
3166 | tHD_LITERAL_DELIM heredoc_bodies
3168 $$ = list1(new_literal_delim(p));
3172 xstring : tXSTRING_BEG tXSTRING
3176 | tXSTRING_BEG string_rep tXSTRING
3178 $$ = new_dxstr(p, push($2, $3));
3182 regexp : tREGEXP_BEG tREGEXP
3186 | tREGEXP_BEG string_rep tREGEXP
3188 $$ = new_dregx(p, $2, $3);
3192 heredoc : tHEREDOC_BEG
3195 heredoc_bodies : heredoc_body
3196 | heredoc_bodies heredoc_body
3199 heredoc_body : tHEREDOC_END
3201 parser_heredoc_info * inf = parsing_heredoc_inf(p);
3202 inf->doc = push(inf->doc, new_str(p, "", 0));
3205 | heredoc_string_rep tHEREDOC_END
3211 heredoc_string_rep : heredoc_string_interp
3212 | heredoc_string_rep heredoc_string_interp
3215 heredoc_string_interp : tHD_STRING_MID
3217 parser_heredoc_info * inf = parsing_heredoc_inf(p);
3218 inf->doc = push(inf->doc, $1);
3219 heredoc_treat_nextline(p);
3223 $<nd>$ = p->lex_strterm;
3224 p->lex_strterm = NULL;
3229 parser_heredoc_info * inf = parsing_heredoc_inf(p);
3230 p->lex_strterm = $<nd>2;
3231 inf->doc = push(push(inf->doc, $1), $3);
3235 words : tWORDS_BEG tSTRING
3237 $$ = new_words(p, list1($2));
3239 | tWORDS_BEG string_rep tSTRING
3241 $$ = new_words(p, push($2, $3));
3246 symbol : basic_symbol
3248 p->lstate = EXPR_ENDARG;
3249 $$ = new_sym(p, $1);
3251 | tSYMBEG tSTRING_BEG string_rep tSTRING
3253 p->lstate = EXPR_ENDARG;
3254 $$ = new_dsym(p, new_dstr(p, push($3, $4)));
3258 basic_symbol : tSYMBEG sym
3270 $$ = new_strsym(p, $1);
3272 | tSTRING_BEG tSTRING
3274 $$ = new_strsym(p, $2);
3278 symbols : tSYMBOLS_BEG tSTRING
3280 $$ = new_symbols(p, list1($2));
3282 | tSYMBOLS_BEG string_rep tSTRING
3284 $$ = new_symbols(p, push($2, $3));
3290 | tUMINUS_NUM tINTEGER %prec tLOWEST
3292 $$ = negate_lit(p, $2);
3294 | tUMINUS_NUM tFLOAT %prec tLOWEST
3296 $$ = negate_lit(p, $2);
3300 variable : tIDENTIFIER
3302 $$ = new_lvar(p, $1);
3306 $$ = new_ivar(p, $1);
3310 $$ = new_gvar(p, $1);
3314 $$ = new_cvar(p, $1);
3318 $$ = new_const(p, $1);
3328 yyerror(p, "can't assign to numbered parameter");
3334 $$ = var_reference(p, $1);
3354 const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
3358 $$ = new_str(p, fn, strlen(fn));
3364 dump_int(p->lineno, buf);
3365 $$ = new_int(p, buf, 10, 0);
3367 | keyword__ENCODING__
3369 #ifdef MRB_UTF8_STRING
3370 const char *enc = "UTF-8";
3372 const char *enc = "ASCII-8BIT";
3374 $$ = new_str(p, enc, strlen(enc));
3382 superclass : /* term */
3388 p->lstate = EXPR_BEG;
3389 p->cmd_start = TRUE;
3402 f_arglist : '(' f_args rparen
3405 p->lstate = EXPR_BEG;
3406 p->cmd_start = TRUE;
3411 /* til real keyword args implemented */
3412 mrb_sym r = mrb_intern_lit(p->mrb, "*");
3413 mrb_sym b = mrb_intern_lit(p->mrb, "&");
3415 $$ = new_args(p, 0, 0, r, 0,
3416 new_args_tail(p, 0, 0, b));
3418 mrb_sym r = mrb_intern_lit(p->mrb, "*");
3419 mrb_sym k = mrb_intern_lit(p->mrb, "**");
3420 mrb_sym b = mrb_intern_lit(p->mrb, "&");
3421 local_add_f(p, r); local_add_f(p, k);
3422 $$ = new_args(p, 0, 0, r, 0,
3423 new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
3432 f_label : tIDENTIFIER tLABEL_TAG
3440 void_expr_error(p, $2);
3441 $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
3446 $$ = new_kw_arg(p, $1, 0);
3451 f_block_kw : f_label primary_value
3453 $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
3458 $$ = new_kw_arg(p, $1, 0);
3463 f_block_kwarg : f_block_kw
3467 | f_block_kwarg ',' f_block_kw
3487 f_kwrest : kwrest_mark tIDENTIFIER
3489 $$ = new_kw_rest_args(p, nsym($2));
3493 $$ = new_kw_rest_args(p, 0);
3497 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
3499 $$ = new_args_tail(p, $1, $3, $4);
3501 | f_kwarg opt_f_block_arg
3503 $$ = new_args_tail(p, $1, 0, $2);
3505 | f_kwrest opt_f_block_arg
3507 $$ = new_args_tail(p, 0, $1, $2);
3511 $$ = new_args_tail(p, 0, 0, $1);
3515 opt_args_tail : ',' args_tail
3521 $$ = new_args_tail(p, 0, 0, 0);
3525 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
3527 $$ = new_args(p, $1, $3, $5, 0, $6);
3529 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
3531 $$ = new_args(p, $1, $3, $5, $7, $8);
3533 | f_arg ',' f_optarg opt_args_tail
3535 $$ = new_args(p, $1, $3, 0, 0, $4);
3537 | f_arg ',' f_optarg ',' f_arg opt_args_tail
3539 $$ = new_args(p, $1, $3, 0, $5, $6);
3541 | f_arg ',' f_rest_arg opt_args_tail
3543 $$ = new_args(p, $1, 0, $3, 0, $4);
3545 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
3547 $$ = new_args(p, $1, 0, $3, $5, $6);
3549 | f_arg opt_args_tail
3551 $$ = new_args(p, $1, 0, 0, 0, $2);
3553 | f_optarg ',' f_rest_arg opt_args_tail
3555 $$ = new_args(p, 0, $1, $3, 0, $4);
3557 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
3559 $$ = new_args(p, 0, $1, $3, $5, $6);
3561 | f_optarg opt_args_tail
3563 $$ = new_args(p, 0, $1, 0, 0, $2);
3565 | f_optarg ',' f_arg opt_args_tail
3567 $$ = new_args(p, 0, $1, 0, $3, $4);
3569 | f_rest_arg opt_args_tail
3571 $$ = new_args(p, 0, 0, $1, 0, $2);
3573 | f_rest_arg ',' f_arg opt_args_tail
3575 $$ = new_args(p, 0, 0, $1, $3, $4);
3579 $$ = new_args(p, 0, 0, 0, 0, $1);
3583 local_add_f(p, mrb_intern_lit(p->mrb, "&"));
3584 $$ = new_args(p, 0, 0, 0, 0, 0);
3588 f_bad_arg : tCONSTANT
3590 yyerror(p, "formal argument cannot be a constant");
3595 yyerror(p, "formal argument cannot be an instance variable");
3600 yyerror(p, "formal argument cannot be a global variable");
3605 yyerror(p, "formal argument cannot be a class variable");
3610 yyerror(p, "formal argument cannot be a numbered parameter");
3615 f_norm_arg : f_bad_arg
3626 f_arg_item : f_norm_arg
3628 $$ = new_arg(p, $1);
3632 $<nd>$ = local_switch(p);
3636 $$ = new_masgn_param(p, $3, p->locals->car);
3637 local_resume(p, $<nd>2);
3646 | f_arg ',' f_arg_item
3652 f_opt_asgn : tIDENTIFIER '='
3660 f_opt : f_opt_asgn arg
3662 void_expr_error(p, $2);
3663 $$ = cons(nsym($1), cons($2, locals_node(p)));
3668 f_block_opt : f_opt_asgn primary_value
3670 void_expr_error(p, $2);
3671 $$ = cons(nsym($1), cons($2, locals_node(p)));
3676 f_block_optarg : f_block_opt
3680 | f_block_optarg ',' f_block_opt
3690 | f_optarg ',' f_opt
3700 f_rest_arg : restarg_mark tIDENTIFIER
3707 local_add_f(p, mrb_intern_lit(p->mrb, "*"));
3716 f_block_arg : blkarg_mark tIDENTIFIER
3722 opt_f_block_arg : ',' f_block_arg
3735 if (!$$) $$ = new_nil(p);
3737 | '(' {p->lstate = EXPR_BEG;} expr rparen
3740 yyerror(p, "can't define singleton method for ().");
3743 switch ((enum node_type)intn($3->car)) {
3753 yyerror(p, "can't define singleton method for literals");
3772 NODE_LINENO($$, $1);
3774 | assocs comma assoc
3780 label_tag : tLABEL_TAG
3781 | tLABEL_TAG heredoc_bodies
3784 assoc : arg tASSOC arg
3786 void_expr_error(p, $1);
3787 void_expr_error(p, $3);
3790 | tIDENTIFIER label_tag arg
3792 void_expr_error(p, $3);
3793 $$ = cons(new_sym(p, $1), $3);
3795 | string_fragment label_tag arg
3797 void_expr_error(p, $3);
3798 if ($1->car == (node*)NODE_DSTR) {
3799 $$ = cons(new_dsym(p, $1), $3);
3802 $$ = cons(new_sym(p, new_strsym(p, $1)), $3);
3807 void_expr_error(p, $2);
3808 $$ = cons(new_kw_rest_args(p, 0), $2);
3812 operation : tIDENTIFIER
3817 operation2 : tIDENTIFIER
3823 operation3 : tIDENTIFIER
3849 opt_terms : /* none */
3857 rparen : opt_terms ')'
3860 trailer : /* none */
3865 term : ';' {yyerrok;}
3872 p->lineno += $<num>1;
3887 #define pylval (*((YYSTYPE*)(p->ylval)))
3890 yyerror(parser_state *p, const char *s)
3895 if (! p->capture_errors) {
3896 #ifndef MRB_DISABLE_STDIO
3897 if (p->filename_sym) {
3898 const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
3899 fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s);
3902 fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
3906 else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) {
3908 c = (char *)parser_palloc(p, n + 1);
3909 memcpy(c, s, n + 1);
3910 p->error_buffer[p->nerr].message = c;
3911 p->error_buffer[p->nerr].lineno = p->lineno;
3912 p->error_buffer[p->nerr].column = p->column;
3918 yyerror_c(parser_state *p, const char *msg, char c)
3922 strncpy(buf, msg, sizeof(buf) - 2);
3923 buf[sizeof(buf) - 2] = '\0';
3924 strncat(buf, &c, 1);
3929 yywarn(parser_state *p, const char *s)
3934 if (! p->capture_errors) {
3935 #ifndef MRB_DISABLE_STDIO
3936 if (p->filename_sym) {
3937 const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
3938 fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s);
3941 fprintf(stderr, "line %d:%d: warning: %s\n", p->lineno, p->column, s);
3945 else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) {
3947 c = (char *)parser_palloc(p, n + 1);
3948 memcpy(c, s, n + 1);
3949 p->warn_buffer[p->nwarn].message = c;
3950 p->warn_buffer[p->nwarn].lineno = p->lineno;
3951 p->warn_buffer[p->nwarn].column = p->column;
3957 yywarning(parser_state *p, const char *s)
3963 yywarning_s(parser_state *p, const char *msg, const char *s)
3967 strncpy(buf, msg, sizeof(buf) - 1);
3968 buf[sizeof(buf) - 1] = '\0';
3969 strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
3970 strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
3975 backref_error(parser_state *p, node *n)
3981 if (c == NODE_NTH_REF) {
3982 yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0');
3984 else if (c == NODE_BACK_REF) {
3985 yyerror_c(p, "can't set variable $", (char)intn(n->cdr));
3988 mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c);
3993 void_expr_error(parser_state *p, node *n)
3997 if (n == NULL) return;
4005 yyerror(p, "void value expression");
4010 void_expr_error(p, n->cdr->car);
4011 void_expr_error(p, n->cdr->cdr);
4019 void_expr_error(p, n->car);
4027 static void pushback(parser_state *p, int c);
4028 static mrb_bool peeks(parser_state *p, const char *s);
4029 static mrb_bool skips(parser_state *p, const char *s);
4032 nextc0(parser_state *p)
4035 #ifndef MRB_DISABLE_STDIO
4037 if (feof(p->f)) return -1;
4039 if (c == EOF) return -1;
4043 if (!p->s || p->s >= p->send) {
4047 c = (unsigned char)*p->s++;
4053 nextc(parser_state *p)
4060 c = intn(p->pb->car);
4067 if (c < 0) goto eof;
4073 const int lf = nextc0(p);
4077 if (lf > 0) pushback(p, lf);
4082 if (!p->cxt) return -1;
4084 if (p->cxt->partial_hook(p) < 0)
4085 return -1; /* end of program(s) */
4086 return -2; /* end of a file in the program files */
4091 pushback(parser_state *p, int c)
4096 p->pb = cons(nint(c), p->pb);
4100 skip(parser_state *p, char term)
4107 if (c == term) break;
4112 peekc_n(parser_state *p, int n)
4119 if (c0 == -1) return c0; /* do not skip partial EOF */
4120 if (c0 >= 0) --p->column;
4121 list = push(list, nint(c0));
4124 p->pb = append((node*)list, p->pb);
4133 peek_n(parser_state *p, int c, int n)
4135 return peekc_n(p, n) == c && c >= 0;
4137 #define peek(p,c) peek_n((p), (c), 0)
4140 peeks(parser_state *p, const char *s)
4142 size_t len = strlen(s);
4144 #ifndef MRB_DISABLE_STDIO
4148 if (!peek_n(p, *s++, n++)) return FALSE;
4154 if (p->s && p->s + len <= p->send) {
4155 if (memcmp(p->s, s, len) == 0) return TRUE;
4161 skips(parser_state *p, const char *s)
4166 /* skip until first char */
4169 if (c < 0) return FALSE;
4178 size_t len = strlen(s);
4181 if (nextc(p) == '\n') {
4197 newtok(parser_state *p)
4199 if (p->tokbuf != p->buf) {
4200 mrb_free(p->mrb, p->tokbuf);
4202 p->tsiz = MRB_PARSER_TOKBUF_SIZE;
4205 return p->column - 1;
4209 tokadd(parser_state *p, int32_t c)
4214 /* mrb_assert(-0x10FFFF <= c && c <= 0xFF); */
4216 /* Single byte from source or non-Unicode escape */
4221 /* Unicode character */
4227 else if (c < 0x800) {
4228 utf8[0] = (char)(0xC0 | (c >> 6));
4229 utf8[1] = (char)(0x80 | (c & 0x3F));
4232 else if (c < 0x10000) {
4233 utf8[0] = (char)(0xE0 | (c >> 12) );
4234 utf8[1] = (char)(0x80 | ((c >> 6) & 0x3F));
4235 utf8[2] = (char)(0x80 | ( c & 0x3F));
4239 utf8[0] = (char)(0xF0 | (c >> 18) );
4240 utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F));
4241 utf8[2] = (char)(0x80 | ((c >> 6) & 0x3F));
4242 utf8[3] = (char)(0x80 | ( c & 0x3F));
4246 if (p->tidx+len >= p->tsiz) {
4247 if (p->tsiz >= MRB_PARSER_TOKBUF_MAX) {
4252 if (p->tokbuf == p->buf) {
4253 p->tokbuf = (char*)mrb_malloc(p->mrb, p->tsiz);
4254 memcpy(p->tokbuf, p->buf, MRB_PARSER_TOKBUF_SIZE);
4257 p->tokbuf = (char*)mrb_realloc(p->mrb, p->tokbuf, p->tsiz);
4260 for (i = 0; i < len; i++) {
4261 p->tokbuf[p->tidx++] = utf8[i];
4266 toklast(parser_state *p)
4268 return p->tokbuf[p->tidx-1];
4272 tokfix(parser_state *p)
4274 if (p->tidx >= MRB_PARSER_TOKBUF_MAX) {
4275 p->tidx = MRB_PARSER_TOKBUF_MAX-1;
4276 yyerror(p, "string too long (truncated)");
4278 p->tokbuf[p->tidx] = '\0';
4282 tok(parser_state *p)
4288 toklen(parser_state *p)
4293 #define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG)
4294 #define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)
4295 #define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)
4296 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
4297 #define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
4298 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
4301 scan_oct(const int *start, int len, int *retlen)
4303 const int *s = start;
4306 /* mrb_assert(len <= 3) */
4307 while (len-- && *s >= '0' && *s <= '7') {
4309 retval |= *s++ - '0';
4311 *retlen = (int)(s - start);
4317 scan_hex(parser_state *p, const int *start, int len, int *retlen)
4319 static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
4320 const int *s = start;
4321 uint32_t retval = 0;
4324 /* mrb_assert(len <= 8) */
4325 while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) {
4327 retval |= (tmp - hexdigit) & 15;
4330 *retlen = (int)(s - start);
4332 return (int32_t)retval;
4336 read_escape_unicode(parser_state *p, int limit)
4342 /* Look for opening brace */
4347 yyerror(p, "invalid escape character syntax");
4350 if (ISXDIGIT(buf[0])) {
4352 for (i=1; i<limit; i++) {
4354 if (buf[i] < 0) goto eof;
4355 if (!ISXDIGIT(buf[i])) {
4356 pushback(p, buf[i]);
4362 pushback(p, buf[0]);
4364 hex = scan_hex(p, buf, i, &i);
4365 if (i == 0 || hex > 0x10FFFF || (hex & 0xFFFFF800) == 0xD800) {
4366 yyerror(p, "invalid Unicode code point");
4372 /* Return negative to indicate Unicode code point */
4374 read_escape(parser_state *p)
4378 switch (c = nextc(p)) {
4379 case '\\':/* Backslash */
4382 case 'n':/* newline */
4385 case 't':/* horizontal tab */
4388 case 'r':/* carriage-return */
4391 case 'f':/* form-feed */
4394 case 'v':/* vertical tab */
4397 case 'a':/* alarm(bell) */
4400 case 'e':/* escape */
4403 case '0': case '1': case '2': case '3': /* octal constant */
4404 case '4': case '5': case '6': case '7':
4410 for (i=1; i<3; i++) {
4412 if (buf[i] < 0) goto eof;
4413 if (buf[i] < '0' || '7' < buf[i]) {
4414 pushback(p, buf[i]);
4418 c = scan_oct(buf, i, &i);
4422 case 'x': /* hex constant */
4427 for (i=0; i<2; i++) {
4429 if (buf[i] < 0) goto eof;
4430 if (!ISXDIGIT(buf[i])) {
4431 pushback(p, buf[i]);
4436 yyerror(p, "invalid hex escape");
4439 return scan_hex(p, buf, i, &i);
4442 case 'u': /* Unicode */
4444 /* \u{xxxxxxxx} form */
4446 c = read_escape_unicode(p, 8);
4447 if (c < 0) return 0;
4448 if (nextc(p) != '}') goto eof;
4451 c = read_escape_unicode(p, 4);
4452 if (c < 0) return 0;
4456 case 'b':/* backspace */
4459 case 's':/* space */
4463 if ((c = nextc(p)) != '-') {
4464 yyerror(p, "Invalid escape character syntax");
4468 if ((c = nextc(p)) == '\\') {
4469 return read_escape(p) | 0x80;
4471 else if (c < 0) goto eof;
4473 return ((c & 0xff) | 0x80);
4477 if ((c = nextc(p)) != '-') {
4478 yyerror(p, "Invalid escape character syntax");
4483 if ((c = nextc(p))== '\\') {
4488 else if (c < 0) goto eof;
4493 case -2: /* end of a file */
4494 yyerror(p, "Invalid escape character syntax");
4503 parse_string(parser_state *p)
4506 string_type type = (string_type)(intptr_t)p->lex_strterm->car;
4507 int nest_level = intn(p->lex_strterm->cdr->car);
4508 int beg = intn(p->lex_strterm->cdr->cdr->car);
4509 int end = intn(p->lex_strterm->cdr->cdr->cdr);
4510 parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
4512 if (beg == 0) beg = -3; /* should never happen */
4513 if (end == 0) end = -3;
4515 while ((c = nextc(p)) != end || nest_level != 0) {
4516 if (hinf && (c == '\n' || c < 0)) {
4522 line_head = hinf->line_head;
4523 hinf->line_head = TRUE;
4525 /* check whether end of heredoc */
4526 const char *s = tok(p);
4527 int len = toklen(p);
4528 if (hinf->allow_indent) {
4529 while (ISSPACE(*s) && len > 0) {
4534 if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
4535 return tHEREDOC_END;
4540 const char s1[] = "can't find heredoc delimiter \"";
4541 const char s2[] = "\" anywhere before EOF";
4543 if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) {
4544 yyerror(p, "can't find heredoc delimiter anywhere before EOF");
4547 strcat(buf, hinf->term);
4553 pylval.nd = new_str(p, tok(p), toklen(p));
4554 return tHD_STRING_MID;
4557 yyerror(p, "unterminated string meets end of file");
4560 else if (c == beg) {
4562 p->lex_strterm->cdr->car = nint(nest_level);
4564 else if (c == end) {
4566 p->lex_strterm->cdr->car = nint(nest_level);
4568 else if (c == '\\') {
4570 if (type & STR_FUNC_EXPAND) {
4571 if (c == end || c == beg) {
4574 else if (c == '\n') {
4577 if (type & STR_FUNC_ARRAY) {
4581 else if (type & STR_FUNC_REGEXP) {
4585 else if (c == 'u' && peek(p, '{')) {
4586 /* \u{xxxx xxxx xxxx} form */
4589 do c = nextc(p); while (ISSPACE(c));
4590 if (c == '}') break;
4592 c = read_escape_unicode(p, 8);
4597 hinf->line_head = FALSE;
4601 tokadd(p, read_escape(p));
4603 hinf->line_head = FALSE;
4607 if (c != beg && c != end) {
4612 if (!(c == '\\' || ((type & STR_FUNC_ARRAY) && ISSPACE(c)))) {
4620 else if ((c == '#') && (type & STR_FUNC_EXPAND)) {
4624 p->lstate = EXPR_BEG;
4625 p->cmd_start = TRUE;
4626 pylval.nd = new_str(p, tok(p), toklen(p));
4628 hinf->line_head = FALSE;
4629 return tHD_STRING_PART;
4631 return tSTRING_PART;
4637 if ((type & STR_FUNC_ARRAY) && ISSPACE(c)) {
4638 if (toklen(p) == 0) {
4643 heredoc_treat_nextline(p);
4644 if (p->parsing_heredoc != NULL) {
4645 return tHD_LITERAL_DELIM;
4649 } while (ISSPACE(c));
4651 return tLITERAL_DELIM;
4656 pylval.nd = new_str(p, tok(p), toklen(p));
4668 p->lstate = EXPR_ENDARG;
4671 if (type & STR_FUNC_XQUOTE) {
4672 pylval.nd = new_xstr(p, tok(p), toklen(p));
4676 if (type & STR_FUNC_REGEXP) {
4679 char *s = strndup(tok(p), toklen(p));
4687 while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) {
4689 case 'i': f |= 1; break;
4690 case 'x': f |= 2; break;
4691 case 'm': f |= 4; break;
4692 case 'u': f |= 16; break;
4693 case 'n': f |= 32; break;
4695 default: tokadd(p, re_opt); break;
4698 pushback(p, re_opt);
4702 strcpy(msg, "unknown regexp option");
4704 if (toklen(p) > 1) {
4708 strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1);
4712 if (f & 1) *flag++ = 'i';
4713 if (f & 2) *flag++ = 'x';
4714 if (f & 4) *flag++ = 'm';
4715 if (f & 16) enc = 'u';
4716 if (f & 32) enc = 'n';
4719 dup = strndup(flags, (size_t)(flag - flags));
4725 encp = strndup(&enc, 1);
4730 pylval.nd = new_regx(p, s, dup, encp);
4734 pylval.nd = new_str(p, tok(p), toklen(p));
4740 number_literal_suffix(parser_state *p)
4744 int column = p->column;
4745 int mask = NUM_SUFFIX_R|NUM_SUFFIX_I;
4747 while ((c = nextc(p)) != -1) {
4748 list = push(list, (node*)(intptr_t)c);
4750 if ((mask & NUM_SUFFIX_I) && c == 'i') {
4751 result |= (mask & NUM_SUFFIX_I);
4752 mask &= ~NUM_SUFFIX_I;
4753 /* r after i, rational of complex is disallowed */
4754 mask &= ~NUM_SUFFIX_R;
4757 if ((mask & NUM_SUFFIX_R) && c == 'r') {
4758 result |= (mask & NUM_SUFFIX_R);
4759 mask &= ~NUM_SUFFIX_R;
4762 if (!ISASCII(c) || ISALPHA(c) || c == '_') {
4765 p->pb = append((node*)list, p->pb);
4779 heredoc_identifier(parser_state *p)
4782 int type = str_heredoc;
4783 mrb_bool indent = FALSE;
4784 mrb_bool quote = FALSE;
4786 parser_heredoc_info *info;
4789 if (ISSPACE(c) || c == '=') {
4797 if (c == '\'' || c == '"') {
4802 while ((c = nextc(p)) >= 0 && c != term) {
4810 yyerror(p, "unterminated here document identifier");
4816 return 0; /* missing here document identifier */
4818 if (! identchar(c)) {
4820 if (indent) pushback(p, '-');
4826 } while ((c = nextc(p)) >= 0 && identchar(c));
4830 newnode = new_heredoc(p);
4831 info = (parser_heredoc_info*)newnode->cdr;
4832 info->term = strndup(tok(p), toklen(p));
4833 info->term_len = toklen(p);
4835 type |= STR_FUNC_EXPAND;
4836 info->type = (string_type)type;
4837 info->allow_indent = indent;
4838 info->line_head = TRUE;
4840 p->heredocs_from_nextline = push(p->heredocs_from_nextline, newnode);
4841 p->lstate = EXPR_END;
4843 pylval.nd = newnode;
4844 return tHEREDOC_BEG;
4848 arg_ambiguous(parser_state *p)
4850 yywarning(p, "ambiguous first argument; put parentheses or even spaces");
4857 parser_yylex(parser_state *p)
4863 enum mrb_lex_state_enum last_state;
4866 if (p->lex_strterm) {
4867 if (is_strterm_type(p, STR_FUNC_HEREDOC)) {
4868 if (p->parsing_heredoc != NULL)
4869 return parse_string(p);
4872 return parse_string(p);
4874 cmd_state = p->cmd_start;
4875 p->cmd_start = FALSE;
4877 last_state = p->lstate;
4878 switch (c = nextc(p)) {
4879 case '\004': /* ^D */
4880 case '\032': /* ^Z */
4881 case '\0': /* NUL */
4882 case -1: /* end of script. */
4883 if (p->heredocs_from_nextline)
4888 case ' ': case '\t': case '\f': case '\r':
4889 case '\13': /* '\v' */
4893 case '#': /* it's a comment */
4896 case -2: /* end of a file */
4899 heredoc_treat_nextline(p);
4901 switch (p->lstate) {
4908 if (p->parsing_heredoc != NULL) {
4909 if (p->lex_strterm) {
4910 return parse_string(p);
4917 if (p->parsing_heredoc != NULL) {
4918 pylval.num = nlines;
4921 while ((c = nextc(p))) {
4923 case ' ': case '\t': case '\f': case '\r':
4924 case '\13': /* '\v' */
4927 case '#': /* comment as a whitespace */
4932 if (!peek(p, '.')) {
4934 p->lineno+=nlines; nlines=1;
4938 goto normal_newline;
4942 p->lineno+=nlines; nlines=1;
4946 goto normal_newline;
4948 case -2: /* end of a file */
4949 goto normal_newline;
4952 goto normal_newline;
4956 p->cmd_start = TRUE;
4957 p->lstate = EXPR_BEG;
4958 pylval.num = nlines;
4962 if ((c = nextc(p)) == '*') {
4963 if ((c = nextc(p)) == '=') {
4964 pylval.id = intern_lit("**");
4965 p->lstate = EXPR_BEG;
4970 yywarning(p, "'**' interpreted as argument prefix");
4973 else if (IS_BEG()) {
4977 c = tPOW; /* "**", "argument prefix" */
4982 pylval.id = intern_lit("*");
4983 p->lstate = EXPR_BEG;
4988 yywarning(p, "'*' interpreted as argument prefix");
4991 else if (IS_BEG()) {
4998 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
4999 p->lstate = EXPR_ARG;
5002 p->lstate = EXPR_BEG;
5008 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5009 p->lstate = EXPR_ARG;
5015 p->lstate = EXPR_BEG;
5027 if (p->column == 1) {
5028 static const char begin[] = "begin";
5029 static const char end[] = "\n=end";
5030 if (peeks(p, begin)) {
5031 c = peekc_n(p, sizeof(begin)-1);
5032 if (c < 0 || ISSPACE(c)) {
5034 if (!skips(p, end)) {
5035 yyerror(p, "embedded document meets end of file");
5039 } while (!(c < 0 || ISSPACE(c)));
5040 if (c != '\n') skip(p, '\n');
5041 p->lineno+=nlines; nlines=1;
5047 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5048 p->lstate = EXPR_ARG;
5051 p->lstate = EXPR_BEG;
5053 if ((c = nextc(p)) == '=') {
5054 if ((c = nextc(p)) == '=') {
5063 else if (c == '>') {
5072 p->lstate != EXPR_DOT &&
5073 p->lstate != EXPR_CLASS &&
5075 (!IS_ARG() || space_seen)) {
5076 int token = heredoc_identifier(p);
5080 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5081 p->lstate = EXPR_ARG;
5084 p->lstate = EXPR_BEG;
5085 if (p->lstate == EXPR_CLASS) {
5086 p->cmd_start = TRUE;
5090 if ((c = nextc(p)) == '>') {
5097 if ((c = nextc(p)) == '=') {
5098 pylval.id = intern_lit("<<");
5099 p->lstate = EXPR_BEG;
5109 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5110 p->lstate = EXPR_ARG;
5113 p->lstate = EXPR_BEG;
5115 if ((c = nextc(p)) == '=') {
5119 if ((c = nextc(p)) == '=') {
5120 pylval.id = intern_lit(">>");
5121 p->lstate = EXPR_BEG;
5131 p->lex_strterm = new_strterm(p, str_dquote, '"', 0);
5135 p->lex_strterm = new_strterm(p, str_squote, '\'', 0);
5136 return parse_string(p);
5139 if (p->lstate == EXPR_FNAME) {
5140 p->lstate = EXPR_ENDFN;
5143 if (p->lstate == EXPR_DOT) {
5145 p->lstate = EXPR_CMDARG;
5147 p->lstate = EXPR_ARG;
5150 p->lex_strterm = new_strterm(p, str_xquote, '`', 0);
5151 return tXSTRING_BEG;
5155 p->lstate = EXPR_VALUE;
5160 yyerror(p, "incomplete character syntax");
5191 char cc[] = { (char)c2, '\0' };
5193 strcpy(buf, "invalid character syntax; use ?\\");
5194 strncat(buf, cc, 2);
5200 p->lstate = EXPR_VALUE;
5204 /* need support UTF-8 if configured */
5205 if ((ISALNUM(c) || c == '_')) {
5208 if ((ISALNUM(c2) || c2 == '_')) {
5220 pylval.nd = new_str(p, tok(p), toklen(p));
5221 p->lstate = EXPR_ENDARG;
5225 if ((c = nextc(p)) == '&') {
5226 p->lstate = EXPR_BEG;
5227 if ((c = nextc(p)) == '=') {
5228 pylval.id = intern_lit("&&");
5229 p->lstate = EXPR_BEG;
5235 else if (c == '.') {
5236 p->lstate = EXPR_DOT;
5239 else if (c == '=') {
5240 pylval.id = intern_lit("&");
5241 p->lstate = EXPR_BEG;
5246 yywarning(p, "'&' interpreted as argument prefix");
5249 else if (IS_BEG()) {
5255 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5256 p->lstate = EXPR_ARG;
5259 p->lstate = EXPR_BEG;
5264 if ((c = nextc(p)) == '|') {
5265 p->lstate = EXPR_BEG;
5266 if ((c = nextc(p)) == '=') {
5267 pylval.id = intern_lit("||");
5268 p->lstate = EXPR_BEG;
5275 pylval.id = intern_lit("|");
5276 p->lstate = EXPR_BEG;
5279 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5280 p->lstate = EXPR_ARG;
5283 p->lstate = EXPR_BEG;
5290 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5291 p->lstate = EXPR_ARG;
5299 pylval.id = intern_lit("+");
5300 p->lstate = EXPR_BEG;
5303 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
5304 p->lstate = EXPR_BEG;
5306 if (c >= 0 && ISDIGIT(c)) {
5312 p->lstate = EXPR_BEG;
5318 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5319 p->lstate = EXPR_ARG;
5327 pylval.id = intern_lit("-");
5328 p->lstate = EXPR_BEG;
5332 p->lstate = EXPR_ENDFN;
5335 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
5336 p->lstate = EXPR_BEG;
5338 if (c >= 0 && ISDIGIT(c)) {
5343 p->lstate = EXPR_BEG;
5348 p->lstate = EXPR_BEG;
5349 if ((c = nextc(p)) == '.') {
5350 if ((c = nextc(p)) == '.') {
5357 if (c >= 0 && ISDIGIT(c)) {
5358 yyerror(p, "no .<digit> floating literal anymore; put 0 before dot");
5360 p->lstate = EXPR_DOT;
5364 case '0': case '1': case '2': case '3': case '4':
5365 case '5': case '6': case '7': case '8': case '9':
5367 int is_float, seen_point, seen_e, nondigit;
5370 is_float = seen_point = seen_e = nondigit = 0;
5371 p->lstate = EXPR_ENDARG;
5373 if (c == '-' || c == '+') {
5378 #define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
5379 int start = toklen(p);
5381 if (c == 'x' || c == 'X') {
5384 if (c >= 0 && ISXDIGIT(c)) {
5387 if (nondigit) break;
5391 if (!ISXDIGIT(c)) break;
5393 tokadd(p, tolower(c));
5394 } while ((c = nextc(p)) >= 0);
5398 if (toklen(p) == start) {
5401 else if (nondigit) goto trailing_uc;
5402 suffix = number_literal_suffix(p);
5403 pylval.nd = new_int(p, tok(p), 16, suffix);
5406 if (c == 'b' || c == 'B') {
5409 if (c == '0' || c == '1') {
5412 if (nondigit) break;
5416 if (c != '0' && c != '1') break;
5419 } while ((c = nextc(p)) >= 0);
5423 if (toklen(p) == start) {
5426 else if (nondigit) goto trailing_uc;
5427 suffix = number_literal_suffix(p);
5428 pylval.nd = new_int(p, tok(p), 2, suffix);
5431 if (c == 'd' || c == 'D') {
5434 if (c >= 0 && ISDIGIT(c)) {
5437 if (nondigit) break;
5441 if (!ISDIGIT(c)) break;
5444 } while ((c = nextc(p)) >= 0);
5448 if (toklen(p) == start) {
5451 else if (nondigit) goto trailing_uc;
5452 suffix = number_literal_suffix(p);
5453 pylval.nd = new_int(p, tok(p), 10, suffix);
5460 if (c == 'o' || c == 'O') {
5461 /* prefixed octal */
5463 if (c < 0 || c == '_' || !ISDIGIT(c)) {
5467 if (c >= '0' && c <= '7') {
5472 if (nondigit) break;
5476 if (c < '0' || c > '9') break;
5477 if (c > '7') goto invalid_octal;
5480 } while ((c = nextc(p)) >= 0);
5482 if (toklen(p) > start) {
5485 if (nondigit) goto trailing_uc;
5486 suffix = number_literal_suffix(p);
5487 pylval.nd = new_int(p, tok(p), 8, suffix);
5495 if (c > '7' && c <= '9') {
5497 yyerror(p, "Invalid octal digit");
5499 else if (c == '.' || c == 'e' || c == 'E') {
5504 suffix = number_literal_suffix(p);
5505 pylval.nd = new_int(p, "0", 10, suffix);
5512 case '0': case '1': case '2': case '3': case '4':
5513 case '5': case '6': case '7': case '8': case '9':
5519 if (nondigit) goto trailing_uc;
5520 if (seen_point || seen_e) {
5525 if (c0 < 0 || !ISDIGIT(c0)) {
5553 if (c != '-' && c != '+') continue;
5558 case '_': /* '_' in number just ignored */
5559 if (nondigit) goto decode_num;
5573 yyerror_c(p, "trailing non digit in number: ", (char)nondigit);
5577 #ifdef MRB_WITHOUT_FLOAT
5578 yywarning_s(p, "floating point numbers are not supported", tok(p));
5579 pylval.nd = new_int(p, "0", 10, 0);
5586 d = mrb_float_read(tok(p), &endp);
5587 if (d == 0 && endp == tok(p)) {
5588 yywarning_s(p, "corrupted float value", tok(p));
5590 else if (errno == ERANGE) {
5591 yywarning_s(p, "float out of range", tok(p));
5594 suffix = number_literal_suffix(p);
5595 pylval.nd = new_float(p, tok(p), suffix);
5599 suffix = number_literal_suffix(p);
5600 pylval.nd = new_int(p, tok(p), 10, suffix);
5612 p->lstate = EXPR_ENDFN;
5614 p->lstate = EXPR_END;
5620 if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) {
5621 p->lstate = EXPR_BEG;
5624 p->lstate = EXPR_DOT;
5627 if (!space_seen && IS_END()) {
5629 p->lstate = EXPR_BEG;
5632 if (!ISSPACE(c) || IS_BEG()) {
5634 p->lstate = EXPR_FNAME;
5638 p->lstate = EXPR_BEG;
5643 p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
5646 if ((c = nextc(p)) == '=') {
5647 pylval.id = intern_lit("/");
5648 p->lstate = EXPR_BEG;
5653 p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
5656 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5657 p->lstate = EXPR_ARG;
5660 p->lstate = EXPR_BEG;
5665 if ((c = nextc(p)) == '=') {
5666 pylval.id = intern_lit("^");
5667 p->lstate = EXPR_BEG;
5670 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5671 p->lstate = EXPR_ARG;
5674 p->lstate = EXPR_BEG;
5680 p->lstate = EXPR_BEG;
5684 p->lstate = EXPR_BEG;
5688 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5689 if ((c = nextc(p)) != '@') {
5692 p->lstate = EXPR_ARG;
5695 p->lstate = EXPR_BEG;
5703 else if (IS_SPCARG(-1)) {
5706 else if (p->lstate == EXPR_END && space_seen) {
5712 p->lstate = EXPR_BEG;
5717 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5718 p->lstate = EXPR_ARG;
5719 if ((c = nextc(p)) == ']') {
5720 if ((c = nextc(p)) == '=') {
5729 else if (IS_BEG()) {
5732 else if (IS_ARG() && space_seen) {
5735 p->lstate = EXPR_BEG;
5741 if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
5742 p->lstate = EXPR_BEG;
5749 if (IS_ARG() || p->lstate == EXPR_END || p->lstate == EXPR_ENDFN)
5750 c = '{'; /* block (primary) */
5751 else if (p->lstate == EXPR_ENDARG)
5752 c = tLBRACE_ARG; /* block (expr) */
5754 c = tLBRACE; /* hash */
5757 p->lstate = EXPR_BEG;
5763 p->lineno+=nlines; nlines=1;
5766 goto retry; /* skip \\n */
5778 if (c < 0 || !ISALNUM(c)) {
5784 if (ISALNUM(term)) {
5785 yyerror(p, "unknown type of %string");
5789 if (c < 0 || term < 0) {
5790 yyerror(p, "unterminated quoted string meets end of file");
5794 if (term == '(') term = ')';
5795 else if (term == '[') term = ']';
5796 else if (term == '{') term = '}';
5797 else if (term == '<') term = '>';
5802 p->lex_strterm = new_strterm(p, str_dquote, term, paren);
5806 p->lex_strterm = new_strterm(p, str_squote, term, paren);
5807 return parse_string(p);
5810 p->lex_strterm = new_strterm(p, str_dword, term, paren);
5814 p->lex_strterm = new_strterm(p, str_sword, term, paren);
5818 p->lex_strterm = new_strterm(p, str_xquote, term, paren);
5819 return tXSTRING_BEG;
5822 p->lex_strterm = new_strterm(p, str_regexp, term, paren);
5826 p->lex_strterm = new_strterm(p, str_ssym, term, paren);
5830 p->lex_strterm = new_strterm(p, str_dsymbols, term, paren);
5831 return tSYMBOLS_BEG;
5834 p->lex_strterm = new_strterm(p, str_ssymbols, term, paren);
5835 return tSYMBOLS_BEG;
5838 yyerror(p, "unknown type of %string");
5842 if ((c = nextc(p)) == '=') {
5843 pylval.id = intern_lit("%");
5844 p->lstate = EXPR_BEG;
5850 if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
5851 p->lstate = EXPR_ARG;
5854 p->lstate = EXPR_BEG;
5860 p->lstate = EXPR_END;
5861 token_column = newtok(p);
5864 yyerror(p, "incomplete global variable syntax");
5868 case '_': /* $_: last read line string */
5870 if (c >= 0 && identchar(c)) { /* if there is more after _ it is a variable */
5878 case '~': /* $~: match-data */
5879 case '*': /* $*: argv */
5880 case '$': /* $$: pid */
5881 case '?': /* $?: last status */
5882 case '!': /* $!: error string */
5883 case '@': /* $@: error position */
5884 case '/': /* $/: input record separator */
5885 case '\\': /* $\: output record separator */
5886 case ';': /* $;: field separator */
5887 case ',': /* $,: output field separator */
5888 case '.': /* $.: last read line number */
5889 case '=': /* $=: ignorecase */
5890 case ':': /* $:: load path */
5891 case '<': /* $<: reading filename */
5892 case '>': /* $>: default output handle */
5893 case '\"': /* $": already loaded files */
5897 pylval.id = intern(tok(p), toklen(p));
5907 pylval.id = intern(tok(p), toklen(p));
5910 case '&': /* $&: last match */
5911 case '`': /* $`: string before last match */
5912 case '\'': /* $': string after last match */
5913 case '+': /* $+: string matches last pattern */
5914 if (last_state == EXPR_FNAME) {
5919 pylval.nd = new_back_ref(p, c);
5922 case '1': case '2': case '3':
5923 case '4': case '5': case '6':
5924 case '7': case '8': case '9':
5928 } while (c >= 0 && ISDIGIT(c));
5930 if (last_state == EXPR_FNAME) goto gvar;
5933 unsigned long n = strtoul(tok(p), NULL, 10);
5935 yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
5938 pylval.nd = new_nth_ref(p, (int)n);
5943 if (!identchar(c)) {
5955 token_column = newtok(p);
5963 yyerror(p, "incomplete instance variable syntax");
5966 yyerror(p, "incomplete class variable syntax");
5970 else if (ISDIGIT(c)) {
5972 yyerror_c(p, "wrong instance variable name: @", c);
5975 yyerror_c(p, "wrong class variable name: @@", c);
5979 if (!identchar(c)) {
5986 token_column = newtok(p);
5990 if (!identchar(c)) {
5992 const char s[] = "Invalid char in expression: 0x";
5993 const char hexdigits[] = "0123456789ABCDEF";
5996 buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4];
5997 buf[sizeof(s)] = hexdigits[(c & 0x0f)];
5998 buf[sizeof(s)+1] = 0;
6003 token_column = newtok(p);
6011 } while (identchar(c));
6012 if (token_column == 0 && toklen(p) == 7 && (c < 0 || c == '\n') &&
6013 strncmp(tok(p), "__END__", toklen(p)) == 0)
6016 switch (tok(p)[0]) {
6021 if ((c == '!' || c == '?') && !peek(p, '=')) {
6032 switch (tok(p)[0]) {
6034 p->lstate = EXPR_END;
6038 p->lstate = EXPR_END;
6039 if (tok(p)[1] == '@')
6046 if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) {
6047 int n = tok(p)[1] - '0';
6051 node *nvars = p->nvars->cdr;
6054 nvar = intn(nvars->car);
6055 if (nvar == -2) break; /* top of the scope */
6057 yywarning(p, "numbered parameter used in outer block");
6060 nvars->car = nint(-1);
6063 nvar = intn(p->nvars->car);
6065 yywarning(p, "numbered parameter used in inner block");
6069 p->lstate = EXPR_END;
6073 yywarning(p, "identifier for numbered parameter; consider another name");
6079 if (toklast(p) == '!' || toklast(p) == '?') {
6083 if (p->lstate == EXPR_FNAME) {
6084 if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
6085 (!peek(p, '=') || (peek_n(p, '>', 1)))) {
6086 result = tIDENTIFIER;
6093 if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
6094 (!peek(p, '=') || (peek_n(p, '>', 1)))) {
6095 result = tIDENTIFIER;
6103 if (result == 0 && ISUPPER(tok(p)[0])) {
6107 result = tIDENTIFIER;
6111 if (IS_LABEL_POSSIBLE()) {
6112 if (IS_LABEL_SUFFIX(0)) {
6113 p->lstate = EXPR_END;
6115 pylval.id = intern(tok(p), toklen(p));
6119 if (p->lstate != EXPR_DOT) {
6120 const struct kwtable *kw;
6122 /* See if it is a reserved word. */
6123 kw = mrb_reserved_word(tok(p), toklen(p));
6125 enum mrb_lex_state_enum state = p->lstate;
6126 pylval.num = p->lineno;
6127 p->lstate = kw->state;
6128 if (state == EXPR_FNAME) {
6129 pylval.id = intern_cstr(kw->name);
6132 if (p->lstate == EXPR_BEG) {
6133 p->cmd_start = TRUE;
6135 if (kw->id[0] == keyword_do) {
6136 if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
6139 return keyword_do_LAMBDA;
6141 if (COND_P()) return keyword_do_cond;
6142 if (CMDARG_P() && state != EXPR_CMDARG)
6143 return keyword_do_block;
6144 if (state == EXPR_ENDARG || state == EXPR_BEG)
6145 return keyword_do_block;
6148 if (state == EXPR_BEG || state == EXPR_VALUE)
6151 if (kw->id[0] != kw->id[1])
6152 p->lstate = EXPR_BEG;
6158 if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) {
6160 p->lstate = EXPR_CMDARG;
6163 p->lstate = EXPR_ARG;
6166 else if (p->lstate == EXPR_FNAME) {
6167 p->lstate = EXPR_ENDFN;
6170 p->lstate = EXPR_END;
6174 mrb_sym ident = intern(tok(p), toklen(p));
6177 if (last_state != EXPR_DOT && ISLOWER(tok(p)[0]) && local_var_p(p, ident)) {
6178 p->lstate = EXPR_END;
6186 yylex(void *lval, parser_state *p)
6189 return parser_yylex(p);
6193 parser_init_cxt(parser_state *p, mrbc_context *cxt)
6196 if (cxt->filename) mrb_parser_set_filename(p, cxt->filename);
6197 if (cxt->lineno) p->lineno = cxt->lineno;
6201 p->locals = cons(0,0);
6202 for (i=0; i<cxt->slen; i++) {
6203 local_add_f(p, cxt->syms[i]);
6206 p->capture_errors = cxt->capture_errors;
6207 p->no_optimize = cxt->no_optimize;
6208 p->upper = cxt->upper;
6209 if (cxt->partial_hook) {
6215 parser_update_cxt(parser_state *p, mrbc_context *cxt)
6221 if (intn(p->tree->car) != NODE_SCOPE) return;
6222 n0 = n = p->tree->cdr->car;
6227 cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym));
6229 for (i=0, n=n0; n; i++,n=n->cdr) {
6230 cxt->syms[i] = sym(n->car);
6234 void mrb_codedump_all(mrb_state*, struct RProc*);
6235 void mrb_parser_dump(mrb_state *mrb, node *tree, int offset);
6238 mrb_parser_parse(parser_state *p, mrbc_context *c)
6240 struct mrb_jmpbuf buf1;
6246 p->cmd_start = TRUE;
6247 p->in_def = p->in_single = 0;
6248 p->nerr = p->nwarn = 0;
6249 p->lex_strterm = NULL;
6251 parser_init_cxt(p, c);
6257 struct mrb_jmpbuf buf2;
6259 p->mrb->jmp = &buf2;
6260 MRB_TRY(p->mrb->jmp) {
6263 MRB_CATCH(p->mrb->jmp) {
6266 MRB_END_EXC(p->mrb->jmp);
6269 if (n != 0 || p->nerr > 0) {
6274 p->tree = new_nil(p);
6276 parser_update_cxt(p, c);
6277 if (c && c->dump_result) {
6278 mrb_parser_dump(p->mrb, p->tree, 0);
6282 yyerror(p, "memory allocation error");
6287 MRB_END_EXC(p->jmp);
6290 MRB_API parser_state*
6291 mrb_parser_new(mrb_state *mrb)
6295 static const parser_state parser_state_zero = { 0 };
6297 pool = mrb_pool_open(mrb);
6298 if (!pool) return NULL;
6299 p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state));
6300 if (!p) return NULL;
6302 *p = parser_state_zero;
6306 p->s = p->send = NULL;
6307 #ifndef MRB_DISABLE_STDIO
6311 p->cmd_start = TRUE;
6312 p->in_def = p->in_single = 0;
6314 p->capture_errors = FALSE;
6317 #if defined(PARSER_TEST) || defined(PARSER_DEBUG)
6320 p->tsiz = MRB_PARSER_TOKBUF_SIZE;
6323 p->lex_strterm = NULL;
6324 p->all_heredocs = p->parsing_heredoc = NULL;
6325 p->lex_strterm_before_heredoc = NULL;
6327 p->current_filename_index = -1;
6328 p->filename_table = NULL;
6329 p->filename_table_length = 0;
6335 mrb_parser_free(parser_state *p) {
6336 if (p->tokbuf != p->buf) {
6337 mrb_free(p->mrb, p->tokbuf);
6339 mrb_pool_close(p->pool);
6342 MRB_API mrbc_context*
6343 mrbc_context_new(mrb_state *mrb)
6345 return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context));
6349 mrbc_context_free(mrb_state *mrb, mrbc_context *cxt)
6351 mrb_free(mrb, cxt->filename);
6352 mrb_free(mrb, cxt->syms);
6357 mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
6360 size_t len = strlen(s);
6361 char *p = (char *)mrb_malloc(mrb, len + 1);
6363 memcpy(p, s, len + 1);
6365 mrb_free(mrb, c->filename);
6373 mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser_state*), void *data)
6375 c->partial_hook = func;
6376 c->partial_data = data;
6380 mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
6386 sym = mrb_intern_cstr(p->mrb, f);
6387 p->filename_sym = sym;
6388 p->lineno = (p->filename_table_length > 0)? 0 : 1;
6390 for (i = 0; i < p->filename_table_length; ++i) {
6391 if (p->filename_table[i] == sym) {
6392 p->current_filename_index = (int)i;
6397 if (p->filename_table_length == UINT16_MAX) {
6398 yyerror(p, "too many files to compile");
6401 p->current_filename_index = p->filename_table_length++;
6403 new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length);
6404 if (p->filename_table) {
6405 memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->current_filename_index);
6407 p->filename_table = new_table;
6408 p->filename_table[p->filename_table_length - 1] = sym;
6412 mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
6413 if (idx >= p->filename_table_length) return 0;
6415 return p->filename_table[idx];
6419 #ifndef MRB_DISABLE_STDIO
6420 MRB_API parser_state*
6421 mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
6425 p = mrb_parser_new(mrb);
6426 if (!p) return NULL;
6427 p->s = p->send = NULL;
6430 mrb_parser_parse(p, c);
6435 MRB_API parser_state*
6436 mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
6440 p = mrb_parser_new(mrb);
6441 if (!p) return NULL;
6445 mrb_parser_parse(p, c);
6449 MRB_API parser_state*
6450 mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
6452 return mrb_parse_nstring(mrb, s, strlen(s), c);
6456 mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
6458 struct RClass *target = mrb->object_class;
6461 unsigned int keep = 0;
6464 return mrb_undef_value();
6466 if (!p->tree || p->nerr) {
6467 if (c) c->parser_nerr = p->nerr;
6468 if (p->capture_errors) {
6471 strcpy(buf, "line ");
6472 dump_int(p->error_buffer[0].lineno, buf+5);
6474 strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1);
6475 mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf)));
6477 return mrb_undef_value();
6480 if (mrb->exc == NULL) {
6481 mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
6484 return mrb_undef_value();
6487 proc = mrb_generate_code(mrb, p);
6490 if (mrb->exc == NULL) {
6491 mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
6493 return mrb_undef_value();
6496 if (c->dump_result) mrb_codedump_all(mrb, proc);
6497 if (c->no_exec) return mrb_obj_value(proc);
6498 if (c->target_class) {
6499 target = c->target_class;
6508 MRB_PROC_SET_TARGET_CLASS(proc, target);
6510 mrb->c->ci->target_class = target;
6512 v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep);
6513 if (mrb->exc) return mrb_nil_value();
6517 #ifndef MRB_DISABLE_STDIO
6519 mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
6521 return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c);
6525 mrb_load_file(mrb_state *mrb, FILE *f)
6527 return mrb_load_file_cxt(mrb, f, NULL);
6532 mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
6534 return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
6538 mrb_load_nstring(mrb_state *mrb, const char *s, size_t len)
6540 return mrb_load_nstring_cxt(mrb, s, len, NULL);
6544 mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
6546 return mrb_load_nstring_cxt(mrb, s, strlen(s), c);
6550 mrb_load_string(mrb_state *mrb, const char *s)
6552 return mrb_load_string_cxt(mrb, s, NULL);
6555 #ifndef MRB_DISABLE_STDIO
6558 dump_prefix(node *tree, int offset)
6560 printf("%05d ", tree->lineno);
6568 dump_recur(mrb_state *mrb, node *tree, int offset)
6571 mrb_parser_dump(mrb, tree->car, offset);
6577 dump_args(mrb_state *mrb, node *n, int offset)
6580 dump_prefix(n, offset+1);
6581 printf("mandatory args:\n");
6582 dump_recur(mrb, n->car, offset+2);
6586 dump_prefix(n, offset+1);
6587 printf("optional args:\n");
6592 dump_prefix(n2, offset+2);
6593 printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car)));
6594 mrb_parser_dump(mrb, n2->car->cdr, offset+3);
6601 dump_prefix(n, offset+1);
6602 printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
6606 dump_prefix(n, offset+1);
6607 printf("post mandatory args:\n");
6608 dump_recur(mrb, n->car, offset+2);
6613 mrb_assert(intn(n->car) == NODE_ARGS_TAIL);
6614 mrb_parser_dump(mrb, n, offset);
6619 * This function restores the GC arena on return.
6620 * For this reason, if a process that further generates an object is
6621 * performed at the caller, the string pointer returned as the return
6622 * value may become invalid.
6625 str_dump(mrb_state *mrb, const char *str, int len)
6627 int ai = mrb_gc_arena_save(mrb);
6629 # if INT_MAX > MRB_INT_MAX / 4
6630 /* check maximum length with "\xNN" charactor */
6631 if (len > MRB_INT_MAX / 4) {
6632 len = MRB_INT_MAX / 4;
6635 s = mrb_str_new(mrb, str, (mrb_int)len);
6636 s = mrb_str_dump(mrb, s);
6637 mrb_gc_arena_restore(mrb, ai);
6638 return RSTRING_PTR(s);
6643 mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
6645 #ifndef MRB_DISABLE_STDIO
6650 dump_prefix(tree, offset);
6651 nodetype = intn(tree->car);
6655 printf("NODE_BEGIN:\n");
6656 dump_recur(mrb, tree, offset+1);
6660 printf("NODE_RESCUE:\n");
6662 dump_prefix(tree, offset+1);
6664 mrb_parser_dump(mrb, tree->car, offset+2);
6668 node *n2 = tree->car;
6670 dump_prefix(n2, offset+1);
6671 printf("rescue:\n");
6675 dump_prefix(n2, offset+2);
6676 printf("handle classes:\n");
6677 dump_recur(mrb, n3->car, offset+3);
6680 dump_prefix(n3, offset+2);
6681 printf("exc_var:\n");
6682 mrb_parser_dump(mrb, n3->cdr->car, offset+3);
6684 if (n3->cdr->cdr->car) {
6685 dump_prefix(n3, offset+2);
6686 printf("rescue body:\n");
6687 mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3);
6694 dump_prefix(tree, offset+1);
6696 mrb_parser_dump(mrb, tree->car, offset+2);
6701 printf("NODE_ENSURE:\n");
6702 dump_prefix(tree, offset+1);
6704 mrb_parser_dump(mrb, tree->car, offset+2);
6705 dump_prefix(tree, offset+1);
6706 printf("ensure:\n");
6707 mrb_parser_dump(mrb, tree->cdr->cdr, offset+2);
6711 printf("NODE_LAMBDA:\n");
6712 dump_prefix(tree, offset);
6717 printf("NODE_BLOCK:\n");
6720 dump_args(mrb, tree->car, offset+1);
6722 dump_prefix(tree, offset+1);
6724 mrb_parser_dump(mrb, tree->cdr->car, offset+2);
6728 printf("NODE_IF:\n");
6729 dump_prefix(tree, offset+1);
6731 mrb_parser_dump(mrb, tree->car, offset+2);
6732 dump_prefix(tree, offset+1);
6734 mrb_parser_dump(mrb, tree->cdr->car, offset+2);
6735 if (tree->cdr->cdr->car) {
6736 dump_prefix(tree, offset+1);
6738 mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2);
6743 printf("NODE_AND:\n");
6744 mrb_parser_dump(mrb, tree->car, offset+1);
6745 mrb_parser_dump(mrb, tree->cdr, offset+1);
6749 printf("NODE_OR:\n");
6750 mrb_parser_dump(mrb, tree->car, offset+1);
6751 mrb_parser_dump(mrb, tree->cdr, offset+1);
6755 printf("NODE_CASE:\n");
6757 mrb_parser_dump(mrb, tree->car, offset+1);
6761 dump_prefix(tree, offset+1);
6763 dump_recur(mrb, tree->car->car, offset+2);
6764 dump_prefix(tree, offset+1);
6766 mrb_parser_dump(mrb, tree->car->cdr, offset+2);
6772 printf("NODE_WHILE:\n");
6773 dump_prefix(tree, offset+1);
6775 mrb_parser_dump(mrb, tree->car, offset+2);
6776 dump_prefix(tree, offset+1);
6778 mrb_parser_dump(mrb, tree->cdr, offset+2);
6782 printf("NODE_UNTIL:\n");
6783 dump_prefix(tree, offset+1);
6785 mrb_parser_dump(mrb, tree->car, offset+2);
6786 dump_prefix(tree, offset+1);
6788 mrb_parser_dump(mrb, tree->cdr, offset+2);
6792 printf("NODE_FOR:\n");
6793 dump_prefix(tree, offset+1);
6796 node *n2 = tree->car;
6799 dump_prefix(n2, offset+2);
6801 dump_recur(mrb, n2->car, offset+3);
6806 dump_prefix(n2, offset+2);
6808 mrb_parser_dump(mrb, n2->car, offset+3);
6813 dump_prefix(n2, offset+2);
6815 dump_recur(mrb, n2->car, offset+3);
6821 dump_prefix(tree, offset+1);
6823 mrb_parser_dump(mrb, tree->car, offset+2);
6825 dump_prefix(tree, offset+1);
6827 mrb_parser_dump(mrb, tree->car, offset+2);
6831 printf("NODE_SCOPE:\n");
6833 node *n2 = tree->car;
6834 mrb_bool first_lval = TRUE;
6836 if (n2 && (n2->car || n2->cdr)) {
6837 dump_prefix(n2, offset+1);
6838 printf("local variables:\n");
6839 dump_prefix(n2, offset+2);
6842 if (!first_lval) printf(", ");
6843 printf("%s", mrb_sym_name(mrb, sym(n2->car)));
6860 printf("NODE_FCALL:\n"); break;
6862 printf("NODE_CALL(.):\n"); break;
6864 printf("NODE_SCALL(&.):\n"); break;
6868 mrb_parser_dump(mrb, tree->car, offset+1);
6869 dump_prefix(tree, offset+1);
6870 printf("method='%s' (%d)\n",
6871 mrb_sym_dump(mrb, sym(tree->cdr->car)),
6872 intn(tree->cdr->car));
6873 tree = tree->cdr->cdr->car;
6875 dump_prefix(tree, offset+1);
6877 dump_recur(mrb, tree->car, offset+2);
6879 dump_prefix(tree, offset+1);
6881 mrb_parser_dump(mrb, tree->cdr, offset+2);
6887 printf("NODE_DOT2:\n");
6888 mrb_parser_dump(mrb, tree->car, offset+1);
6889 mrb_parser_dump(mrb, tree->cdr, offset+1);
6893 printf("NODE_DOT3:\n");
6894 mrb_parser_dump(mrb, tree->car, offset+1);
6895 mrb_parser_dump(mrb, tree->cdr, offset+1);
6899 printf("NODE_COLON2:\n");
6900 mrb_parser_dump(mrb, tree->car, offset+1);
6901 dump_prefix(tree, offset+1);
6902 printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr)));
6906 printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree)));
6910 printf("NODE_ARRAY:\n");
6911 dump_recur(mrb, tree, offset+1);
6915 printf("NODE_HASH:\n");
6917 dump_prefix(tree, offset+1);
6919 mrb_parser_dump(mrb, tree->car->car, offset+2);
6920 dump_prefix(tree, offset+1);
6922 mrb_parser_dump(mrb, tree->car->cdr, offset+2);
6928 printf("NODE_KW_HASH:\n");
6930 dump_prefix(tree, offset+1);
6932 mrb_parser_dump(mrb, tree->car->car, offset+2);
6933 dump_prefix(tree, offset+1);
6935 mrb_parser_dump(mrb, tree->car->cdr, offset+2);
6941 printf("NODE_SPLAT:\n");
6942 mrb_parser_dump(mrb, tree, offset+1);
6946 printf("NODE_ASGN:\n");
6947 dump_prefix(tree, offset+1);
6949 mrb_parser_dump(mrb, tree->car, offset+2);
6950 dump_prefix(tree, offset+1);
6952 mrb_parser_dump(mrb, tree->cdr, offset+2);
6956 printf("NODE_MASGN:\n");
6957 dump_prefix(tree, offset+1);
6960 node *n2 = tree->car;
6963 dump_prefix(tree, offset+2);
6965 dump_recur(mrb, n2->car, offset+3);
6970 dump_prefix(n2, offset+2);
6972 if (n2->car == (node*)-1) {
6973 dump_prefix(n2, offset+2);
6974 printf("(empty)\n");
6977 mrb_parser_dump(mrb, n2->car, offset+3);
6983 dump_prefix(n2, offset+2);
6985 dump_recur(mrb, n2->car, offset+3);
6990 dump_prefix(tree, offset+1);
6992 mrb_parser_dump(mrb, tree->cdr, offset+2);
6996 printf("NODE_OP_ASGN:\n");
6997 dump_prefix(tree, offset+1);
6999 mrb_parser_dump(mrb, tree->car, offset+2);
7001 dump_prefix(tree, offset+1);
7002 printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car));
7004 mrb_parser_dump(mrb, tree->car, offset+1);
7008 printf("NODE_SUPER:\n");
7010 dump_prefix(tree, offset+1);
7012 dump_recur(mrb, tree->car, offset+2);
7014 dump_prefix(tree, offset+1);
7016 mrb_parser_dump(mrb, tree->cdr, offset+2);
7022 printf("NODE_ZSUPER\n");
7026 printf("NODE_RETURN:\n");
7027 mrb_parser_dump(mrb, tree, offset+1);
7031 printf("NODE_YIELD:\n");
7032 dump_recur(mrb, tree, offset+1);
7036 printf("NODE_BREAK:\n");
7037 mrb_parser_dump(mrb, tree, offset+1);
7041 printf("NODE_NEXT:\n");
7042 mrb_parser_dump(mrb, tree, offset+1);
7046 printf("NODE_REDO\n");
7050 printf("NODE_RETRY\n");
7054 printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree)));
7058 printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree)));
7062 printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree)));
7066 printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree)));
7070 printf("NODE_NVAR %d\n", intn(tree));
7074 printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree)));
7078 printf("NODE_MATCH:\n");
7079 dump_prefix(tree, offset + 1);
7081 mrb_parser_dump(mrb, tree->car, offset + 2);
7082 dump_prefix(tree, offset + 1);
7084 mrb_parser_dump(mrb, tree->cdr, offset + 2);
7088 printf("NODE_BACK_REF: $%c\n", intn(tree));
7092 printf("NODE_NTH_REF: $%d\n", intn(tree));
7096 printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree)));
7099 case NODE_BLOCK_ARG:
7100 printf("NODE_BLOCK_ARG:\n");
7101 mrb_parser_dump(mrb, tree, offset+1);
7105 printf("NODE_INT %s base %d\n", (char*)tree->car, intn(tree->cdr->car));
7109 printf("NODE_FLOAT %s\n", (char*)tree);
7113 printf("NODE_NEGATE:\n");
7114 mrb_parser_dump(mrb, tree, offset+1);
7118 printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
7122 printf("NODE_DSTR:\n");
7123 dump_recur(mrb, tree, offset+1);
7127 printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
7131 printf("NODE_DXSTR:\n");
7132 dump_recur(mrb, tree, offset+1);
7136 printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr);
7140 printf("NODE_DREGX:\n");
7141 dump_recur(mrb, tree->car, offset+1);
7142 dump_prefix(tree, offset);
7143 printf("tail: %s\n", (char*)tree->cdr->cdr->car);
7144 if (tree->cdr->cdr->cdr->car) {
7145 dump_prefix(tree, offset);
7146 printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car);
7148 if (tree->cdr->cdr->cdr->cdr) {
7149 dump_prefix(tree, offset);
7150 printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr);
7155 printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)),
7160 printf("NODE_DSYM:\n");
7161 mrb_parser_dump(mrb, tree, offset+1);
7165 printf("NODE_WORDS:\n");
7166 dump_recur(mrb, tree, offset+1);
7170 printf("NODE_SYMBOLS:\n");
7171 dump_recur(mrb, tree, offset+1);
7174 case NODE_LITERAL_DELIM:
7175 printf("NODE_LITERAL_DELIM\n");
7179 printf("NODE_SELF\n");
7183 printf("NODE_NIL\n");
7187 printf("NODE_TRUE\n");
7191 printf("NODE_FALSE\n");
7195 printf("NODE_ALIAS %s %s:\n",
7196 mrb_sym_dump(mrb, sym(tree->car)),
7197 mrb_sym_dump(mrb, sym(tree->cdr)));
7201 printf("NODE_UNDEF");
7205 printf(" %s", mrb_sym_dump(mrb, sym(t->car)));
7213 printf("NODE_CLASS:\n");
7214 if (tree->car->car == (node*)0) {
7215 dump_prefix(tree, offset+1);
7216 printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7218 else if (tree->car->car == (node*)1) {
7219 dump_prefix(tree, offset+1);
7220 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7223 mrb_parser_dump(mrb, tree->car->car, offset+1);
7224 dump_prefix(tree, offset+1);
7225 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7227 if (tree->cdr->car) {
7228 dump_prefix(tree, offset+1);
7230 mrb_parser_dump(mrb, tree->cdr->car, offset+2);
7232 dump_prefix(tree, offset+1);
7234 mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2);
7238 printf("NODE_MODULE:\n");
7239 if (tree->car->car == (node*)0) {
7240 dump_prefix(tree, offset+1);
7241 printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7243 else if (tree->car->car == (node*)1) {
7244 dump_prefix(tree, offset+1);
7245 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7248 mrb_parser_dump(mrb, tree->car->car, offset+1);
7249 dump_prefix(tree, offset+1);
7250 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
7252 dump_prefix(tree, offset+1);
7254 mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
7258 printf("NODE_SCLASS:\n");
7259 mrb_parser_dump(mrb, tree->car, offset+1);
7260 dump_prefix(tree, offset+1);
7262 mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
7266 printf("NODE_DEF:\n");
7267 dump_prefix(tree, offset+1);
7268 printf("%s\n", mrb_sym_dump(mrb, sym(tree->car)));
7271 node *n2 = tree->car;
7272 mrb_bool first_lval = TRUE;
7274 if (n2 && (n2->car || n2->cdr)) {
7275 dump_prefix(n2, offset+1);
7276 printf("local variables:\n");
7277 dump_prefix(n2, offset+2);
7280 if (!first_lval) printf(", ");
7281 printf("%s", mrb_sym_name(mrb, sym(n2->car)));
7291 dump_args(mrb, tree->car, offset);
7293 mrb_parser_dump(mrb, tree->cdr->car, offset+1);
7297 printf("NODE_SDEF:\n");
7298 mrb_parser_dump(mrb, tree->car, offset+1);
7300 dump_prefix(tree, offset+1);
7301 printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car)));
7302 tree = tree->cdr->cdr;
7304 dump_args(mrb, tree->car, offset+1);
7307 mrb_parser_dump(mrb, tree->car, offset+1);
7311 printf("NODE_POSTEXE:\n");
7312 mrb_parser_dump(mrb, tree, offset+1);
7316 printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term);
7317 dump_recur(mrb, ((parser_heredoc_info*)tree)->doc, offset+1);
7320 case NODE_ARGS_TAIL:
7321 printf("NODE_ARGS_TAIL:\n");
7323 node *kws = tree->car;
7326 mrb_parser_dump(mrb, kws->car, offset+1);
7332 mrb_assert(intn(tree->car->car) == NODE_KW_REST_ARGS);
7333 mrb_parser_dump(mrb, tree->car, offset+1);
7337 dump_prefix(tree, offset+1);
7338 printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car)));
7343 printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car)));
7344 mrb_parser_dump(mrb, tree->cdr->car, offset + 1);
7347 case NODE_KW_REST_ARGS:
7348 printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
7352 printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype);