summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog36
-rw-r--r--bignum.c106
-rw-r--r--dir.c3
-rw-r--r--eval.c75
-rw-r--r--gc.c1
-rw-r--r--intern.h3
-rw-r--r--node.h2
-rw-r--r--pack.c59
-rw-r--r--parse.y54
-rw-r--r--re.c1
-rw-r--r--sample/test.rb37
-rw-r--r--variable.c18
12 files changed, 289 insertions, 106 deletions
diff --git a/ChangeLog b/ChangeLog
index 6149a50bf25..8b66569f2b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+Wed Feb 13 17:58:12 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (stmt): local variable declaration order was changed
+ since 1.6
+
+ * parse.y (arg): ditto.
+
+ * pack.c (pack_pack): add templates 'q' and 'Q'.
+
+ * pack.c (pack_unpack): ditto.
+
+ * bignum.c (rb_quad_pack): new utility function.
+
+ * bignum.c (rb_quad_unpack): ditto.
+
+Tue Feb 12 01:21:34 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (assignable): should emit CVASGN within the method
+ body.
+
+Mon Feb 11 06:13:53 2002 Matt Armstrong <matt@lickey.com>
+
+ * dir.c (dir_s_glob): should not warn even if no match found.
+
+Mon Feb 11 04:25:54 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_eval): clean up class variable behavior.
+
+ * eval.c (assign): ditto.
+
+ * eval.c (is_defined): ditto.
+
+ * variable.c (rb_mod_class_variables): need not to call rb_cvar_singleton().
+
+ * variable.c (rb_cvar_singleton): removed.
+
Sun Feb 10 16:52:53 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* ruby.c (load_file): avoid SEGV on '#' only input.
diff --git a/bignum.c b/bignum.c
index 173c8fb968b..c959950e7d4 100644
--- a/bignum.c
+++ b/bignum.c
@@ -185,6 +185,112 @@ rb_int2inum(n)
return rb_int2big(n);
}
+#ifdef HAVE_LONG_LONG
+
+void
+rb_quad_pack(buf, val)
+ char *buf;
+ VALUE val;
+{
+ LONG_LONG q;
+
+ val = rb_to_int(val);
+ if (FIXNUM_P(val)) {
+ q = FIX2LONG(val);
+ }
+ else {
+ long len = RBIGNUM(val)->len;
+ BDIGIT *ds;
+
+ ds = BDIGITS(val);
+ q = 0;
+ while (len--) {
+ q = BIGUP(q);
+ q += ds[len];
+ }
+ }
+ memcpy(buf, (char*)&q, sizeof(LONG_LONG));
+}
+
+VALUE
+rb_quad_unpack(buf, sign)
+ const char *buf;
+ int sign;
+{
+ unsigned LONG_LONG q;
+ long neg = 0;
+ long i = 0;
+ BDIGIT *digits;
+ VALUE big;
+
+ memcpy(&q, buf, sizeof(LONG_LONG));
+ if (sign) {
+ if (FIXABLE((LONG_LONG)q)) return INT2FIX((LONG_LONG)q);
+ if ((LONG_LONG)q < 0) {
+ q = -(LONG_LONG)q;
+ neg = 1;
+ }
+ }
+ else {
+ if (POSFIXABLE(q)) return INT2FIX(q);
+ }
+
+ i = 0;
+ big = bignew(DIGSPERLONGLONG, 1);
+ digits = BDIGITS(big);
+ while (i < DIGSPERLONGLONG) {
+ digits[i++] = BIGLO(q);
+ q = BIGDN(q);
+ }
+
+ i = DIGSPERLONGLONG;
+ while (i-- && !digits[i]) ;
+ RBIGNUM(big)->len = i+1;
+
+ if (neg) {
+ RBIGNUM(big)->sign = 0;
+ }
+ return bignorm(big);
+}
+
+#else
+
+#define QUAD_SIZE 8
+
+void
+rb_quad_pack(buf, val)
+ char *buf;
+ VALUE val;
+{
+ long len;
+
+ memset(buf, 0, QUAD_SIZE);
+ val = rb_to_int(val);
+ if (FIXNUM_P(val)) {
+ val = rb_uint2big(FIX2LONG(val));
+ }
+ len = RBIGNUM(val)->len * sizeof(BDIGIT);
+ if (len > QUAD_SIZE) len = QUAD_SIZE;
+ memcpy(buf, (char*)BDIGITS(val), len);
+}
+
+VALUE
+rb_quad_unpack(buf, sign)
+ const char *buf;
+ int sign;
+{
+ VALUE big = bignew(QUAD_SIZE/sizeof(BDIGIT), 1);
+
+ memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);
+ if (sign && (buf[7] & 0x80)) {
+ RBIGNUM(big)->sign = 0;
+ }
+
+ return bignorm(big);
+}
+
+#endif
+
VALUE
rb_cstr_to_inum(str, base, badcheck)
const char *str;
diff --git a/dir.c b/dir.c
index 4f283fccfc1..13176f4cc56 100644
--- a/dir.c
+++ b/dir.c
@@ -939,9 +939,6 @@ dir_s_glob(dir, str)
if (buf != buffer)
free(buf);
if (ary) {
- if (RARRAY(ary)->len == 0) {
- rb_warning("no matches found: %s", RSTRING(str)->ptr);
- }
return ary;
}
return Qnil;
diff --git a/eval.c b/eval.c
index 18dedb61b35..c53889031e8 100644
--- a/eval.c
+++ b/eval.c
@@ -436,7 +436,7 @@ rb_method_boundp(klass, id, ex)
return Qfalse;
}
-static ID init, eqq, each, aref, aset, match, to_ary, missing;
+static ID init, alloc, eqq, each, aref, aset, match, to_ary, missing;
static ID added, singleton_added;
static ID __id__, __send__;
@@ -1899,24 +1899,19 @@ is_defined(self, node, buf)
break;
case NODE_CVAR:
- if (!ruby_frame || !ruby_frame->last_class ||
- !FL_TEST(ruby_frame->last_class, FL_SINGLETON)) {
- if (NIL_P(ruby_cbase)) {
- if (rb_cvar_defined(CLASS_OF(self), node->nd_vid)) {
- return "class variable";
- }
- break;
+ if (NIL_P(ruby_cbase)) {
+ if (rb_cvar_defined(CLASS_OF(self), node->nd_vid)) {
+ return "class variable";
}
- if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
- if (rb_cvar_defined(ruby_cbase, node->nd_vid)) {
- return "class variable";
- }
- break;
+ break;
+ }
+ if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
+ if (rb_cvar_defined(ruby_cbase, node->nd_vid)) {
+ return "class variable";
}
+ break;
}
- /* fall through */
- case NODE_CVAR2:
- if (rb_cvar_defined(rb_cvar_singleton(self), node->nd_vid)) {
+ if (rb_cvar_defined(rb_iv_get(ruby_cbase, "__attached__"), node->nd_vid)) {
return "class variable";
}
break;
@@ -2866,17 +2861,15 @@ rb_eval(self, n)
rb_raise(rb_eTypeError, "no class/module to define class variable");
}
result = rb_eval(self, node->nd_value);
- if (FL_TEST(ruby_cbase, FL_SINGLETON)) {
- rb_cvar_declare(rb_cvar_singleton(rb_iv_get(ruby_cbase, "__attached__")),
- node->nd_vid, result);
- break;
+ if (ruby_verbose && FL_TEST(ruby_cbase, FL_SINGLETON)) {
+ rb_warn("declaring singleton class variable");
}
rb_cvar_declare(ruby_cbase, node->nd_vid, result);
break;
case NODE_CVASGN:
result = rb_eval(self, node->nd_value);
- rb_cvar_set(rb_cvar_singleton(self), node->nd_vid, result);
+ rb_cvar_set(ruby_cbase, node->nd_vid, result);
break;
case NODE_LVAR:
@@ -2902,22 +2895,16 @@ rb_eval(self, n)
result = ev_const_get(RNODE(ruby_frame->cbase), node->nd_vid, self);
break;
- case NODE_CVAR: /* normal method */
- if (!ruby_frame || !ruby_frame->last_class ||
- !FL_TEST(ruby_frame->last_class, FL_SINGLETON)) {
- /* non singleton method */
- if (NIL_P(ruby_cbase)) {
- result = rb_cvar_get(CLASS_OF(self), node->nd_vid);
- break;
- }
- if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
- result = rb_cvar_get(ruby_cbase, node->nd_vid);
- break;
- }
+ case NODE_CVAR:
+ if (NIL_P(ruby_cbase)) {
+ result = rb_cvar_get(CLASS_OF(self), node->nd_vid);
+ break;
}
- /* fall through */
- case NODE_CVAR2: /* singleton method */
- result = rb_cvar_get(rb_cvar_singleton(self), node->nd_vid);
+ if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
+ result = rb_cvar_get(ruby_cbase, node->nd_vid);
+ break;
+ }
+ result = rb_cvar_get(rb_iv_get(ruby_cbase, "__attached__"), node->nd_vid);
break;
case NODE_BLOCK_ARG:
@@ -3103,6 +3090,9 @@ rb_eval(self, n)
if (NIL_P(ruby_class)) {
rb_raise(rb_eTypeError, "no class/module to add method");
}
+ if (ruby_class == rb_cClass && node->nd_mid == alloc) {
+ rb_raise(rb_eNameError, "redefining Class#allocate will cause infinite loop");
+ }
if (ruby_class == rb_cObject && node->nd_mid == init) {
rb_warn("redefining Object#initialize may cause infinite loop");
}
@@ -3922,14 +3912,14 @@ assign(self, lhs, val, pcall)
break;
case NODE_CVDECL:
- if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
- rb_cvar_declare(ruby_cbase, lhs->nd_vid, val);
- break;
+ if (ruby_verbose && FL_TEST(ruby_cbase, FL_SINGLETON)) {
+ rb_warn("declaring singleton class variable");
}
- self = rb_iv_get(ruby_cbase, "__attached__");
- /* fall through */
+ rb_cvar_declare(ruby_cbase, lhs->nd_vid, val);
+ break;
+
case NODE_CVASGN:
- rb_cvar_set(rb_cvar_singleton(self), lhs->nd_vid, val);
+ rb_cvar_set(ruby_cbase, lhs->nd_vid, val);
break;
case NODE_MASGN:
@@ -6021,6 +6011,7 @@ void
Init_eval()
{
init = rb_intern("initialize");
+ alloc = rb_intern("allocate");
eqq = rb_intern("===");
each = rb_intern("each");
diff --git a/gc.c b/gc.c
index 89085de9212..90e9e5d8144 100644
--- a/gc.c
+++ b/gc.c
@@ -700,7 +700,6 @@ rb_gc_mark_children(ptr)
case NODE_DVAR:
case NODE_IVAR:
case NODE_CVAR:
- case NODE_CVAR2:
case NODE_NTH_REF:
case NODE_BACK_REF:
case NODE_ALIAS:
diff --git a/intern.h b/intern.h
index d41086dfd0b..b5d08145276 100644
--- a/intern.h
+++ b/intern.h
@@ -70,6 +70,8 @@ long rb_big2long _((VALUE));
#define rb_big2int(x) rb_big2long(x)
unsigned long rb_big2ulong _((VALUE));
#define rb_big2uint(x) rb_big2ulong(x)
+void rb_quad_pack _((char*,VALUE));
+VALUE rb_quad_unpack _((const char*,int));
VALUE rb_dbl2big _((double));
double rb_big2dbl _((VALUE));
VALUE rb_big_plus _((VALUE, VALUE));
@@ -424,7 +426,6 @@ void rb_cvar_declare _((VALUE, ID, VALUE));
VALUE rb_cvar_defined _((VALUE, ID));
void rb_cvar_set _((VALUE, ID, VALUE));
VALUE rb_cvar_get _((VALUE, ID));
-VALUE rb_cvar_singleton _((VALUE));
void rb_cv_set _((VALUE, const char *, VALUE));
VALUE rb_cv_get _((VALUE, const char *));
void rb_define_class_variable _((VALUE, const char *, VALUE));
diff --git a/node.h b/node.h
index d39a5a9a933..b7c9daec516 100644
--- a/node.h
+++ b/node.h
@@ -71,7 +71,6 @@ enum node_type {
NODE_IVAR,
NODE_CONST,
NODE_CVAR,
- NODE_CVAR2,
NODE_NTH_REF,
NODE_BACK_REF,
NODE_MATCH,
@@ -285,7 +284,6 @@ typedef struct RNode {
#define NEW_IVAR(v) rb_node_newnode(NODE_IVAR,v,0,0)
#define NEW_CONST(v) rb_node_newnode(NODE_CONST,v,0,0)
#define NEW_CVAR(v) rb_node_newnode(NODE_CVAR,v,0,0)
-#define NEW_CVAR2(v) rb_node_newnode(NODE_CVAR2,v,0,0)
#define NEW_NTH_REF(n) rb_node_newnode(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_BACK_REF(n) rb_node_newnode(NODE_BACK_REF,0,n,local_cnt('~'))
#define NEW_MATCH(c) rb_node_newnode(NODE_MATCH,c,0,0)
diff --git a/pack.c b/pack.c
index 242a0c70411..316becea40a 100644
--- a/pack.c
+++ b/pack.c
@@ -316,6 +316,11 @@ typedef unsigned int U32;
#define NUM2U32(x) NUM2UINT(x)
#endif
+#ifdef HAVE_LONG_LONG
+# define QUAD_SIZE sizeof(LONG_LONG)
+#else
+# define QUAD_SIZE 8
+#endif
static char *toofew = "too few arguments";
static void encodes _((VALUE,char*,int,int));
@@ -594,6 +599,18 @@ pack_pack(ary, fmt)
}
break;
+ case 'q':
+ case 'Q':
+ while (len-- > 0) {
+ char tmp[QUAD_SIZE];
+
+ from = NEXTFROM;
+ if (NIL_P(from)) from = INT2FIX(0);
+ rb_quad_pack(tmp, from);
+ rb_str_buf_cat(res, (char*)&tmp, QUAD_SIZE);
+ }
+ break;
+
case 'n':
while (len-- > 0) {
unsigned short s;
@@ -1007,26 +1024,24 @@ hex2num(c)
}
}
-#ifdef NATINT_PACK
-#define PACK_LENGTH_ADJUST(type,sz) do { \
- int t__len = NATINT_LEN(type,(sz)); \
+#define PACK_LENGTH_ADJUST_SIZE(sz) do { \
tmp = 0; \
- if (len > (send-s)/t__len) { \
+ if (len > (send-s)/sz) { \
if (!star) { \
- tmp = len-(send-s)/t__len; \
+ tmp = len-(send-s)/sz; \
} \
- len = (send-s)/t__len; \
+ len = (send-s)/sz; \
} \
} while (0)
+
+#ifdef NATINT_PACK
+#define PACK_LENGTH_ADJUST(type,sz) do { \
+ int t__len = NATINT_LEN(type,(sz)); \
+ PACK_LENGTH_ADJUST_SIZE(t__len); \
+} while (0)
#else
#define PACK_LENGTH_ADJUST(type,sz) do { \
- tmp = 0; \
- if (len > (send-s)/sizeof(type)) { \
- if (!star) { \
- tmp = len - (send-s)/sizeof(type); \
- } \
- len = (send-s)/sizeof(type); \
- } \
+ PACK_LENGTH_ADJUST_SIZE(sizeof(type)); \
} while (0)
#endif
@@ -1294,6 +1309,24 @@ pack_unpack(str, fmt)
PACK_ITEM_ADJUST();
break;
+ case 'q':
+ PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
+ while (len-- > 0) {
+ char *tmp = (char*)s;
+ s += QUAD_SIZE;
+ rb_ary_push(ary, rb_quad_unpack(tmp, 1));
+ }
+ PACK_ITEM_ADJUST();
+ break;
+ case 'Q':
+ PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
+ while (len-- > 0) {
+ char *tmp = (char*)s;
+ s += QUAD_SIZE;
+ rb_ary_push(ary, rb_quad_unpack(tmp, 0));
+ }
+ break;
+
case 'n':
PACK_LENGTH_ADJUST(unsigned short,2);
while (len-- > 0) {
diff --git a/parse.y b/parse.y
index 0081e9fa814..da2a093e99f 100644
--- a/parse.y
+++ b/parse.y
@@ -215,7 +215,7 @@ static void top_local_setup();
%type <node> compstmt stmts stmt expr arg primary command command_call method_call
%type <node> if_tail opt_else case_body cases rescue exc_list exc_var ensure
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
-%type <node> command_args aref_args opt_block_arg block_arg var_ref
+%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> mrhs mrhs_basic superclass block_call block_command
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
%type <node> assoc_list assocs assoc undef_list backref
@@ -425,24 +425,24 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
$1->nd_value = $3;
$$ = $1;
}
- | variable tOP_ASGN command_call
+ | var_lhs tOP_ASGN command_call
{
- NODE *n = assignable($1, 0);
- if (n) {
+ ID vid = $1->nd_vid;
+ if ($1) {
if ($2 == tOROP) {
- n->nd_value = $3;
- $$ = NEW_OP_ASGN_OR(gettable($1), n);
- if (is_instance_id($1)) {
- $$->nd_aid = $1;
+ $1->nd_value = $3;
+ $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
+ if (is_instance_id(vid)) {
+ $$->nd_aid = vid;
}
}
else if ($2 == tANDOP) {
- n->nd_value = $3;
- $$ = NEW_OP_ASGN_AND(gettable($1), n);
+ $1->nd_value = $3;
+ $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
}
else {
- $$ = n;
- $$->nd_value = call_op(gettable($1),$2,1,$3);
+ $$ = $1;
+ $$->nd_value = call_op(gettable(vid),$2,1,$3);
}
fixpos($$, $3);
}
@@ -770,24 +770,24 @@ arg : lhs '=' arg
value_expr($3);
$$ = node_assign($1, $3);
}
- | variable tOP_ASGN arg
+ | var_lhs tOP_ASGN arg
{
- NODE *n = assignable($1, 0);
- if (n) {
+ ID vid = $1->nd_vid;
+ if ($1) {
if ($2 == tOROP) {
- n->nd_value = $3;
- $$ = NEW_OP_ASGN_OR(gettable($1), n);
- if (is_instance_id($1)) {
- $$->nd_aid = $1;
+ $1->nd_value = $3;
+ $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
+ if (is_instance_id(vid)) {
+ $$->nd_aid = vid;
}
}
else if ($2 == tANDOP) {
- n->nd_value = $3;
- $$ = NEW_OP_ASGN_AND(gettable($1), n);
+ $1->nd_value = $3;
+ $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
}
else {
- $$ = n;
- $$->nd_value = call_op(gettable($1),$2,1,$3);
+ $$ = $1;
+ $$->nd_value = call_op(gettable(vid),$2,1,$3);
}
fixpos($$, $3);
}
@@ -1798,6 +1798,11 @@ var_ref : variable
$$ = gettable($1);
}
+var_lhs : variable
+ {
+ $$ = assignable($1);
+ }
+
backref : tNTH_REF
| tBACK_REF
@@ -4322,7 +4327,6 @@ gettable(id)
return NEW_CONST(id);
}
else if (is_class_id(id)) {
- if (in_single) return NEW_CVAR2(id);
return NEW_CVAR(id);
}
rb_compile_error("identifier %s is not valid", rb_id2name(id));
@@ -4380,7 +4384,7 @@ assignable(id, val)
return NEW_CDECL(id, val);
}
else if (is_class_id(id)) {
- if (in_single) return NEW_CVASGN(id, val);
+ if (in_def || in_single) return NEW_CVASGN(id, val);
return NEW_CVDECL(id, val);
}
else {
diff --git a/re.c b/re.c
index d587cdbb5c0..5e73ddbd8b6 100644
--- a/re.c
+++ b/re.c
@@ -629,7 +629,6 @@ rb_reg_search(re, str, pos, reverse)
else {
range = RSTRING(str)->len - pos;
}
- regs.allocated = 0;
result = re_search(RREGEXP(re)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,
pos, range, &regs);
diff --git a/sample/test.rb b/sample/test.rb
index fc2eb5ae0f9..d3773fe6887 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -1288,6 +1288,43 @@ foobar = "foobar"
$_ = foobar
test_ok($_ == foobar)
+class Gods
+ @@rule = "Uranus"
+ def ruler0
+ @@rule
+ end
+
+ def self.ruler1 # <= per method definition style
+ @@rule
+ end
+ class << self # <= multiple method definition style
+ def ruler2
+ @@rule
+ end
+ end
+end
+
+module Olympians
+ @@rule ="Zeus"
+ def ruler3
+ @@rule
+ end
+end
+
+class Titans < Gods
+ @@rule = "Cronus"
+ include Olympians # OK to cause warning (intentional)
+end
+
+test_ok(Gods.new.ruler0 == "Cronus")
+test_ok(Gods.ruler1 == "Cronus")
+test_ok(Gods.ruler2 == "Cronus")
+test_ok(Titans.ruler1 == "Cronus")
+test_ok(Titans.ruler2 == "Cronus")
+atlas = Titans.new
+test_ok(atlas.ruler0 == "Cronus")
+test_ok(atlas.ruler3 == "Zeus")
+
test_check "trace"
$x = 1234
$y = 0
diff --git a/variable.c b/variable.c
index 1c7a2601e07..656497e7424 100644
--- a/variable.c
+++ b/variable.c
@@ -1411,20 +1411,6 @@ rb_define_global_const(name, val)
rb_define_const(rb_cObject, name, val);
}
-VALUE
-rb_cvar_singleton(obj)
- VALUE obj;
-{
- switch (TYPE(obj)) {
- case T_MODULE:
- case T_CLASS:
- return obj;
- default:
- break;
- }
- return CLASS_OF(obj);
-}
-
static VALUE
original_module(c)
VALUE c;
@@ -1613,10 +1599,6 @@ rb_mod_class_variables(obj)
{
VALUE ary = rb_ary_new();
- if (FL_TEST(obj, FL_SINGLETON)) {
- obj = rb_cvar_singleton(rb_iv_get(obj, "__attached__"));
- }
-
for (;;) {
if (RCLASS(obj)->iv_tbl) {
st_foreach(RCLASS(obj)->iv_tbl, cv_i, ary);