summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-18 14:13:41 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-18 14:13:41 +0000
commit8232622071b61db04cd6f0e3a32b7608360e6b25 (patch)
tree3f083733e7251ac5ca51861fa7a2c6e9f2236a88 /parse.y
parent6dfb5aa6ac5c9432ad7a7b8bebda4916004051b6 (diff)
* parse.y (value_expr0): allow return/break/next/redo/retry in rhs
of logical operator. [ruby-dev:18534] * parse.y (remove_begin): eliminate useless NODE_BEGIN. [ruby-dev:18535] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2971 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y35
1 files changed, 30 insertions, 5 deletions
diff --git a/parse.y b/parse.y
index b9ca1fa96c..9d057aa66a 100644
--- a/parse.y
+++ b/parse.y
@@ -119,9 +119,12 @@ static NODE *logop();
static NODE *newline_node();
static void fixpos();
-static int value_expr();
-static void void_expr();
+static int value_expr0();
+static void void_expr0();
static void void_stmts();
+static NODE *remove_begin();
+#define value_expr(node) value_expr0((node) = remove_begin(node))
+#define void_expr(node) void_expr0((node) = remove_begin(node))
static NODE *block_append();
static NODE *list_append();
@@ -4697,9 +4700,11 @@ node_assign(lhs, rhs)
}
static int
-value_expr(node)
+value_expr0(node)
NODE *node;
{
+ int cond = 0;
+
while (node) {
switch (nd_type(node)) {
case NODE_CLASS:
@@ -4714,7 +4719,7 @@ value_expr(node)
case NODE_NEXT:
case NODE_REDO:
case NODE_RETRY:
- yyerror("void value expression");
+ if (!cond) yyerror("void value expression");
/* or "control never reach"? */
return Qfalse;
@@ -4736,6 +4741,7 @@ value_expr(node)
case NODE_AND:
case NODE_OR:
+ cond = 1;
node = node->nd_2nd;
break;
@@ -4752,7 +4758,7 @@ value_expr(node)
}
static void
-void_expr(node)
+void_expr0(node)
NODE *node;
{
char *useless = 0;
@@ -4862,6 +4868,25 @@ void_stmts(node)
}
}
+static NODE *
+remove_begin(node)
+ NODE *node;
+{
+ NODE **n = &node;
+ while (*n) {
+ switch (nd_type(*n)) {
+ case NODE_NEWLINE:
+ n = &(*n)->nd_next;
+ continue;
+ case NODE_BEGIN:
+ *n = (*n)->nd_body;
+ default:
+ return node;
+ }
+ }
+ return node;
+}
+
static int
assign_in_cond(node)
NODE *node;