summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-04-25 08:54:52 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-04-25 08:54:52 +0000
commitd47be3973548e80112955be57a3e256331235ac9 (patch)
treedd10757dfab43c0bb1638e059bdac032dba8854c
parentaaebe679198ee8e701e8036d19c497f232a5c566 (diff)
* eval.c (proc_invoke): Proc#yield should pass through retry and
break like keyword yield. [ruby-talk:70034] * eval.c (proc_invoke): orphan Proc now raises LocalJumpError for break and retry again. * eval.c (rb_eval): ARGSCAT should splat the argument. * eval.c (splat_value): splat operation function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3729 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog20
-rw-r--r--eval.c102
2 files changed, 75 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index ee77d16103..af518c6d95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,20 @@
-2003-04-24 Dave Thomas <dave@thomases.com>
+Fri Apr 25 02:03:25 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (proc_invoke): Proc#yield should pass through retry and
+ break like keyword yield. [ruby-talk:70034]
+
+ * eval.c (proc_invoke): orphan Proc now raises LocalJumpError for
+ break and retry again.
+
+ * eval.c (rb_eval): ARGSCAT should splat the argument.
+
+ * eval.c (splat_value): splat operation function.
+
+Thu Apr 24 23:37:02 2003 Dave Thomas <dave@thomases.com>
* lib/matrix.rb (Matrix#minor): Used Range#size, which no longer
exists.
-2003-04-24 Dave Thomas <dave@thomases.com>
-
* lib/complex.rb (new!): Complex.new had been made private, but
Kernel#Complex called it. Re-exposed as new!.
@@ -21190,3 +21200,7 @@ Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1 alpha0 released.
+
+Local variables:
+add-log-time-format: current-time-string
+end:
diff --git a/eval.c b/eval.c
index f53a1a7b6a..9ce0f1c49f 100644
--- a/eval.c
+++ b/eval.c
@@ -2245,19 +2245,6 @@ svalue_to_avalue(v)
}
static VALUE
-avalue_splat(v)
- VALUE v;
-{
- if (RARRAY(v)->len == 0) {
- return Qundef;
- }
- if (RARRAY(v)->len == 1) {
- return RARRAY(v)->ptr[0];
- }
- return v;
-}
-
-static VALUE
svalue_to_mrhs(v, lhs)
VALUE v;
NODE *lhs;
@@ -2277,6 +2264,45 @@ svalue_to_mrhs(v, lhs)
}
static VALUE
+avalue_splat(v)
+ VALUE v;
+{
+ if (RARRAY(v)->len == 0) {
+ return Qundef;
+ }
+ if (RARRAY(v)->len == 1) {
+ return RARRAY(v)->ptr[0];
+ }
+ return v;
+}
+
+static VALUE
+splat_value(v)
+ VALUE v;
+{
+ if (NIL_P(v)) return rb_ary_new3(1, Qnil);
+#if 1
+ /* hack to avoid invoke Object#to_a */
+ if (TYPE(v) != T_ARRAY) {
+ VALUE tmp = rb_check_array_type(v);
+ if (NIL_P(tmp)) {
+ VALUE origin;
+ ID id = rb_intern("to_a");
+
+ if (search_method(CLASS_OF(v), id, &origin) &&
+ origin != RCLASS(rb_cObject)->super) { /* exclude Object#to_a */
+ return rb_funcall(v, id, 0);
+ }
+ else {
+ return rb_ary_new3(1, v);
+ }
+ }
+ }
+#endif
+ return avalue_splat(rb_Array(v));
+}
+
+static VALUE
class_prefix(self, cpath)
VALUE self;
NODE *cpath;
@@ -2660,31 +2686,7 @@ rb_eval(self, n)
break;
case NODE_SPLAT:
-#if 0
- /* simplified version after Object#to_a removed */
- result = rb_eval(self, node->nd_head);
- if (NIL_P(result)) result = rb_ary_new3(1, Qnil);
- result = avalue_splat(rb_Array(result));
-#else
- result = rb_eval(self, node->nd_head);
- if (NIL_P(result)) result = rb_ary_new3(1, Qnil);
- if (TYPE(result) != T_ARRAY) {
- VALUE tmp = rb_check_array_type(result);
- if (NIL_P(tmp)) {
- VALUE origin;
- ID id = rb_intern("to_a");
-
- if (search_method(CLASS_OF(result), id, &origin) &&
- origin != RCLASS(rb_cObject)->super) { /* exclude Object#to_a */
- result = rb_funcall(result, id, 0);
- }
- else {
- result = rb_ary_new3(1, result);
- }
- }
- }
- result = avalue_splat(rb_Array(result));
-#endif
+ result = splat_value(rb_eval(self, node->nd_head));
break;
case NODE_SVALUE:
@@ -2845,7 +2847,7 @@ rb_eval(self, n)
case NODE_ARGSCAT:
result = rb_ary_concat(rb_eval(self, node->nd_head),
- rb_eval(self, node->nd_body));
+ splat_value(rb_eval(self, node->nd_body)));
break;
case NODE_ARGSPUSH:
@@ -6736,7 +6738,7 @@ proc_invoke(proc, args, pcall, self)
struct BLOCK _block;
struct BLOCK *data;
volatile VALUE result = Qnil;
- int state;
+ int state, incoming_state;
volatile int orphan;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
@@ -6770,6 +6772,7 @@ proc_invoke(proc, args, pcall, self)
POP_TAG();
POP_ITER();
+ incoming_state = state;
if (ruby_block->tag->dst == state) {
state &= TAG_MASK;
}
@@ -6781,11 +6784,22 @@ proc_invoke(proc, args, pcall, self)
switch (state) {
case 0:
break;
- case TAG_BREAK:
- result = prot_tag->retval;
- break;
case TAG_RETRY:
- localjump_error("retry from proc-closure", Qnil);
+ if (pcall || orphan) {
+ localjump_error("retry from proc-closure", Qnil);
+ }
+ /* fall through */
+ case TAG_BREAK:
+ if (pcall) {
+ result = prot_tag->retval;
+ }
+ else if (orphan) {
+ localjump_error("break from proc-closure", prot_tag->retval);
+ }
+ else {
+ ruby_block->tag->dst = incoming_state;
+ JUMP_TAG(incoming_state);
+ }
break;
case TAG_RETURN:
if (orphan) { /* orphan procedure */