diff --git a/ChangeLog b/ChangeLog index c30682514b..655cd44466 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Thu Aug 31 14:28:39 2000 Yukihiro Matsumoto + + * stable version 1.6.0 released. + +Thu Aug 31 10:11:47 2000 Yukihiro Matsumoto + + * parse.y (stmt): allow stmt_rhs to be right hand side of multiple + assignment. + + * time.c (rb_time_timeval): type error should not mention the word + 'interval'. + +Wed Aug 30 23:21:20 2000 Yukihiro Matsumoto + + * numeric.c (rb_num2long): use rb_Integer() instead of independent + convert routine. + + * eval.c (rb_rescue2): now arbitrary number of exception types can + be specified. + + * object.c (rb_convert_type): use rb_rescue2 now to handle NameError. + + * object.c (rb_convert_type): better error message. + Wed Aug 30 17:09:14 2000 WATANABE Hirofumi * ext/Win32API/Win32API.c (Win32API_initialize): AlphaNT support. diff --git a/ToDo b/ToDo index e56903820f..a453ee3059 100644 --- a/ToDo +++ b/ToDo @@ -62,7 +62,7 @@ Standard Libraries - String#slice, String#slice! - Marshal should handle generic instance variables. - debugger for thread programming -- SyntaxError, NameError, LoadError and NotImplementError are subclasses of +- SyntaxError, NameError, LoadError and NotImplementedError are subclasses of ScriptError..), \G diff --git a/compar.c b/compar.c index b21a83c530..3c5af84ff9 100644 --- a/compar.c +++ b/compar.c @@ -37,7 +37,8 @@ static VALUE cmp_eq2(a) VALUE *a; { - return rb_rescue(cmp_eq, (VALUE)a, cmp_failed, 0); + return rb_rescue2(cmp_eq, (VALUE)a, cmp_failed, 0, + rb_eStandardError, rb_eNameError, 0); } static VALUE @@ -49,7 +50,7 @@ cmp_equal(x, y) if (x == y) return Qtrue; a[0] = x; a[1] = y; - return rb_rescue2(cmp_eq2, (VALUE)a, rb_eScriptError, cmp_failed, 0); + return rb_rescue2(cmp_eq2, (VALUE)a, cmp_failed, 0, rb_eScriptError, 0); } static VALUE diff --git a/eval.c b/eval.c index 0ed7ca3555..12cfd734b8 100644 --- a/eval.c +++ b/eval.c @@ -22,6 +22,14 @@ #include "st.h" #include "dln.h" +#ifdef HAVE_STDARG_PROTOTYPES +#include +#define va_init_list(a,b) va_start(a,b) +#else +#include +#define va_init_list(a,b) va_start(a) +#endif + #ifndef HAVE_STRING_H char *strrchr _((const char*,const char)); #endif @@ -3706,37 +3714,57 @@ handle_rescue(self, node) } VALUE -rb_rescue2(b_proc, data1, eclass, r_proc, data2) +#ifdef HAVE_STDARG_PROTOTYPES +rb_rescue2(VALUE (*b_proc)(), VALUE data1, VALUE (*r_proc)(), VALUE data2, ...) +#else +rb_rescue2(b_proc, data1, r_proc, data2, va_alist) VALUE (*b_proc)(), (*r_proc)(); - VALUE data1, eclass, data2; + VALUE data1, data2; + va_dcl +#endif { int state; volatile VALUE result; volatile VALUE e_info = ruby_errinfo; + va_list args; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { retry_entry: result = (*b_proc)(data1); } - else if (state == TAG_RAISE && rb_obj_is_kind_of(ruby_errinfo, eclass)) { - if (r_proc) { - PUSH_TAG(PROT_NONE); - if ((state = EXEC_TAG()) == 0) { - result = (*r_proc)(data2, ruby_errinfo); + else if (state == TAG_RAISE) { + int handle = Qfalse; + VALUE eclass; + + va_init_list(args, data2); + while (eclass = va_arg(args, VALUE)) { + if (rb_obj_is_kind_of(ruby_errinfo, eclass)) { + handle = Qtrue; + break; } - POP_TAG(); - if (state == TAG_RETRY) { + } + va_end(args); + + if (handle) { + if (r_proc) { + PUSH_TAG(PROT_NONE); + if ((state = EXEC_TAG()) == 0) { + result = (*r_proc)(data2, ruby_errinfo); + } + POP_TAG(); + if (state == TAG_RETRY) { + state = 0; + goto retry_entry; + } + } + else { + result = Qnil; state = 0; - goto retry_entry; } - } - else { - result = Qnil; - state = 0; - } - if (state == 0) { - ruby_errinfo = e_info; + if (state == 0) { + ruby_errinfo = e_info; + } } } POP_TAG(); @@ -3750,7 +3778,7 @@ rb_rescue(b_proc, data1, r_proc, data2) VALUE (*b_proc)(), (*r_proc)(); VALUE data1, data2; { - return rb_rescue2(b_proc, data1, rb_eStandardError, r_proc, data2); + return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, 0); } VALUE diff --git a/numeric.c b/numeric.c index 3c68917be8..5761986ffe 100644 --- a/numeric.c +++ b/numeric.c @@ -70,7 +70,8 @@ do_coerce(x, y) VALUE a[2]; a[0] = *x; a[1] = *y; - ary = rb_rescue2(coerce_body, (VALUE)a, rb_eNameError, coerce_rescue, (VALUE)a); + ary = rb_rescue2(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a, + rb_eStandardError, rb_eNameError, 0); if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { rb_raise(rb_eTypeError, "coerce must return [x, y]"); } @@ -746,22 +747,6 @@ num_truncate(num) return flo_truncate(rb_Float(num)); } -static VALUE -to_integer(val) - VALUE val; -{ - return rb_funcall(val, to_i, 0); -} - -static VALUE -fail_to_integer(val) - VALUE val; -{ - rb_raise(rb_eTypeError, "failed to convert %s into Integer", - rb_class2name(CLASS_OF(val))); - return Qnil; /* dummy */ -} - long rb_num2long(val) VALUE val; @@ -800,10 +785,7 @@ rb_num2long(val) return Qnil; /* not reached */ default: - val = rb_rescue(to_integer, val, fail_to_integer, val); - if (!rb_obj_is_kind_of(val, rb_cInteger)) { - rb_raise(rb_eTypeError, "`to_i' need to return integer"); - } + val = rb_Integer(val); return NUM2LONG(val); } } diff --git a/object.c b/object.c index 73a24c9417..8e1c25b519 100644 --- a/object.c +++ b/object.c @@ -853,8 +853,12 @@ rb_convert_type(val, type, tname, method) arg1.val = arg2.val = val; arg1.s = method; arg2.s = tname; - val = rb_rescue(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2); - Check_Type(val, type); + val = rb_rescue2(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2, + rb_eStandardError, rb_eNameError, 0); + if (TYPE(val) != type) { + rb_raise(rb_eTypeError, "%s#%s should return %s", + rb_class2name(CLASS_OF(arg1.val)), method, tname); + } return val; } @@ -888,9 +892,11 @@ rb_Integer(val) arg1.val = arg2.val = val; arg1.s = "to_i"; arg2.s = "Integer"; - val = rb_rescue(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2); + val = rb_rescue2(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2, + rb_eStandardError, rb_eNameError, 0); if (!rb_obj_is_kind_of(val, rb_cInteger)) { - rb_raise(rb_eTypeError, "to_i should return Integer"); + rb_raise(rb_eTypeError, "%s#to_i should return Integer", + rb_class2name(CLASS_OF(arg1.val))); } return val; } diff --git a/parse.y b/parse.y index 3f0d637eca..a9416a7abf 100644 --- a/parse.y +++ b/parse.y @@ -214,8 +214,8 @@ static void top_local_setup(); * precedence table */ -%nonassoc kDO -%nonassoc kDO2 +/*%nonassoc kDO +%nonassoc kDO2*/ %left kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD kRESCUE_MOD %left kOR kAND %right kNOT @@ -392,6 +392,12 @@ stmt : block_call value_expr($3); $$ = node_assign($1, $3); } + | mlhs '=' stmt_rhs + { + value_expr($3); + $1->nd_value = $3; + $$ = $1; + } | expr expr : mlhs '=' mrhs diff --git a/range.c b/range.c index 5accc14c5d..96f9fd6bb0 100644 --- a/range.c +++ b/range.c @@ -42,7 +42,8 @@ range_init(obj, beg, end, exclude_end) args[0] = beg; args[1] = end; if (!FIXNUM_P(beg) || !FIXNUM_P(end)) { - rb_rescue(range_check, (VALUE)args, range_failed, 0); + rb_rescue2(range_check, (VALUE)args, range_failed, 0, + rb_eStandardError, rb_eNameError, 0); } if (exclude_end) { diff --git a/ruby.h b/ruby.h index 09f2190609..6b65d61632 100644 --- a/ruby.h +++ b/ruby.h @@ -467,7 +467,7 @@ VALUE rb_yield _((VALUE)); int rb_block_given_p _((void)); VALUE rb_iterate _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_rescue _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); -VALUE rb_rescue2 _((VALUE(*)(),VALUE,VALUE,VALUE(*)(),VALUE)); +VALUE rb_rescue2 __((VALUE(*)(),VALUE,VALUE(*)(),VALUE,...)); VALUE rb_ensure _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_catch _((const char*,VALUE(*)(),VALUE)); void rb_throw _((const char*,VALUE)) NORETURN; diff --git a/time.c b/time.c index 3fb535e26c..78863e0535 100644 --- a/time.c +++ b/time.c @@ -105,9 +105,10 @@ rb_time_new(sec, usec) return time_new_internal(rb_cTime, sec, usec); } -struct timeval -rb_time_interval(time) +static struct timeval +time_timeval(time, interval) VALUE time; + int interval; { struct timeval t; @@ -134,13 +135,21 @@ rb_time_interval(time) break; default: - rb_raise(rb_eTypeError, "can't convert %s into Time interval", - rb_class2name(CLASS_OF(time))); + rb_raise(rb_eTypeError, "can't convert %s into Time%s", + rb_class2name(CLASS_OF(time)), + interval ? " interval" : ""); break; } return t; } +struct timeval +rb_time_interval(time) + VALUE time; +{ + return time_timeval(time, Qtrue); +} + struct timeval rb_time_timeval(time) VALUE time; @@ -153,7 +162,7 @@ rb_time_timeval(time) t = tobj->tv; return t; } - return rb_time_interval(time); + return time_timeval(time, Qfalse); } static VALUE