зеркало из https://github.com/github/ruby.git
* parse.y, node.h, compile.c: change node tree structure. a purpose
of this change is to unify argument structure of method and block. this change prohibits duplicate block parameter name. new argument infromation: NODE_ARGS [m: int, o: NODE_OPT_ARG, ->] NODE_ARGS_AUX [r: ID, b: ID, ->] NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*] optarg information: NODE_OPT_ARGS [idx, expr, ->] * vm_macro.def: ditto. * gc.c: ditto. * iseq.c: ditto. * compile.h: fix debug function name. * test/ripper/test_scanner_events.rb: |_,_,foo| -> |_1,_2,foo| * test/ruby/test_lambda.rb: disalbe test temporarily. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11840 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
c5148e0383
Коммит
0fe72040e4
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
Sat Feb 24 10:49:55 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* parse.y, node.h, compile.c: change node tree structure. a purpose
|
||||
of this change is to unify argument structure of method and block.
|
||||
this change prohibits duplicate block parameter name.
|
||||
new argument infromation:
|
||||
NODE_ARGS [m: int, o: NODE_OPT_ARG, ->]
|
||||
NODE_ARGS_AUX [r: ID, b: ID, ->]
|
||||
NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*]
|
||||
optarg information:
|
||||
NODE_OPT_ARGS [idx, expr, ->]
|
||||
|
||||
* vm_macro.def: ditto.
|
||||
|
||||
* gc.c: ditto.
|
||||
|
||||
* iseq.c: ditto.
|
||||
|
||||
* compile.h: fix debug function name.
|
||||
|
||||
* test/ripper/test_scanner_events.rb: |_,_,foo| -> |_1,_2,foo|
|
||||
|
||||
* test/ruby/test_lambda.rb: disalbe test temporarily.
|
||||
|
||||
Sat Feb 24 10:46:28 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* test/testunit/test_testcase.rb: catch up with current instance
|
||||
|
|
115
compile.c
115
compile.c
|
@ -147,7 +147,6 @@ iseq_compile(VALUE self, NODE *narg)
|
|||
|
||||
debugs("[compile step 1 (traverse each node)]\n");
|
||||
|
||||
|
||||
iseq->node = node;
|
||||
|
||||
if (iseq->type == ISEQ_TYPE_BLOCK) {
|
||||
|
@ -1035,7 +1034,7 @@ set_block_local_tbl(rb_iseq_t *iseq, NODE * node, LINK_ANCHOR *anchor)
|
|||
}
|
||||
}
|
||||
|
||||
if (iseq->arg_opts || iseq->arg_rest) {
|
||||
if (iseq->arg_opts || iseq->arg_rest || iseq->arg_block) {
|
||||
iseq->arg_simple = 0;
|
||||
}
|
||||
else {
|
||||
|
@ -1077,9 +1076,96 @@ get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
#if 1
|
||||
|
||||
static int
|
||||
set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_arg)
|
||||
{
|
||||
NODE *node_aux = node_arg->nd_next;
|
||||
int mandatory_len = 0;
|
||||
NODE *node_opt = 0;
|
||||
ID rest_id = 0;
|
||||
ID block_id = 0;
|
||||
ID post_start_id = 0;
|
||||
int post_len = 0;
|
||||
NODE *node_init = 0;
|
||||
|
||||
iseq->argc = node_arg->nd_frml;
|
||||
node_opt = node_arg->nd_opt;
|
||||
|
||||
if (node_aux) {
|
||||
rest_id = node_aux->nd_rest;
|
||||
block_id = (ID)node_aux->nd_body;
|
||||
node_aux = node_aux->nd_next;
|
||||
|
||||
if (node_aux) {
|
||||
post_start_id = node_aux->nd_pid;
|
||||
post_len = node_aux->nd_plen;
|
||||
node_init = node_aux->nd_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_init) {
|
||||
COMPILE(optargs, "arguments", node_init);
|
||||
}
|
||||
|
||||
if (node_opt) {
|
||||
NODE *node = node_opt;
|
||||
LABEL *label;
|
||||
VALUE labels = rb_ary_new();
|
||||
int i = 0, j;
|
||||
|
||||
while (node) {
|
||||
label = NEW_LABEL(nd_line(node));
|
||||
rb_ary_push(labels, (VALUE)label | 1);
|
||||
ADD_LABEL(optargs, label);
|
||||
COMPILE_POPED(optargs, "optarg", node->nd_body);
|
||||
|
||||
node = node->nd_next;
|
||||
i += 1;
|
||||
}
|
||||
/* last label */
|
||||
label = NEW_LABEL(nd_line(node_arg));
|
||||
rb_ary_push(labels, (VALUE)label | 1);
|
||||
ADD_LABEL(optargs, label);
|
||||
i += 1;
|
||||
|
||||
iseq->arg_opts = i;
|
||||
iseq->arg_opt_tbl = ALLOC_N(VALUE, i);
|
||||
MEMCPY(iseq->arg_opt_tbl, RARRAY_PTR(labels), VALUE, i);
|
||||
for (j = 0; j < i; j++) {
|
||||
iseq->arg_opt_tbl[j] &= ~1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
iseq->arg_opts = 0;
|
||||
}
|
||||
|
||||
if ((long)rest_id == -1) {
|
||||
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, 0 /* dummy var */);
|
||||
}
|
||||
else if (rest_id) {
|
||||
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id);
|
||||
}
|
||||
if (iseq->arg_rest == -1) rb_bug("arg_rest: -1");
|
||||
|
||||
|
||||
if (block_id) {
|
||||
iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id);
|
||||
}
|
||||
|
||||
if (iseq->arg_rest != 0 || iseq->arg_opts != 0 || iseq->arg_block != 0) {
|
||||
iseq->arg_simple = 0;
|
||||
}
|
||||
else {
|
||||
iseq->arg_simple = 1;
|
||||
}
|
||||
|
||||
return COMPILE_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
*/
|
||||
static int
|
||||
set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
|
||||
{
|
||||
|
@ -1121,7 +1207,9 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
|
|||
|
||||
iseq->arg_opts = i;
|
||||
iseq->arg_opt_tbl = ALLOC_N(VALUE, i);
|
||||
|
||||
MEMCPY(iseq->arg_opt_tbl, RARRAY_PTR(labels), VALUE, i);
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
iseq->arg_opt_tbl[j] &= ~1;
|
||||
}
|
||||
|
@ -1144,6 +1232,7 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
|
|||
}
|
||||
return COMPILE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
set_localtbl(rb_iseq_t *iseq, ID *tbl)
|
||||
|
@ -3681,6 +3770,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
int idx = liseq->local_size - i;
|
||||
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
|
||||
}
|
||||
|
||||
if (!liseq->arg_simple) {
|
||||
if (liseq->arg_opts) {
|
||||
/* optional arguments */
|
||||
|
@ -3693,13 +3783,20 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
i += j;
|
||||
argc = INT2FIX(i);
|
||||
}
|
||||
|
||||
if (liseq->arg_rest) {
|
||||
/* rest arguments */
|
||||
int idx = liseq->local_size - liseq->arg_rest + 1;
|
||||
ADD_INSN1(args, nd_line(node), getlocal,
|
||||
INT2FIX(idx));
|
||||
argc = INT2FIX(liseq->arg_rest);
|
||||
flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||
|
||||
if (liseq->arg_rest == -1) {
|
||||
/* TODO */
|
||||
}
|
||||
else {
|
||||
int idx = liseq->local_size - liseq->arg_rest + 1;
|
||||
ADD_INSN1(args, nd_line(node), getlocal,
|
||||
INT2FIX(idx));
|
||||
argc = INT2FIX(liseq->arg_rest);
|
||||
flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
compile.h
18
compile.h
|
@ -41,27 +41,27 @@
|
|||
#if CPDEBUG > 0
|
||||
|
||||
#define debugp(header, value) \
|
||||
(debug_indent(0, CPDEBUG, gl_node_level * 2), \
|
||||
(ruby_debug_indent(0, CPDEBUG, gl_node_level * 2), \
|
||||
ruby_debug_value(0, CPDEBUG, header, value))
|
||||
|
||||
#define debugi(header, id) \
|
||||
(debug_indent(0, CPDEBUG, gl_node_level * 2), \
|
||||
debug_id(0, CPDEBUG, header, id))
|
||||
(ruby_debug_indent(0, CPDEBUG, gl_node_level * 2), \
|
||||
ruby_debug_id(0, CPDEBUG, header, id))
|
||||
|
||||
#define debugp_param(header, value) \
|
||||
(debug_indent(1, CPDEBUG, gl_node_level * 2), \
|
||||
(ruby_debug_indent(1, CPDEBUG, gl_node_level * 2), \
|
||||
ruby_debug_value(1, CPDEBUG, header, value))
|
||||
|
||||
#define debugp_verbose(header, value) \
|
||||
(debug_indent(2, CPDEBUG, gl_node_level * 2), \
|
||||
(ruby_debug_indent(2, CPDEBUG, gl_node_level * 2), \
|
||||
ruby_debug_value(2, CPDEBUG, header, value))
|
||||
|
||||
#define debugp_verbose_node(header, value) \
|
||||
(debug_indent(10, CPDEBUG, gl_node_level * 2), \
|
||||
(ruby_debug_indent(10, CPDEBUG, gl_node_level * 2), \
|
||||
ruby_debug_value(10, CPDEBUG, header, value))
|
||||
|
||||
#define debug_nodeprint(node) \
|
||||
debug_indent(-1, CPDEBUG, gl_node_level*2); \
|
||||
ruby_debug_indent(-1, CPDEBUG, gl_node_level*2); \
|
||||
printf("node: %s (%d)\n", ruby_node_name(nd_type(node)), nd_line(node)); \
|
||||
gl_node_level ++;
|
||||
|
||||
|
@ -91,8 +91,8 @@ r_value(VALUE value)
|
|||
#endif
|
||||
|
||||
#if CPDEBUG > 1
|
||||
#define debugs debug_indent(-1, CPDEBUG, gl_node_level*2), printf
|
||||
#define debug_compile(msg, v) (debug_indent(-1, CPDEBUG, gl_node_level*2), printf("%s", msg), (v))
|
||||
#define debugs ruby_debug_indent(-1, CPDEBUG, gl_node_level*2), printf
|
||||
#define debug_compile(msg, v) (ruby_debug_indent(-1, CPDEBUG, gl_node_level*2), printf("%s", msg), (v))
|
||||
#else
|
||||
#define debugs if(0)printf
|
||||
#define debug_compile(msg, v) (v)
|
||||
|
|
4
gc.c
4
gc.c
|
@ -844,7 +844,6 @@ gc_mark_children(VALUE ptr, int lev)
|
|||
case NODE_RESCUE:
|
||||
case NODE_RESBODY:
|
||||
case NODE_CLASS:
|
||||
case NODE_ARGS:
|
||||
case NODE_BLOCK_PASS:
|
||||
gc_mark((VALUE)obj->as.node.u2.node, lev);
|
||||
/* fall through */
|
||||
|
@ -859,11 +858,13 @@ gc_mark_children(VALUE ptr, int lev)
|
|||
case NODE_CALL:
|
||||
case NODE_DEFS:
|
||||
case NODE_OP_ASGN1:
|
||||
case NODE_ARGS:
|
||||
gc_mark((VALUE)obj->as.node.u1.node, lev);
|
||||
/* fall through */
|
||||
case NODE_SUPER: /* 3 */
|
||||
case NODE_FCALL:
|
||||
case NODE_DEFN:
|
||||
case NODE_ARGS_AUX:
|
||||
ptr = (VALUE)obj->as.node.u3.node;
|
||||
goto again;
|
||||
|
||||
|
@ -922,6 +923,7 @@ gc_mark_children(VALUE ptr, int lev)
|
|||
|
||||
case NODE_SCOPE: /* 2,3 */
|
||||
case NODE_CDECL:
|
||||
case NODE_OPT_ARG:
|
||||
gc_mark((VALUE)obj->as.node.u3.node, lev);
|
||||
ptr = (VALUE)obj->as.node.u2.node;
|
||||
goto again;
|
||||
|
|
11
iseq.c
11
iseq.c
|
@ -542,10 +542,15 @@ insn_operand_intern(rb_iseq_t *iseq,
|
|||
case TS_LINDEX:
|
||||
{
|
||||
rb_iseq_t *ip = iseq->local_iseq;
|
||||
int lidx = ip->local_size - op + 1;
|
||||
ID id = ip->local_tbl[lidx];
|
||||
|
||||
ret =
|
||||
rb_str_new2(
|
||||
rb_id2name(ip->local_tbl[ip->local_size - op + 1]));
|
||||
if (id) {
|
||||
ret = rb_str_new2(rb_id2name(id));
|
||||
}
|
||||
else {
|
||||
ret = rb_str_new2("*");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TS_DINDEX:{
|
||||
|
|
14
node.h
14
node.h
|
@ -87,6 +87,8 @@ enum node_type {
|
|||
NODE_DREGX,
|
||||
NODE_DREGX_ONCE,
|
||||
NODE_ARGS,
|
||||
NODE_ARGS_AUX,
|
||||
NODE_OPT_ARG,
|
||||
NODE_POSTARG,
|
||||
NODE_ARGSCAT,
|
||||
NODE_ARGSPUSH,
|
||||
|
@ -209,9 +211,11 @@ typedef struct RNode {
|
|||
|
||||
#define nd_lit u1.value
|
||||
|
||||
#define nd_frml u3.value
|
||||
#define nd_rest u2.node
|
||||
#define nd_frml u2.argc
|
||||
#define nd_rest u1.id
|
||||
#define nd_opt u1.node
|
||||
#define nd_pid u1.id
|
||||
#define nd_plen u2.argc
|
||||
|
||||
#define nd_recv u1.node
|
||||
#define nd_mid u2.id
|
||||
|
@ -315,8 +319,10 @@ typedef struct RNode {
|
|||
#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
|
||||
#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
|
||||
#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
|
||||
#define NEW_ARGS(f,o,r) NEW_NODE(NODE_ARGS,o,r,f)
|
||||
#define NEW_POSTARG(r,m) NEW_NODE(NODE_POSTARG,m,0,r)
|
||||
#define NEW_ARGS(m,o) NEW_NODE(NODE_ARGS,o,m,0)
|
||||
#define NEW_ARGS_AUX(r,b) NEW_NODE(NODE_ARGS_AUX,r,b,0)
|
||||
#define NEW_OPT_ARG(i,v) NEW_NODE(NODE_OPT_ARG,i,v,0)
|
||||
#define NEW_POSTARG(i,v) NEW_NODE(NODE_POSTARG,i,v,0)
|
||||
#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)
|
||||
#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)
|
||||
#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)
|
||||
|
|
141
parse.y
141
parse.y
|
@ -346,7 +346,7 @@ static NODE *evstr2dstr(NODE*);
|
|||
static NODE *call_op_gen(struct parser_params*,NODE*,ID,int,NODE*);
|
||||
#define call_op(recv,id,narg,arg1) call_op_gen(parser, recv,id,narg,arg1)
|
||||
|
||||
static NODE *new_args_gen(struct parser_params*,VALUE,NODE*,NODE*,NODE*,NODE*);
|
||||
static NODE *new_args_gen(struct parser_params*,int,NODE*,ID,NODE*,ID);
|
||||
#define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
|
||||
static void shadowing_lvar_gen(struct parser_params*,ID);
|
||||
#define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
|
||||
|
@ -617,15 +617,15 @@ static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
|
|||
%type <node> open_args paren_args opt_paren_args
|
||||
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
|
||||
%type <node> mrhs superclass block_call block_command
|
||||
%type <node> f_arglist f_args f_rest_arg f_post_arg
|
||||
%type <node> f_optarg f_opt f_block_arg opt_f_block_arg
|
||||
%type <node> f_arglist f_args f_post_arg
|
||||
%type <node> f_optarg f_opt
|
||||
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
|
||||
%type <node> block_param opt_block_param block_param_def bparam_list bparam_item
|
||||
%type <node> opt_bv_decl bv_decls bvar lambda f_larglist lambda_body
|
||||
%type <node> brace_block cmd_brace_block do_block lhs none fitem
|
||||
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post
|
||||
%type <id> fsym variable sym symbol operation operation2 operation3
|
||||
%type <id> cname fname op f_norm_arg
|
||||
%type <id> cname fname op f_norm_arg f_rest_arg f_block_arg opt_f_block_arg
|
||||
%type <val> f_arg
|
||||
/*%%%*/
|
||||
/*%
|
||||
|
@ -4151,13 +4151,7 @@ f_norm_arg : tCONSTANT
|
|||
/*%%%*/
|
||||
if (!is_local_id($1))
|
||||
yyerror("formal argument must be local variable");
|
||||
if (dyna_in_block()) {
|
||||
shadowing_lvar($1);
|
||||
dyna_var($1);
|
||||
}
|
||||
else {
|
||||
local_cnt($1);
|
||||
}
|
||||
shadowing_lvar($1);
|
||||
$$ = $1;
|
||||
/*%
|
||||
$$ = $1;
|
||||
|
@ -4167,32 +4161,18 @@ f_norm_arg : tCONSTANT
|
|||
|
||||
f_arg : f_norm_arg
|
||||
{
|
||||
/*%%%*/
|
||||
VALUE arg = ID2SYM($1);
|
||||
/*%
|
||||
VALUE arg = $1;
|
||||
%*/
|
||||
$$ = rb_ary_new3(1, arg);
|
||||
$$ = 1;
|
||||
}
|
||||
| f_arg ',' f_norm_arg
|
||||
{
|
||||
/*%%%*/
|
||||
VALUE arg = ID2SYM($3);
|
||||
$$ = $1;
|
||||
if (rb_ary_includes($$, arg)) {
|
||||
yyerror("duplicated argument name");
|
||||
}
|
||||
rb_ary_push($$, arg);
|
||||
/*%
|
||||
rb_ary_push($$, $3);
|
||||
%*/
|
||||
$$ = $1 + 1;
|
||||
}
|
||||
;
|
||||
|
||||
f_post_arg : f_norm_arg
|
||||
{
|
||||
/*%%%*/
|
||||
$$ = NEW_LIST(assignable($1, 0));
|
||||
$$ = NEW_ARGS_AUX($1, 1);
|
||||
/*%
|
||||
$$ = mlhs_add(mlhs_new(), $1);
|
||||
%*/
|
||||
|
@ -4200,7 +4180,8 @@ f_post_arg : f_norm_arg
|
|||
| f_post_arg ',' f_norm_arg
|
||||
{
|
||||
/*%%%*/
|
||||
$$ = list_append($1, assignable($3, 0));
|
||||
$1->nd_alen++;
|
||||
$$ = $1;
|
||||
/*%
|
||||
$$ = mlhs_add($1, $3);
|
||||
%*/
|
||||
|
@ -4212,11 +4193,8 @@ f_opt : tIDENTIFIER '=' arg_value
|
|||
/*%%%*/
|
||||
if (!is_local_id($1))
|
||||
yyerror("formal argument must be local variable");
|
||||
if (dyna_in_block()) {
|
||||
shadowing_lvar($1);
|
||||
dyna_var($1);
|
||||
}
|
||||
$$ = assignable($1, $3);
|
||||
shadowing_lvar($1);
|
||||
$$ = NEW_OPT_ARG(0, assignable($1, $3));
|
||||
/*%
|
||||
$$ = rb_assoc_new($1, $3);
|
||||
%*/
|
||||
|
@ -4226,8 +4204,7 @@ f_opt : tIDENTIFIER '=' arg_value
|
|||
f_optarg : f_opt
|
||||
{
|
||||
/*%%%*/
|
||||
$$ = NEW_BLOCK($1);
|
||||
$$->nd_end = $$;
|
||||
$$ = $1;
|
||||
/*%
|
||||
$$ = rb_ary_new3(1, $1);
|
||||
%*/
|
||||
|
@ -4235,7 +4212,13 @@ f_optarg : f_opt
|
|||
| f_optarg ',' f_opt
|
||||
{
|
||||
/*%%%*/
|
||||
$$ = block_append($1, $3);
|
||||
NODE *opts = $1;
|
||||
|
||||
while (opts->nd_next) {
|
||||
opts = opts->nd_next;
|
||||
}
|
||||
opts->nd_next = $3;
|
||||
$$ = $1;
|
||||
/*%
|
||||
$$ = rb_ary_push($1, $3);
|
||||
%*/
|
||||
|
@ -4251,11 +4234,8 @@ f_rest_arg : restarg_mark tIDENTIFIER
|
|||
/*%%%*/
|
||||
if (!is_local_id($2))
|
||||
yyerror("rest argument must be local variable");
|
||||
if (dyna_in_block()) {
|
||||
shadowing_lvar($2);
|
||||
dyna_var($2);
|
||||
}
|
||||
$$ = assignable($2, 0);
|
||||
shadowing_lvar($2);
|
||||
$$ = $2;
|
||||
/*%
|
||||
$$ = dispatch1(restparam, $2);
|
||||
%*/
|
||||
|
@ -4264,10 +4244,11 @@ f_rest_arg : restarg_mark tIDENTIFIER
|
|||
{
|
||||
/*%%%*/
|
||||
if (dyna_in_block()) {
|
||||
$$ = NEW_DASGN_CURR(internal_id(), 0);
|
||||
$$ = internal_id();
|
||||
}
|
||||
else {
|
||||
$$ = NEW_NODE(NODE_LASGN,0,0,local_append(0));
|
||||
local_append(0);
|
||||
$$ = -1;
|
||||
}
|
||||
/*%
|
||||
$$ = dispatch1(restparam, Qnil);
|
||||
|
@ -4286,14 +4267,8 @@ f_block_arg : blkarg_mark tIDENTIFIER
|
|||
yyerror("block argument must be local variable");
|
||||
else if (!dyna_in_block() && local_id($2))
|
||||
yyerror("duplicated block argument name");
|
||||
if (dyna_in_block()) {
|
||||
shadowing_lvar($2);
|
||||
dyna_var($2);
|
||||
$$ = assignable($2, 0);
|
||||
}
|
||||
else {
|
||||
$$ = NEW_BLOCK_ARG($2);
|
||||
}
|
||||
shadowing_lvar($2);
|
||||
$$ = $2;
|
||||
/*%
|
||||
$$ = $2;
|
||||
%*/
|
||||
|
@ -4305,6 +4280,9 @@ opt_f_block_arg : ',' f_block_arg
|
|||
$$ = $2;
|
||||
}
|
||||
| none
|
||||
{
|
||||
$$ = 0 ;
|
||||
}
|
||||
;
|
||||
|
||||
singleton : var_ref
|
||||
|
@ -7314,9 +7292,21 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
|
|||
static void
|
||||
shadowing_lvar_gen(struct parser_params *parser, ID name)
|
||||
{
|
||||
if (dvar_defined(name) || local_id(name)) {
|
||||
rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
|
||||
}
|
||||
if (dyna_in_block()) {
|
||||
if (dvar_curr(name)) {
|
||||
yyerror("duplicated argument name");
|
||||
}
|
||||
else if (dvar_defined(name) || local_id(name)) {
|
||||
rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
|
||||
}
|
||||
dyna_var(name);
|
||||
}
|
||||
else {
|
||||
if (local_id(name)) {
|
||||
yyerror("duplicated argument name");
|
||||
}
|
||||
local_cnt(name);
|
||||
}
|
||||
}
|
||||
|
||||
static NODE*
|
||||
|
@ -7966,47 +7956,14 @@ arg_dup_check(ID vid, VALUE m, VALUE list, NODE *node)
|
|||
}
|
||||
|
||||
static NODE*
|
||||
new_args_gen(struct parser_params *parser, VALUE m, NODE *o, NODE *r, NODE *p, NODE *b)
|
||||
new_args_gen(struct parser_params *parser, int m, NODE *o, ID r, NODE *p, ID b)
|
||||
{
|
||||
int saved_line = ruby_sourceline;
|
||||
NODE *node;
|
||||
VALUE list;
|
||||
NODE *node = NEW_ARGS(m, o);
|
||||
|
||||
list = rb_ary_new();
|
||||
node = o;
|
||||
while (node) {
|
||||
if (!node->nd_head) break;
|
||||
if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
|
||||
yyerror("duplicated optional argument name");
|
||||
return 0;
|
||||
}
|
||||
node = node->nd_next;
|
||||
}
|
||||
if (RTEST(r)) {
|
||||
if (arg_dup_check(r->nd_vid, m, list, r)) {
|
||||
yyerror("duplicated rest argument name");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
node->nd_next = NEW_ARGS_AUX(r, b);
|
||||
if (p) {
|
||||
node = p;
|
||||
while (node) {
|
||||
if (!node->nd_head) break;
|
||||
if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
|
||||
yyerror("duplicated argument name");
|
||||
return 0;
|
||||
}
|
||||
node = node->nd_next;
|
||||
}
|
||||
r = NEW_POSTARG(r, p);
|
||||
}
|
||||
node = NEW_ARGS(m, o, r);
|
||||
if (b) {
|
||||
if (arg_dup_check(b->nd_vid, m, list, b)) {
|
||||
yyerror("duplicated block argument name");
|
||||
return 0;
|
||||
}
|
||||
node = block_append(node, b);
|
||||
node->nd_next->nd_next = p;
|
||||
}
|
||||
ruby_sourceline = saved_line;
|
||||
return node;
|
||||
|
|
|
@ -17,7 +17,7 @@ class TestRipper_ScannerEvents < Test::Unit::TestCase
|
|||
|
||||
def scan(target, str)
|
||||
sym = "on_#{target}".intern
|
||||
Ripper.lex(str).select {|_,type,_| type == sym }.map {|_,_,tok| tok }
|
||||
Ripper.lex(str).select {|_1,type,_2| type == sym }.map {|_1,_2,tok| tok }
|
||||
end
|
||||
|
||||
def test_tokenize
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
require 'test/unit'
|
||||
|
||||
__END__
|
||||
|
||||
class TestLambdaParameters < Test::Unit::TestCase
|
||||
def test_call_simple
|
||||
assert_equal(1, ->(a){ a }.call(1))
|
||||
|
|
81
vm_macro.def
81
vm_macro.def
|
@ -86,7 +86,8 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
GetISeqPtr(niseqval, niseq);
|
||||
|
||||
clear_local_size = niseq->local_size - num;
|
||||
/* set arguments */
|
||||
|
||||
/* simple (only mandatory) arguments */
|
||||
if (niseq->arg_simple) {
|
||||
if (niseq->argc != num) {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%lu for %d)",
|
||||
|
@ -94,7 +95,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* check optional arguments */
|
||||
/* optional arguments */
|
||||
if (niseq->arg_opts) {
|
||||
int iseq_argc = niseq->argc;
|
||||
int opts = niseq->arg_opts - 1;
|
||||
|
@ -110,10 +111,9 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
(unsigned long)num, iseq_argc);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
printf("num: %lu, opts: %d, iseq_argc: %d\n",
|
||||
(unsigned long)num, opts, iseq_argc);
|
||||
}
|
||||
if (0) printf("num: %lu, opts: %d, iseq_argc: %d\n",
|
||||
(unsigned long)num, opts, iseq_argc);
|
||||
|
||||
if (num - iseq_argc < opts) {
|
||||
opt_pc = niseq->arg_opt_tbl[num - iseq_argc];
|
||||
sp += opts - (num - iseq_argc);
|
||||
|
@ -124,23 +124,17 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
opt_pc = niseq->arg_opt_tbl[opts];
|
||||
}
|
||||
}
|
||||
/* check rest */
|
||||
if (niseq->arg_rest == -1) {
|
||||
if (niseq->arg_opts) {
|
||||
num = niseq->argc + niseq->arg_opts;
|
||||
}
|
||||
else {
|
||||
num = niseq->argc;
|
||||
}
|
||||
sp = &rsp[1 + num + 1];
|
||||
}
|
||||
else if (niseq->arg_rest != 0) {
|
||||
|
||||
/* rest argument */
|
||||
if (niseq->arg_rest != 0) {
|
||||
int rest = niseq->arg_rest - 1;
|
||||
int pack_size = num - rest;
|
||||
|
||||
if (0) {
|
||||
printf("num: %lu, rest: %d, ps: %d\n",
|
||||
(unsigned long)num, niseq->arg_rest, pack_size);
|
||||
}
|
||||
|
||||
if (pack_size < 0) {
|
||||
rb_raise(rb_eArgError,
|
||||
"wrong number of arguments (%lu for %d)",
|
||||
|
@ -165,6 +159,10 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
(niseq->arg_opts
|
||||
&& num == niseq->argc + niseq->arg_opts - 1)
|
||||
|| num == niseq->argc)) {
|
||||
|
||||
if (0) printf("num: %d, rest: %d, opts: %d, argc: %d\n",
|
||||
num, niseq->arg_rest, niseq->arg_opts, niseq->argc);
|
||||
|
||||
rb_raise(rb_eArgError,
|
||||
"wrong number of arguments (%lu for %d)",
|
||||
(unsigned long)num, niseq->argc);
|
||||
|
@ -189,6 +187,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
clear_local_size--;
|
||||
}
|
||||
}
|
||||
|
||||
/* stack overflow check */
|
||||
if (CHECK_STACK_OVERFLOW(th, GET_CFP(), niseq->stack_max + 0x100)) {
|
||||
rb_exc_raise(sysstack_error);
|
||||
|
@ -198,32 +197,30 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
*sp++ = Qnil;
|
||||
}
|
||||
|
||||
{
|
||||
if (0 && (flag & VM_CALL_TAILCALL_BIT)) {
|
||||
th->cfp++;
|
||||
push_frame(th, niseq, FRAME_MAGIC_METHOD,
|
||||
recv, (VALUE) blockptr,
|
||||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
}
|
||||
else if (0 &&
|
||||
(flag & VM_CALL_TAILRECURSION_BIT) && niseq == GET_ISEQ()) {
|
||||
/* do nothing */
|
||||
GET_CFP()->self = recv;
|
||||
SET_LFP(sp);
|
||||
SET_DFP(sp);
|
||||
*sp++ = (VALUE) blockptr;
|
||||
reg_cfp->sp = sp;
|
||||
reg_cfp->bp = sp;
|
||||
SET_PC(niseq->iseq_encoded + opt_pc);
|
||||
}
|
||||
else {
|
||||
push_frame(th, niseq,
|
||||
FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
|
||||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
reg_cfp->sp = rsp;
|
||||
}
|
||||
RESTORE_REGS();
|
||||
if (0 && (flag & VM_CALL_TAILCALL_BIT)) {
|
||||
th->cfp++;
|
||||
push_frame(th, niseq, FRAME_MAGIC_METHOD,
|
||||
recv, (VALUE) blockptr,
|
||||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
}
|
||||
else if (0 &&
|
||||
(flag & VM_CALL_TAILRECURSION_BIT) && niseq == GET_ISEQ()) {
|
||||
/* do nothing */
|
||||
GET_CFP()->self = recv;
|
||||
SET_LFP(sp);
|
||||
SET_DFP(sp);
|
||||
*sp++ = (VALUE) blockptr;
|
||||
reg_cfp->sp = sp;
|
||||
reg_cfp->bp = sp;
|
||||
SET_PC(niseq->iseq_encoded + opt_pc);
|
||||
}
|
||||
else {
|
||||
push_frame(th, niseq,
|
||||
FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
|
||||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
reg_cfp->sp = rsp;
|
||||
}
|
||||
RESTORE_REGS();
|
||||
}
|
||||
|
||||
MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr)
|
||||
|
|
Загрузка…
Ссылка в новой задаче