summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-18 14:40:57 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-10-18 14:40:57 +0000
commit74be32bc2ccd17f97986f30cc14c5b76b66c9393 (patch)
tree9cc2cc232394dd226d5119e02ef517a10585cfd9 /parse.y
parentafae6e33dea2c95f16aa4797780b9461ba1254ff (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/branches/ruby_1_6@2972 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y105
1 files changed, 68 insertions, 37 deletions
diff --git a/parse.y b/parse.y
index 7670c26119..2f8f8e62f1 100644
--- a/parse.y
+++ b/parse.y
@@ -97,9 +97,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();
@@ -4537,53 +4540,62 @@ node_assign(lhs, rhs)
}
static int
-value_expr(node)
+value_expr0(node)
NODE *node;
{
- if (node == 0) return Qtrue;
+ int cond = 0;
- switch (nd_type(node)) {
- case NODE_RETURN:
- case NODE_BREAK:
- case NODE_NEXT:
- case NODE_REDO:
- case NODE_RETRY:
- case NODE_WHILE:
- case NODE_UNTIL:
- case NODE_CLASS:
- case NODE_MODULE:
- case NODE_DEFN:
- case NODE_DEFS:
- yyerror("void value expression");
- return Qfalse;
- break;
-
- case NODE_BLOCK:
- while (node->nd_next) {
- node = node->nd_next;
- }
- return value_expr(node->nd_head);
+ while (node) {
+ switch (nd_type(node)) {
+ case NODE_RETURN:
+ case NODE_BREAK:
+ case NODE_NEXT:
+ case NODE_REDO:
+ case NODE_RETRY:
+ case NODE_WHILE:
+ case NODE_UNTIL:
+ case NODE_CLASS:
+ case NODE_MODULE:
+ case NODE_DEFN:
+ case NODE_DEFS:
+ if (!cond) yyerror("void value expression");
+ return Qfalse;
+
+ case NODE_BLOCK:
+ while (node->nd_next) {
+ node = node->nd_next;
+ }
+ node = node->nd_head;
+ break;
- case NODE_BEGIN:
- return value_expr(node->nd_body);
+ case NODE_BEGIN:
+ node = node->nd_body;
+ break;
- case NODE_IF:
- return value_expr(node->nd_body) && value_expr(node->nd_else);
+ case NODE_IF:
+ if (!value_expr(node->nd_body)) return Qfalse;
+ node = node->nd_else;
+ break;
- case NODE_AND:
- case NODE_OR:
- return value_expr(node->nd_2nd);
+ case NODE_AND:
+ case NODE_OR:
+ cond = 1;
+ node = node->nd_2nd;
+ break;
- case NODE_NEWLINE:
- return value_expr(node->nd_next);
+ case NODE_NEWLINE:
+ node = node->nd_next;
+ break;
- default:
- return Qtrue;
+ default:
+ return Qtrue;
+ }
}
+ return Qtrue;
}
static void
-void_expr(node)
+void_expr0(node)
NODE *node;
{
char *useless = 0;
@@ -4696,6 +4708,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;