mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* parse.y (new_yield): distinguish "yield 1,2" and "yield [1,2]".
[ruby-dev:20360] * eval.c (rb_eval): support new_yield() change. * variable.c (rb_const_get_0): warn for Foo::BAR when BAR is a toplevel constant (i.e. a constant defined under Object). [ruby-list:36935] * parse.y (no_blockarg): separate no block argument check and ret_args argument processing. * range.c (rb_range_beg_len): out_of_range check after adjusting end point. [ruby-dev:20370] * parse.y (call_args): the first argument to arg_cancat() should be NODE_LIST. [ruby-core:01151] * eval.c (rb_eval): should dispatch based on ID type. * eval.c (rb_yield_0): should restore scope_vmode during yield. [ruby-dev:20361] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3967 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
65ba3eba64
commit
f289fddace
10 changed files with 151 additions and 40 deletions
33
ChangeLog
33
ChangeLog
|
@ -12,6 +12,20 @@ Fri Jun 20 15:04:28 2003 NAKAMURA Usaku <usa@ruby-lang.org>
|
|||
|
||||
* ruby.c (proc_options): ditto.
|
||||
|
||||
Fri Jun 20 03:09:21 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (new_yield): distinguish "yield 1,2" and "yield [1,2]".
|
||||
[ruby-dev:20360]
|
||||
|
||||
* eval.c (rb_eval): support new_yield() change.
|
||||
|
||||
* variable.c (rb_const_get_0): warn for Foo::BAR when BAR is a
|
||||
toplevel constant (i.e. a constant defined under Object).
|
||||
[ruby-list:36935]
|
||||
|
||||
* parse.y (no_blockarg): separate no block argument check and
|
||||
ret_args argument processing.
|
||||
|
||||
Fri Jun 20 00:45:19 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
||||
|
||||
* lib/csv.rb: Import csv module.
|
||||
|
@ -32,12 +46,31 @@ Thu Jun 19 13:13:10 2003 NAKAMURA Usaku <usa@ruby-lang.org>
|
|||
* hash.c (env_delete, rb_f_getenv, env_fetch): case insensitive to
|
||||
access environment variables on DOSISH platforms.
|
||||
|
||||
Thu Jun 19 00:51:47 2003 NAKAMURA Hiroshi <nakahiro@sarion.co.jp>
|
||||
|
||||
* range.c (rb_range_beg_len): out_of_range check after adjusting
|
||||
end point. [ruby-dev:20370]
|
||||
|
||||
Wed Jun 18 23:59:11 2003 Guy Decoux <ts@moulon.inra.fr>
|
||||
|
||||
* parse.y (call_args): the first argument to arg_cancat() should
|
||||
be NODE_LIST. [ruby-core:01151]
|
||||
|
||||
Wed Jun 18 23:41:27 2003 Marc Cartright <marc@isri.unlv.edu>
|
||||
|
||||
* ext/zlib/zlib.c (zstream_run): In a particular situation,
|
||||
deflate/inflate will return Z_BUF_ERROR, even though another call
|
||||
is required by the zlib library.
|
||||
|
||||
Wed Jun 18 13:50:06 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_eval): should dispatch based on ID type.
|
||||
|
||||
Wed Jun 18 12:53:42 2003 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* eval.c (rb_yield_0): should restore scope_vmode during yield.
|
||||
[ruby-dev:20361]
|
||||
|
||||
Wed Jun 18 01:13:36 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
|
||||
|
||||
* ext/syck/rubyext.c (rb_syck_load_handler): merge key implemented.
|
||||
|
|
4
class.c
4
class.c
|
@ -229,7 +229,7 @@ rb_define_class_under(outer, name, super)
|
|||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined_at(outer, id)) {
|
||||
klass = rb_const_get(outer, id);
|
||||
klass = rb_const_get_at(outer, id);
|
||||
if (TYPE(klass) != T_CLASS) {
|
||||
rb_raise(rb_eTypeError, "%s is not a class", name);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ rb_define_module_under(outer, name)
|
|||
|
||||
id = rb_intern(name);
|
||||
if (rb_const_defined_at(outer, id)) {
|
||||
module = rb_const_get(outer, id);
|
||||
module = rb_const_get_at(outer, id);
|
||||
if (TYPE(module) == T_MODULE)
|
||||
return module;
|
||||
rb_raise(rb_eTypeError, "%s::%s is not a module",
|
||||
|
|
26
eval.c
26
eval.c
|
@ -2131,7 +2131,7 @@ is_defined(self, node, buf)
|
|||
switch (TYPE(val)) {
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
if (rb_const_defined_at(val, node->nd_mid))
|
||||
if (rb_const_defined_from(val, node->nd_mid))
|
||||
return "constant";
|
||||
break;
|
||||
default:
|
||||
|
@ -2774,14 +2774,14 @@ rb_eval(self, n)
|
|||
break;
|
||||
|
||||
case NODE_YIELD:
|
||||
if (node->nd_stts) {
|
||||
if (node->nd_head) {
|
||||
result = rb_eval(self, node->nd_head);
|
||||
}
|
||||
else {
|
||||
result = Qundef; /* no arg */
|
||||
}
|
||||
SET_CURRENT_SOURCE();
|
||||
result = rb_yield_0(result, 0, 0, Qfalse, Qfalse);
|
||||
result = rb_yield_0(result, 0, 0, Qfalse, node->nd_state);
|
||||
break;
|
||||
|
||||
case NODE_RESCUE:
|
||||
|
@ -3235,16 +3235,23 @@ rb_eval(self, n)
|
|||
VALUE klass;
|
||||
|
||||
klass = rb_eval(self, node->nd_head);
|
||||
if (rb_is_const_id(node->nd_mid)) {
|
||||
switch (TYPE(klass)) {
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
result = rb_const_get(klass, node->nd_mid);
|
||||
result = rb_const_get_from(klass, node->nd_mid);
|
||||
break;
|
||||
default:
|
||||
result = rb_funcall(klass, node->nd_mid, 0, 0);
|
||||
rb_raise(rb_eTypeError, "%s is not a class/module",
|
||||
RSTRING(rb_obj_as_string(klass))->ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = rb_funcall(klass, node->nd_mid, 0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COLON3:
|
||||
|
@ -3506,7 +3513,7 @@ rb_eval(self, n)
|
|||
cbase = class_prefix(self, node->nd_cpath);
|
||||
cname = node->nd_cpath->nd_mid;
|
||||
if (rb_const_defined_at(cbase, cname)) {
|
||||
klass = rb_const_get(cbase, cname);
|
||||
klass = rb_const_get_at(cbase, cname);
|
||||
if (TYPE(klass) != T_CLASS) {
|
||||
rb_raise(rb_eTypeError, "%s is not a class",
|
||||
rb_id2name(cname));
|
||||
|
@ -3549,7 +3556,7 @@ rb_eval(self, n)
|
|||
cbase = class_prefix(self, node->nd_cpath);
|
||||
cname = node->nd_cpath->nd_mid;
|
||||
if (rb_const_defined_at(cbase, cname)) {
|
||||
module = rb_const_get(cbase, cname);
|
||||
module = rb_const_get_at(cbase, cname);
|
||||
if (TYPE(module) != T_MODULE) {
|
||||
rb_raise(rb_eTypeError, "%s is not a module",
|
||||
rb_id2name(cname));
|
||||
|
@ -4014,6 +4021,7 @@ rb_yield_0(val, self, klass, pcall, avalue)
|
|||
volatile VALUE old_wrapper;
|
||||
struct BLOCK * volatile block;
|
||||
struct SCOPE * volatile old_scope;
|
||||
int old_vmode;
|
||||
struct FRAME frame;
|
||||
NODE *cnode = ruby_current_node;
|
||||
int state;
|
||||
|
@ -4035,6 +4043,8 @@ rb_yield_0(val, self, klass, pcall, avalue)
|
|||
ruby_wrapper = block->wrapper;
|
||||
old_scope = ruby_scope;
|
||||
ruby_scope = block->scope;
|
||||
old_vmode = scope_vmode;
|
||||
scope_vmode = block->vmode;
|
||||
ruby_block = block->prev;
|
||||
if (block->flags & BLOCK_D_SCOPE) {
|
||||
/* put place holder for dynamic (in-block) local variables */
|
||||
|
@ -4154,6 +4164,7 @@ rb_yield_0(val, self, klass, pcall, avalue)
|
|||
if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
|
||||
scope_dup(old_scope);
|
||||
ruby_scope = old_scope;
|
||||
scope_vmode = old_vmode;
|
||||
ruby_current_node = cnode;
|
||||
if (state) {
|
||||
if (!block->tag) {
|
||||
|
@ -8117,7 +8128,6 @@ rb_thread_save_context(th)
|
|||
th->wrapper = ruby_wrapper;
|
||||
th->cref = ruby_cref;
|
||||
th->dyna_vars = ruby_dyna_vars;
|
||||
FL_SET(ruby_dyna_vars, DVAR_DONT_RECYCLE);
|
||||
th->block = ruby_block;
|
||||
th->flags &= THREAD_FLAGS_MASK;
|
||||
th->flags |= (rb_trap_immediate<<8) | scope_vmode;
|
||||
|
|
2
file.c
2
file.c
|
@ -2562,7 +2562,6 @@ rb_file_const(name, value)
|
|||
{
|
||||
rb_define_const(rb_mFConst, name, value);
|
||||
rb_define_const(rb_cIO, name, value);
|
||||
rb_define_const(rb_cFile, name, value);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2903,7 +2902,6 @@ Init_File()
|
|||
rb_define_method(rb_cFile, "flock", rb_file_flock, 1);
|
||||
|
||||
rb_mFConst = rb_define_module_under(rb_cFile, "Constants");
|
||||
rb_include_module(rb_cFile, rb_mFConst);
|
||||
rb_file_const("LOCK_SH", INT2FIX(LOCK_SH));
|
||||
rb_file_const("LOCK_EX", INT2FIX(LOCK_EX));
|
||||
rb_file_const("LOCK_UN", INT2FIX(LOCK_UN));
|
||||
|
|
4
intern.h
4
intern.h
|
@ -451,10 +451,12 @@ void *rb_mod_const_of _((VALUE, void*));
|
|||
VALUE rb_const_list _((void*));
|
||||
VALUE rb_mod_constants _((VALUE));
|
||||
VALUE rb_mod_remove_const _((VALUE, VALUE));
|
||||
int rb_const_defined_at _((VALUE, ID));
|
||||
int rb_const_defined _((VALUE, ID));
|
||||
int rb_const_defined_at _((VALUE, ID));
|
||||
int rb_const_defined_from _((VALUE, ID));
|
||||
VALUE rb_const_get _((VALUE, ID));
|
||||
VALUE rb_const_get_at _((VALUE, ID));
|
||||
VALUE rb_const_get_from _((VALUE, ID));
|
||||
void rb_const_set _((VALUE, ID, VALUE));
|
||||
void rb_const_assign _((VALUE, ID, VALUE));
|
||||
VALUE rb_mod_constants _((VALUE));
|
||||
|
|
2
node.h
2
node.h
|
@ -261,7 +261,7 @@ typedef struct RNode {
|
|||
#define NEW_RESBODY(a,ex,n) rb_node_newnode(NODE_RESBODY,n,ex,a)
|
||||
#define NEW_ENSURE(b,en) rb_node_newnode(NODE_ENSURE,b,0,en)
|
||||
#define NEW_RETURN(s) rb_node_newnode(NODE_RETURN,s,0,0)
|
||||
#define NEW_YIELD(a) rb_node_newnode(NODE_YIELD,a,0,0)
|
||||
#define NEW_YIELD(a,s) rb_node_newnode(NODE_YIELD,a,0,s)
|
||||
#define NEW_LIST(a) NEW_ARRAY(a)
|
||||
#define NEW_ARRAY(a) rb_node_newnode(NODE_ARRAY,a,1,0)
|
||||
#define NEW_ZARRAY() rb_node_newnode(NODE_ZARRAY,0,0,0)
|
||||
|
|
51
parse.y
51
parse.y
|
@ -145,6 +145,7 @@ static NODE *arg_blk_pass();
|
|||
static NODE *new_call();
|
||||
static NODE *new_fcall();
|
||||
static NODE *new_super();
|
||||
static NODE *new_yield();
|
||||
|
||||
static NODE *gettable();
|
||||
static NODE *assignable();
|
||||
|
@ -714,7 +715,7 @@ command : operation command_args %prec tLOWEST
|
|||
}
|
||||
| kYIELD command_args
|
||||
{
|
||||
$$ = NEW_YIELD(ret_args($2));
|
||||
$$ = new_yield($2);
|
||||
fixpos($$, $2);
|
||||
}
|
||||
;
|
||||
|
@ -1287,7 +1288,7 @@ call_args2 : arg_value ',' args opt_block_arg
|
|||
}
|
||||
| arg_value ',' args ',' tSTAR arg_value opt_block_arg
|
||||
{
|
||||
$$ = arg_concat(list_concat($1,$3), $6);
|
||||
$$ = arg_concat(list_concat(NEW_LIST($1),$3), $6);
|
||||
$$ = arg_blk_pass($$, $7);
|
||||
}
|
||||
| assocs opt_block_arg
|
||||
|
@ -1454,15 +1455,15 @@ primary : literal
|
|||
}
|
||||
| kYIELD '(' call_args ')'
|
||||
{
|
||||
$$ = NEW_YIELD(ret_args($3));
|
||||
$$ = new_yield($3);
|
||||
}
|
||||
| kYIELD '(' ')'
|
||||
{
|
||||
$$ = NEW_YIELD(0);
|
||||
$$ = NEW_YIELD(0, Qfalse);
|
||||
}
|
||||
| kYIELD
|
||||
{
|
||||
$$ = NEW_YIELD(0);
|
||||
$$ = NEW_YIELD(0, Qfalse);
|
||||
}
|
||||
| kDEFINED opt_nl '(' {in_defined = 1;} expr ')'
|
||||
{
|
||||
|
@ -5366,24 +5367,54 @@ cond_negative(nodep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
no_blockarg(node)
|
||||
NODE *node;
|
||||
{
|
||||
if (node && nd_type(node) == NODE_BLOCK_PASS) {
|
||||
rb_compile_error("block argument should not be given");
|
||||
}
|
||||
}
|
||||
|
||||
static NODE *
|
||||
ret_args(node)
|
||||
NODE *node;
|
||||
{
|
||||
if (node) {
|
||||
if (nd_type(node) == NODE_BLOCK_PASS) {
|
||||
rb_compile_error("block argument should not be given");
|
||||
}
|
||||
no_blockarg(node);
|
||||
if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
|
||||
node = node->nd_head;
|
||||
}
|
||||
}
|
||||
if (node && nd_type(node) == NODE_RESTARY) {
|
||||
if (nd_type(node) == NODE_RESTARY) {
|
||||
nd_set_type(node, NODE_SPLAT);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static NODE *
|
||||
new_yield(node)
|
||||
NODE *node;
|
||||
{
|
||||
long state = Qtrue;
|
||||
|
||||
if (node) {
|
||||
no_blockarg(node);
|
||||
if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
|
||||
node = node->nd_head;
|
||||
state = Qfalse;
|
||||
}
|
||||
if (nd_type(node) == NODE_RESTARY) {
|
||||
nd_set_type(node, NODE_SPLAT);
|
||||
state = Qfalse;
|
||||
}
|
||||
}
|
||||
else {
|
||||
state = Qfalse;
|
||||
}
|
||||
return NEW_YIELD(node, state);
|
||||
}
|
||||
|
||||
static NODE*
|
||||
negate_lit(node)
|
||||
NODE *node;
|
||||
|
|
8
range.c
8
range.c
|
@ -377,13 +377,9 @@ rb_range_beg_len(range, begp, lenp, len, err)
|
|||
if (end > len)
|
||||
end = len;
|
||||
}
|
||||
if (end < 0) {
|
||||
end += len;
|
||||
if (end < 0) {
|
||||
goto out_of_range;
|
||||
}
|
||||
}
|
||||
if (end < 0) end += len;
|
||||
if (!EXCL(range)) end++; /* include end point */
|
||||
if (end < 0) goto out_of_range;
|
||||
len = end - beg;
|
||||
if (len < 0) goto out_of_range;
|
||||
|
||||
|
|
|
@ -125,7 +125,6 @@ def f; yield *[1]; end; f {|a| test_ok(a == 1)}
|
|||
def f; yield *[nil]; end; f {|a| test_ok(a == nil)}
|
||||
def f; yield *[[]]; end; f {|a| test_ok(a == [])}
|
||||
def f; yield *[*[1]]; end; f {|a| test_ok(a == 1)}
|
||||
def f; yield *[*[1,2]]; end; f {|a| test_ok(a == [1,2])}
|
||||
|
||||
def f; yield; end; f {|*a| test_ok(a == [])}
|
||||
def f; yield nil; end; f {|*a| test_ok(a == [nil])}
|
||||
|
|
46
variable.c
46
variable.c
|
@ -1284,10 +1284,11 @@ rb_const_get_at(klass, id)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_const_get(klass, id)
|
||||
static VALUE
|
||||
rb_const_get_0(klass, id, exclude)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
int exclude;
|
||||
{
|
||||
VALUE value, tmp;
|
||||
int mod_retry = 0;
|
||||
|
@ -1295,6 +1296,10 @@ rb_const_get(klass, id)
|
|||
tmp = klass;
|
||||
retry:
|
||||
while (tmp) {
|
||||
if (exclude && tmp == rb_cObject && klass != rb_cObject) {
|
||||
rb_warn("toplevel constant %s referenced by %s::%s",
|
||||
rb_id2name(id), rb_class2name(klass), rb_id2name(id));
|
||||
}
|
||||
while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
|
||||
if (value == Qundef) {
|
||||
rb_autoload_load(tmp, id);
|
||||
|
@ -1315,6 +1320,22 @@ rb_const_get(klass, id)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_const_get_from(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
return rb_const_get_0(klass, id, Qtrue);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_const_get(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
return rb_const_get_0(klass, id, Qfalse);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_remove_const(mod, name)
|
||||
VALUE mod, name;
|
||||
|
@ -1439,6 +1460,27 @@ rb_const_defined_at(klass, id)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
rb_const_defined_from(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
VALUE tmp = klass, value;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp == rb_cObject && klass != rb_cObject) {
|
||||
break;
|
||||
}
|
||||
if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl, id, &value)) {
|
||||
if (value == Qundef && NIL_P(autoload_file(klass, id)))
|
||||
return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
tmp = RCLASS(tmp)->super;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
rb_const_defined(klass, id)
|
||||
VALUE klass;
|
||||
|
|
Loading…
Reference in a new issue