summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler/core/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-compiler/core/parse.y')
-rw-r--r--mrbgems/mruby-compiler/core/parse.y384
1 files changed, 231 insertions, 153 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 2c2bff714..ed4265a16 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -13,7 +13,6 @@
#include <ctype.h>
#include <errno.h>
-#include <stdlib.h>
#include <string.h>
#include <mruby.h>
#include <mruby/compile.h>
@@ -34,7 +33,6 @@ typedef struct mrb_parser_heredoc_info parser_heredoc_info;
static int yyparse(parser_state *p);
static int yylex(void *lval, parser_state *p);
static void yyerror(parser_state *p, const char *s);
-static void yywarn(parser_state *p, const char *s);
static void yywarning(parser_state *p, const char *s);
static void backref_error(parser_state *p, node *n);
static void void_expr_error(parser_state *p, node *n);
@@ -106,7 +104,7 @@ parser_palloc(parser_state *p, size_t size)
void *m = mrb_pool_alloc(p->pool, size);
if (!m) {
- MRB_THROW(p->jmp);
+ MRB_THROW(p->mrb->jmp);
}
return m;
}
@@ -286,9 +284,10 @@ local_var_p(parser_state *p, mrb_sym sym)
const mrb_sym *v = ir->lv;
int i;
- if (!v) break;
- for (i=0; i+1 < ir->nlocals; i++) {
- if (v[i] == sym) return TRUE;
+ if (v) {
+ for (i=0; i+1 < ir->nlocals; i++) {
+ if (v[i] == sym) return TRUE;
+ }
}
if (MRB_PROC_SCOPE_P(u)) break;
u = u->upper;
@@ -500,13 +499,18 @@ new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass)
static node*
new_fcall(parser_state *p, mrb_sym b, node *c)
{
- node *n = new_self(p);
- NODE_LINENO(n, c);
- n = list4((node*)NODE_FCALL, n, nsym(b), c);
+ node *n = list4((node*)NODE_FCALL, 0, nsym(b), c);
NODE_LINENO(n, c);
return n;
}
+/* (a b . c) */
+static node*
+new_callargs(parser_state *p, node *a, node *b, node *c)
+{
+ return cons(a, cons(b, c));
+}
+
/* (:super . c) */
static node*
new_super(parser_state *p, node *c)
@@ -518,7 +522,7 @@ new_super(parser_state *p, node *c)
static node*
new_zsuper(parser_state *p)
{
- return list1((node*)NODE_ZSUPER);
+ return cons((node*)NODE_ZSUPER, 0);
}
/* (:yield . c) */
@@ -527,7 +531,12 @@ new_yield(parser_state *p, node *c)
{
if (c) {
if (c->cdr) {
- yyerror(p, "both block arg and actual block given");
+ if (c->cdr->cdr) {
+ yyerror(p, "both block arg and actual block given");
+ }
+ if (c->cdr->car) {
+ return cons((node*)NODE_YIELD, push(c->car, c->cdr->car));
+ }
}
return cons((node*)NODE_YIELD, c->car);
}
@@ -961,13 +970,14 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
static node*
new_imaginary(parser_state *p, node *imaginary)
{
- return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
+ return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex),
+ new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1);
}
static node*
new_rational(parser_state *p, node *rational)
{
- return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), list1(list1(rational)), 1);
+ return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1);
}
/* (:int . i) */
@@ -1190,17 +1200,17 @@ call_uni_op(parser_state *p, node *recv, const char *m)
static node*
call_bin_op(parser_state *p, node *recv, const char *m, node *arg1)
{
- return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1);
+ return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1);
}
static void
args_with_block(parser_state *p, node *a, node *b)
{
if (b) {
- if (a->cdr) {
+ if (a->cdr && a->cdr->cdr) {
yyerror(p, "both block arg and actual block given");
}
- a->cdr = b;
+ a->cdr->cdr = b;
}
}
@@ -1227,19 +1237,16 @@ call_with_block(parser_state *p, node *a, node *b)
switch (typen(a->car)) {
case NODE_SUPER:
case NODE_ZSUPER:
- if (!a->cdr) a->cdr = cons(0, b);
- else {
- args_with_block(p, a->cdr, b);
- }
+ if (!a->cdr) a->cdr = new_callargs(p, 0, 0, b);
+ else args_with_block(p, a->cdr, b);
break;
case NODE_CALL:
case NODE_FCALL:
case NODE_SCALL:
- n = a->cdr->cdr->cdr;
- if (!n->car) n->car = cons(0, b);
- else {
- args_with_block(p, n->car, b);
- }
+ /* (NODE_CALL recv mid (args kw . blk)) */
+ n = a->cdr->cdr->cdr; /* (args kw . blk) */
+ if (!n->car) n->car = new_callargs(p, 0, 0, b);
+ else args_with_block(p, n->car, b);
break;
default:
break;
@@ -1247,7 +1254,7 @@ call_with_block(parser_state *p, node *a, node *b)
}
static node*
-negate_lit(parser_state *p, node *n)
+new_negate(parser_state *p, node *n)
{
return cons((node*)NODE_NEGATE, n);
}
@@ -1261,10 +1268,11 @@ cond(node *n)
static node*
ret_args(parser_state *p, node *n)
{
- if (n->cdr) {
+ if (n->cdr->cdr) {
yyerror(p, "block argument should not be given");
return NULL;
}
+ if (!n->car) return NULL;
if (!n->car->cdr) return n->car->car;
return new_array(p, n->car);
}
@@ -1293,6 +1301,24 @@ var_reference(parser_state *p, node *lhs)
return lhs;
}
+static node*
+label_reference(parser_state *p, mrb_sym sym)
+{
+ const char *name = mrb_sym_name(p->mrb, sym);
+ node *n;
+
+ if (local_var_p(p, sym)) {
+ n = new_lvar(p, sym);
+ }
+ else if (ISUPPER(name[0])) {
+ n = new_const(p, sym);
+ }
+ else {
+ n = new_fcall(p, sym, 0);
+ }
+ return n;
+}
+
typedef enum mrb_string_type string_type;
static node*
@@ -1623,7 +1649,7 @@ bodystmt : compstmt
NODE_LINENO($$, $1);
}
else if ($3) {
- yywarn(p, "else without rescue is useless");
+ yywarning(p, "else without rescue is useless");
$$ = push($1, $3);
}
else {
@@ -1754,6 +1780,44 @@ command_asgn : lhs '=' command_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
}
+ | defn_head f_opt_arglist_paren '=' command
+ {
+ $$ = $1;
+ endless_method_name(p, $1);
+ void_expr_error(p, $4);
+ defn_setup(p, $$, $2, $4);
+ nvars_unnest(p);
+ p->in_def--;
+ }
+ | defn_head f_opt_arglist_paren '=' command modifier_rescue arg
+ {
+ $$ = $1;
+ endless_method_name(p, $1);
+ void_expr_error(p, $4);
+ void_expr_error(p, $6);
+ defn_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
+ nvars_unnest(p);
+ p->in_def--;
+ }
+ | defs_head f_opt_arglist_paren '=' command
+ {
+ $$ = $1;
+ void_expr_error(p, $4);
+ defs_setup(p, $$, $2, $4);
+ nvars_unnest(p);
+ p->in_def--;
+ p->in_single--;
+ }
+ | defs_head f_opt_arglist_paren '=' command modifier_rescue arg
+ {
+ $$ = $1;
+ void_expr_error(p, $4);
+ void_expr_error(p, $6);
+ defs_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
+ nvars_unnest(p);
+ p->in_def--;
+ p->in_single--;
+ }
| backref tOP_ASGN command_rhs
{
backref_error(p, $1);
@@ -2253,11 +2317,11 @@ arg : lhs '=' arg_rhs
}
| tUMINUS_NUM tINTEGER tPOW arg
{
- $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+ $$ = new_negate(p, call_bin_op(p, $2, "**", $4));
}
| tUMINUS_NUM tFLOAT tPOW arg
{
- $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+ $$ = new_negate(p, call_bin_op(p, $2, "**", $4));
}
| tUPLUS arg
{
@@ -2265,7 +2329,7 @@ arg : lhs '=' arg_rhs
}
| tUMINUS arg
{
- $$ = call_uni_op(p, $2, "-@");
+ $$ = new_negate(p, $2);
}
| arg '|' arg
{
@@ -2370,7 +2434,7 @@ arg : lhs '=' arg_rhs
nvars_unnest(p);
p->in_def--;
}
- | defs_head f_arglist_paren '=' arg
+ | defs_head f_opt_arglist_paren '=' arg
{
$$ = $1;
void_expr_error(p, $4);
@@ -2379,7 +2443,7 @@ arg : lhs '=' arg_rhs
p->in_def--;
p->in_single--;
}
- | defs_head f_arglist_paren '=' arg modifier_rescue arg
+ | defs_head f_opt_arglist_paren '=' arg modifier_rescue arg
{
$$ = $1;
void_expr_error(p, $4);
@@ -2403,7 +2467,7 @@ aref_args : none
}
| args comma assocs trailer
{
- $$ = push($1, new_kw_hash(p, $3));
+ $$ = push($1, new_hash(p, $3));
}
| assocs trailer
{
@@ -2430,39 +2494,23 @@ paren_args : '(' opt_call_args ')'
}
| '(' args comma tBDOT3 rparen
{
-#if 1
- mrb_sym r = intern_op(mul);
- mrb_sym b = intern_op(and);
- $$ = cons(push($2, new_splat(p, new_lvar(p, r))),
- new_block_arg(p, new_lvar(p, b)));
-#else
mrb_sym r = intern_op(mul);
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
- $$ = cons(list2(push($2, new_splat(p, new_lvar(p, r))),
- new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
- new_block_arg(p, new_lvar(p, b)));
-#endif
+ $$ = new_callargs(p, push($2, new_splat(p, new_lvar(p, r))),
+ new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))),
+ new_block_arg(p, new_lvar(p, b)));
}
| '(' tBDOT3 rparen
{
-#if 1
- mrb_sym r = intern_op(mul);
- mrb_sym b = intern_op(and);
- if (local_var_p(p, r) && local_var_p(p, b)) {
- $$ = cons(list1(new_splat(p, new_lvar(p, r))),
- new_block_arg(p, new_lvar(p, b)));
- }
-#else
mrb_sym r = intern_op(mul);
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
- $$ = cons(list2(new_splat(p, new_lvar(p, r)),
- new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
- new_block_arg(p, new_lvar(p, b)));
+ $$ = new_callargs(p, list1(new_splat(p, new_lvar(p, r))),
+ new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))),
+ new_block_arg(p, new_lvar(p, b)));
}
-#endif
else {
yyerror(p, "unexpected argument forwarding ...");
$$ = 0;
@@ -2478,17 +2526,17 @@ opt_call_args : none
| call_args opt_terms
| args comma
{
- $$ = cons($1,0);
+ $$ = new_callargs(p,$1,0,0);
NODE_LINENO($$, $1);
}
| args comma assocs comma
{
- $$ = cons(push($1, new_kw_hash(p, $3)), 0);
+ $$ = new_callargs(p,$1,new_kw_hash(p,$3),0);
NODE_LINENO($$, $1);
}
| assocs comma
{
- $$ = cons(list1(new_kw_hash(p, $1)), 0);
+ $$ = new_callargs(p,0,new_kw_hash(p,$1),0);
NODE_LINENO($$, $1);
}
;
@@ -2496,27 +2544,27 @@ opt_call_args : none
call_args : command
{
void_expr_error(p, $1);
- $$ = cons(list1($1), 0);
+ $$ = new_callargs(p, list1($1), 0, 0);
NODE_LINENO($$, $1);
}
| args opt_block_arg
{
- $$ = cons($1, $2);
+ $$ = new_callargs(p, $1, 0, $2);
NODE_LINENO($$, $1);
}
| assocs opt_block_arg
{
- $$ = cons(list1(new_kw_hash(p, $1)), $2);
+ $$ = new_callargs(p, 0, new_kw_hash(p, $1), $2);
NODE_LINENO($$, $1);
}
| args comma assocs opt_block_arg
{
- $$ = cons(push($1, new_kw_hash(p, $3)), $4);
+ $$ = new_callargs(p, $1, new_kw_hash(p, $3), $4);
NODE_LINENO($$, $1);
}
| block_arg
{
- $$ = cons(0, $1);
+ $$ = new_callargs(p, 0, 0, $1);
NODE_LINENO($$, $1);
}
;
@@ -2548,20 +2596,19 @@ opt_block_arg : comma block_arg
}
;
-comma : ','
- | ',' opt_nl heredoc_bodies
+comma : ',' opt_nl
;
args : arg
{
void_expr_error(p, $1);
- $$ = cons($1, 0);
+ $$ = list1($1);
NODE_LINENO($$, $1);
}
| tSTAR arg
{
void_expr_error(p, $2);
- $$ = cons(new_splat(p, $2), 0);
+ $$ = list1(new_splat(p, $2));
NODE_LINENO($$, $2);
}
| args comma arg
@@ -2673,7 +2720,7 @@ primary : literal
}
| operation brace_block
{
- $$ = new_fcall(p, $1, cons(0, $2));
+ $$ = new_fcall(p, $1, new_callargs(p, 0, 0, $2));
}
| method_call
| method_call brace_block
@@ -3268,7 +3315,14 @@ string_fragment : tCHAR
}
| tSTRING_BEG string_rep tSTRING
{
- $$ = new_dstr(p, push($2, $3));
+ node *n = $2;
+ if (intn($3->cdr->cdr) > 0) {
+ n = push(n, $3);
+ }
+ else {
+ cons_free($3);
+ }
+ $$ = new_dstr(p, n);
}
;
@@ -3310,7 +3364,14 @@ xstring : tXSTRING_BEG tXSTRING
}
| tXSTRING_BEG string_rep tXSTRING
{
- $$ = new_dxstr(p, push($2, $3));
+ node *n = $2;
+ if (intn($3->cdr->cdr) > 0) {
+ n = push(n, $3);
+ }
+ else {
+ cons_free($3);
+ }
+ $$ = new_dxstr(p, n);
}
;
@@ -3373,7 +3434,14 @@ words : tWORDS_BEG tSTRING
}
| tWORDS_BEG string_rep tSTRING
{
- $$ = new_words(p, push($2, $3));
+ node *n = $2;
+ if (intn($3->cdr->cdr) > 0) {
+ n = push(n, $3);
+ }
+ else {
+ cons_free($3);
+ }
+ $$ = new_words(p, n);
}
;
@@ -3385,8 +3453,15 @@ symbol : basic_symbol
}
| tSYMBEG tSTRING_BEG string_rep tSTRING
{
+ node *n = $3;
p->lstate = EXPR_ENDARG;
- $$ = new_dsym(p, new_dstr(p, push($3, $4)));
+ if (intn($4->cdr->cdr) > 0) {
+ n = push(n, $4);
+ }
+ else {
+ cons_free($4);
+ }
+ $$ = new_dsym(p, new_dstr(p, n));
}
;
@@ -3416,7 +3491,11 @@ symbols : tSYMBOLS_BEG tSTRING
}
| tSYMBOLS_BEG string_rep tSTRING
{
- $$ = new_symbols(p, push($2, $3));
+ node *n = $2;
+ if (intn($3->cdr->cdr) > 0) {
+ n = push(n, $3);
+ }
+ $$ = new_symbols(p, n);
}
;
@@ -3424,11 +3503,11 @@ numeric : tINTEGER
| tFLOAT
| tUMINUS_NUM tINTEGER %prec tLOWEST
{
- $$ = negate_lit(p, $2);
+ $$ = new_negate(p, $2);
}
| tUMINUS_NUM tFLOAT %prec tLOWEST
{
- $$ = negate_lit(p, $2);
+ $$ = new_negate(p, $2);
}
;
@@ -3501,12 +3580,7 @@ var_ref : variable
}
| keyword__ENCODING__
{
-#ifdef MRB_UTF8_STRING
- const char *enc = "UTF-8";
-#else
- const char *enc = "ASCII-8BIT";
-#endif
- $$ = new_str(p, enc, strlen(enc));
+ $$ = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0);
}
;
@@ -3547,39 +3621,21 @@ f_arglist_paren : '(' f_args rparen
}
| '(' f_arg ',' tBDOT3 rparen
{
-#if 1
- /* til real keyword args implemented */
- mrb_sym r = intern_op(mul);
- mrb_sym b = intern_op(and);
- local_add_f(p, r);
- $$ = new_args(p, $2, 0, r, 0,
- new_args_tail(p, 0, 0, b));
-#else
mrb_sym r = intern_op(mul);
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
- local_add_f(p, r); local_add_f(p, k);
+ local_add_f(p, r);
$$ = new_args(p, $2, 0, r, 0,
new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
-#endif
}
| '(' tBDOT3 rparen
{
-#if 1
- /* til real keyword args implemented */
- mrb_sym r = intern_op(mul);
- mrb_sym b = intern_op(and);
- local_add_f(p, r);
- $$ = new_args(p, 0, 0, r, 0,
- new_args_tail(p, 0, 0, b));
-#else
mrb_sym r = intern_op(mul);
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
- local_add_f(p, r); local_add_f(p, k);
+ local_add_f(p, r);
$$ = new_args(p, 0, 0, r, 0,
new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
-#endif
}
;
@@ -3938,22 +3994,22 @@ assocs : assoc
}
;
-label_tag : tLABEL_TAG
- | tLABEL_TAG heredoc_bodies
- ;
-
assoc : arg tASSOC arg
{
void_expr_error(p, $1);
void_expr_error(p, $3);
$$ = cons($1, $3);
}
- | tIDENTIFIER label_tag arg
+ | tIDENTIFIER tLABEL_TAG arg
{
void_expr_error(p, $3);
$$ = cons(new_sym(p, $1), $3);
}
- | string_fragment label_tag arg
+ | tIDENTIFIER tLABEL_TAG
+ {
+ $$ = cons(new_sym(p, $1), label_reference(p, $1));
+ }
+ | string_fragment tLABEL_TAG arg
{
void_expr_error(p, $3);
if (typen($1->car) == NODE_DSTR) {
@@ -4012,7 +4068,7 @@ opt_terms : /* none */
;
opt_nl : /* none */
- | nl
+ | opt_nl nl
;
rparen : opt_terms ')'
@@ -4025,7 +4081,6 @@ trailer : /* none */
term : ';' {yyerrok;}
| nl
- | heredoc_body
;
nl : '\n'
@@ -4033,6 +4088,7 @@ nl : '\n'
p->lineno += $<num>1;
p->column = 0;
}
+ | heredoc_body
;
terms : term
@@ -4087,7 +4143,7 @@ yyerror_c(parser_state *p, const char *msg, char c)
}
static void
-yywarn(parser_state *p, const char *s)
+yywarning(parser_state *p, const char *s)
{
char* c;
size_t n;
@@ -4115,12 +4171,6 @@ yywarn(parser_state *p, const char *s)
}
static void
-yywarning(parser_state *p, const char *s)
-{
- yywarn(p, s);
-}
-
-static void
yywarning_s(parser_state *p, const char *msg, const char *s)
{
char buf[256];
@@ -6225,10 +6275,10 @@ parser_yylex(parser_state *p)
if (last_state == EXPR_FNAME) goto gvar;
tokfix(p);
{
- unsigned long n = strtoul(tok(p), NULL, 10);
- if (n > INT_MAX) {
- yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
- return 0;
+ mrb_int n = mrb_int_read(tok(p), NULL, NULL);
+ if (n > INT32_MAX) {
+ yywarning(p, "capture group index too big; always nil");
+ return keyword_nil;
}
pylval.nd = new_nth_ref(p, (int)n);
}
@@ -6513,6 +6563,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt)
int i = 0;
if (!cxt) return;
+ if (!p->tree) return;
if (intn(p->tree->car) != NODE_SCOPE) return;
n0 = n = p->tree->cdr->car;
while (n) {
@@ -6533,53 +6584,39 @@ MRB_API void
mrb_parser_parse(parser_state *p, mrbc_context *c)
{
struct mrb_jmpbuf buf1;
- p->jmp = &buf1;
+ struct mrb_jmpbuf *prev = p->mrb->jmp;
+ p->mrb->jmp = &buf1;
- MRB_TRY(p->jmp) {
+ MRB_TRY(p->mrb->jmp) {
int n = 1;
p->cmd_start = TRUE;
p->in_def = p->in_single = 0;
p->nerr = p->nwarn = 0;
p->lex_strterm = NULL;
-
parser_init_cxt(p, c);
- if (p->mrb->jmp) {
- n = yyparse(p);
- }
- else {
- struct mrb_jmpbuf buf2;
-
- p->mrb->jmp = &buf2;
- MRB_TRY(p->mrb->jmp) {
- n = yyparse(p);
- }
- MRB_CATCH(p->mrb->jmp) {
- p->nerr++;
- }
- MRB_END_EXC(p->mrb->jmp);
- p->mrb->jmp = 0;
- }
+ n = yyparse(p);
if (n != 0 || p->nerr > 0) {
p->tree = 0;
+ p->mrb->jmp = prev;
return;
}
- if (!p->tree) {
- p->tree = new_nil(p);
- }
parser_update_cxt(p, c);
if (c && c->dump_result) {
mrb_parser_dump(p->mrb, p->tree, 0);
}
}
- MRB_CATCH(p->jmp) {
- yyerror(p, "memory allocation error");
+ MRB_CATCH(p->mrb->jmp) {
p->nerr++;
- p->tree = 0;
- return;
+ if (p->mrb->exc == NULL) {
+ yyerror(p, "memory allocation error");
+ p->nerr++;
+ p->tree = 0;
+ }
}
MRB_END_EXC(p->jmp);
+ p->mrb->jmp = prev;
}
MRB_API parser_state*
@@ -6964,8 +7001,13 @@ dump_args(mrb_state *mrb, node *n, int offset)
}
n = n->cdr;
if (n->car) {
+ mrb_sym rest = sym(n->car);
+
dump_prefix(n, offset+1);
- printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
+ if (rest == MRB_OPSYM(mul))
+ printf("rest=*\n");
+ else
+ printf("rest=*%s\n", mrb_sym_name(mrb, rest));
}
n = n->cdr;
if (n->car) {
@@ -7242,9 +7284,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(tree, offset+1);
- printf("block:\n");
- mrb_parser_dump(mrb, tree->cdr, offset+2);
+ if (tree->cdr->car) {
+ dump_prefix(tree, offset+1);
+ printf("kwargs:\n");
+ mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+ }
+ if (tree->cdr->cdr) {
+ dump_prefix(tree, offset+1);
+ printf("block:\n");
+ mrb_parser_dump(mrb, tree->cdr->cdr, offset+2);
+ }
}
}
break;
@@ -7385,7 +7434,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_ZSUPER:
- printf("NODE_ZSUPER\n");
+ printf("NODE_ZSUPER:\n");
+ if (tree) {
+ dump_prefix(tree, offset+1);
+ printf("args:\n");
+ dump_recur(mrb, tree->car, offset+2);
+ if (tree->cdr) {
+ dump_prefix(tree, offset+1);
+ printf("block:\n");
+ mrb_parser_dump(mrb, tree->cdr, offset+2);
+ }
+ }
break;
case NODE_RETURN:
@@ -7711,7 +7770,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_KW_REST_ARGS:
- printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
+ if (tree)
+ printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
+ else
+ printf("NODE_KW_REST_ARGS\n");
break;
default:
@@ -7720,3 +7782,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
}
#endif
}
+
+typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user);
+void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user);
+
+void
+mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user)
+{
+ const mrb_ast_node *n = p->tree;
+ if ((intptr_t)n->car == NODE_SCOPE) {
+ n = n->cdr->car;
+ for (; n; n = n->cdr) {
+ mrb_sym sym = sym(n->car);
+ if (sym && !func(mrb, sym, user)) break;
+ }
+ }
+}