1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* eval.c (svalue_to_avalue): need to splat but no error.

* eval.c: new macros - YIELD_CALL, YIELD_VALUES.

* eval.c (rb_yield_values): specify YIELD_VALUES.

* eval.c (rb_yield_0): use new macros.

* eval.c (proc_invoke): slightly modified to separate YIELD_CALL
  and YIELD_VALUES from YIELD_ARY_ARGS.

* object.c (Init_Object): add nil.to_splat => [].


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11284 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2006-11-06 10:27:59 +00:00
parent 2ec88c167b
commit 862e723d03
4 changed files with 72 additions and 37 deletions

View file

@ -1,3 +1,18 @@
Mon Nov 6 18:54:13 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (svalue_to_avalue): need to splat but no error.
* eval.c: new macros - YIELD_CALL, YIELD_VALUES.
* eval.c (rb_yield_values): specify YIELD_VALUES.
* eval.c (rb_yield_0): use new macros.
* eval.c (proc_invoke): slightly modified to separate YIELD_CALL
and YIELD_VALUES from YIELD_ARY_ARGS.
* object.c (Init_Object): add nil.to_splat => [].
Mon Nov 6 15:41:55 2006 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk/itemconfig.rb: ext/tk/lib/tk/itemconfig.rb: bug

79
eval.c
View file

@ -224,6 +224,9 @@ VALUE rb_cProc;
VALUE rb_cBinding;
static VALUE proc_alloc(VALUE,struct BLOCK*,int);
static VALUE proc_invoke(VALUE,VALUE,VALUE,VALUE,int);
#define INVOKE_CALL (YIELD_CALL|YIELD_VALUES)
#define INVOKE_VALUES YIELD_VALUES
static VALUE proc_lambda(void);
static VALUE rb_f_binding(VALUE);
static void rb_f_END(void);
@ -1049,9 +1052,10 @@ static NODE *compile(VALUE, const char*, int);
static VALUE rb_yield_0(VALUE, VALUE, VALUE, int);
#define YIELD_ARY_ARGS 1
#define YIELD_PROC_INVOKE 2
#define YIELD_PUBLIC_DEF 4
#define YIELD_CALL 1
#define YIELD_VALUES 2
#define YIELD_PROC_INVOKE 4
#define YIELD_PUBLIC_DEF 8
#define YIELD_FUNC_AVALUE 1
#define YIELD_FUNC_SVALUE 2
@ -2608,31 +2612,33 @@ call_trace_func(rb_event_t event, NODE *node, VALUE self, ID id, VALUE klass /*
}
static VALUE
svalue_to_avalue(VALUE v)
{
VALUE tmp;
if (v == Qundef) return rb_ary_new2(0);
tmp = rb_check_array_type(v);
if (NIL_P(tmp)) {
return rb_ary_new3(1, v);
}
return tmp;
}
static VALUE
splat_value(VALUE v)
splat(VALUE v, int strict)
{
VALUE tmp;
if (v == Qundef) return rb_ary_new2(0);
tmp = rb_check_convert_type(v, T_ARRAY, "Array", "to_splat");
if (NIL_P(tmp)) {
if (strict) {
rb_raise(rb_eTypeError, "failed to splat");
}
return rb_ary_new3(1, v);
}
return tmp;
}
static VALUE
svalue_to_avalue(VALUE v)
{
return splat(v, Qfalse);
}
static VALUE
splat_value(VALUE v)
{
return splat(v, Qtrue);
}
static VALUE
class_prefix(VALUE self, NODE *cpath)
{
@ -3006,7 +3012,7 @@ rb_eval(VALUE self, NODE *n)
result = Qundef; /* no arg */
}
SET_CURRENT_SOURCE();
result = rb_yield_0(result, 0, 0, 0);
result = rb_yield_0(result, 0, 0, node->nd_state ? YIELD_VALUES : 0);
break;
case NODE_RESCUE:
@ -4704,7 +4710,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags)
int old_vmode;
struct FRAME frame;
NODE *cnode = ruby_current_node;
int ary_args, lambda;
int lambda, call;
int state, broken = 0;
rb_need_block();
@ -4738,7 +4744,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags)
node = block->body;
var = block->var;
lambda = block->flags & BLOCK_LAMBDA;
ary_args = flags & YIELD_ARY_ARGS;
call = flags & YIELD_CALL;
if (var) {
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@ -4767,7 +4773,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags)
goto block_var;
}
else if (nd_type(var) == NODE_ARGS) {
if (!ary_args) val = svalue_to_avalue(val);
if (!(flags & YIELD_VALUES)) val = svalue_to_avalue(val);
formal_assign(self, var, RARRAY_LEN(val), RARRAY_PTR(val), 0);
}
else if (nd_type(var) == NODE_BLOCK) {
@ -4784,7 +4790,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags)
if (lambda && val == Qundef) {
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
}
if (ary_args) {
if (call) {
if (lambda && RARRAY_LEN(val) != 1) {
rb_raise(rb_eArgError, "wrong number of arguments (%ld for 1)",
RARRAY_LEN(val));
@ -4812,7 +4818,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags)
POP_TAG();
if (state) goto pop_state;
}
else if (lambda && ary_args && RARRAY_LEN(val) != 0 &&
else if (lambda && call && RARRAY_LEN(val) != 0 &&
(!node || nd_type(node) != NODE_IFUNC ||
node->nd_cfnc != bmcall)) {
rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
@ -4943,7 +4949,7 @@ rb_yield_values(int n, ...)
rb_ary_push(val, va_arg(args, VALUE));
}
va_end(args);
return rb_yield_0(val, 0, 0, 0);
return rb_yield_0(val, 0, 0, YIELD_VALUES);
}
/*
@ -5799,7 +5805,8 @@ rb_call0(VALUE klass, VALUE recv, ID id, ID oid,
Data_Get_Struct(body->nd_cval, struct BLOCK, data);
EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
}
result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass, 1);
result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass,
INVOKE_CALL);
if (event_hooks) {
EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
}
@ -6510,7 +6517,7 @@ yield_under_i(VALUE arg)
{
VALUE *args = (VALUE *)arg;
int flags = YIELD_PUBLIC_DEF;
if (args[0] != Qundef) flags |= YIELD_ARY_ARGS;
if (args[0] != Qundef) flags |= YIELD_VALUES;
return rb_yield_0(args[0], args[1], ruby_cbase, flags);
}
@ -7692,7 +7699,7 @@ call_end_proc(VALUE data)
PUSH_FRAME(Qfalse);
ruby_frame->self = ruby_frame->prev->self;
ruby_frame->node = 0;
proc_invoke(data, rb_ary_new2(0), Qundef, 0, 1);
proc_invoke(data, rb_ary_new2(0), Qundef, 0, INVOKE_VALUES);
POP_FRAME();
}
@ -8453,7 +8460,7 @@ block_orphan(struct BLOCK *data)
}
static VALUE
proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int flags)
{
struct BLOCK _block;
struct BLOCK *data;
@ -8461,12 +8468,11 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
int state;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
volatile int pcall, lambda;
volatile int lambda;
VALUE bvar = 0;
Data_Get_Struct(proc, struct BLOCK, data);
pcall = call ? YIELD_ARY_ARGS : 0;
pcall |= YIELD_PROC_INVOKE;
flags |= YIELD_PROC_INVOKE;
lambda = data->flags & BLOCK_LAMBDA;
if (rb_block_given_p() && ruby_frame->callee) {
if (klass != ruby_frame->this_class)
@ -8481,7 +8487,7 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
_block.block_obj = bvar;
if (self != Qundef) _block.frame.self = self;
if (klass) _block.frame.this_class = klass;
_block.frame.argc = call ? RARRAY_LEN(args) : 1;
_block.frame.argc = (flags&YIELD_CALL) ? RARRAY_LEN(args) : 1;
_block.frame.flags = ruby_frame->flags;
if (_block.frame.argc && (ruby_frame->flags & FRAME_DMETH)) {
NEWOBJ(scope, struct SCOPE);
@ -8496,7 +8502,7 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(proc);
result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall);
result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, flags);
}
else if (TAG_DST()) {
result = prot_tag->retval;
@ -8520,7 +8526,8 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
JUMP_TAG(state);
case TAG_RETURN:
if (result != Qundef) {
if (pcall) break;
if (flags & YIELD_CALL)
break;
return_jump(result);
}
default:
@ -8566,7 +8573,7 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call)
VALUE
rb_proc_call(VALUE proc, VALUE args /* OK */)
{
return proc_invoke(proc, args, Qundef, 0, 1);
return proc_invoke(proc, args, Qundef, 0, INVOKE_CALL);
}
/*
@ -8595,7 +8602,7 @@ rb_proc_yield(int argc, VALUE *argv, VALUE proc)
case 0:
return proc_invoke(proc, Qundef, Qundef, 0, 0);
default:
return proc_invoke(proc, rb_ary_new4(argc, argv), Qundef, 0, 0);
return proc_invoke(proc, rb_ary_new4(argc, argv), Qundef, 0, INVOKE_VALUES);
}
}

View file

@ -714,6 +714,8 @@ nil_to_s(VALUE obj)
}
/*
* Document-method: to_a
*
* call-seq:
* nil.to_a => []
*
@ -722,6 +724,16 @@ nil_to_s(VALUE obj)
* nil.to_a #=> []
*/
/*
* Document-method: to_splat
*
* call-seq:
* nil.to_splat => []
*
* Always returns an empty array.
*
*/
static VALUE
nil_to_a(VALUE obj)
{
@ -2333,6 +2345,7 @@ Init_Object(void)
rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
rb_define_method(rb_cNilClass, "to_splat", nil_to_a, 0);
rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
rb_define_method(rb_cNilClass, "&", false_and, 1);
rb_define_method(rb_cNilClass, "|", false_or, 1);

View file

@ -1006,7 +1006,7 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
| mlhs '=' arg_value
{
/*%%%*/
$1->nd_value = NEW_SPLAT($3);
$1->nd_value = $3;
$$ = $1;
/*%
dispatch2(massign, $1, $3);