зеркало из https://github.com/github/ruby.git
[Bug #20094] Distinguish `begin` and parentheses
This commit is contained in:
Родитель
15c280639e
Коммит
bc002971b6
|
@ -7097,6 +7097,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
|
||||||
case NODE_COLON2:
|
case NODE_COLON2:
|
||||||
case NODE_COLON3:
|
case NODE_COLON3:
|
||||||
case NODE_BEGIN:
|
case NODE_BEGIN:
|
||||||
|
case NODE_BLOCK:
|
||||||
CHECK(COMPILE(ret, "case in literal", node)); // (1)
|
CHECK(COMPILE(ret, "case in literal", node)); // (1)
|
||||||
if (in_single_pattern) {
|
if (in_single_pattern) {
|
||||||
ADD_INSN1(ret, line_node, dupn, INT2FIX(2));
|
ADD_INSN1(ret, line_node, dupn, INT2FIX(2));
|
||||||
|
|
36
parse.y
36
parse.y
|
@ -1188,7 +1188,6 @@ static void fixpos(NODE*,NODE*);
|
||||||
static int value_expr_gen(struct parser_params*,NODE*);
|
static int value_expr_gen(struct parser_params*,NODE*);
|
||||||
static void void_expr(struct parser_params*,NODE*);
|
static void void_expr(struct parser_params*,NODE*);
|
||||||
static NODE *remove_begin(NODE*);
|
static NODE *remove_begin(NODE*);
|
||||||
static NODE *remove_begin_all(NODE*);
|
|
||||||
#define value_expr(node) value_expr_gen(p, (node))
|
#define value_expr(node) value_expr_gen(p, (node))
|
||||||
static NODE *void_stmts(struct parser_params*,NODE*);
|
static NODE *void_stmts(struct parser_params*,NODE*);
|
||||||
static void reduce_nodes(struct parser_params*,NODE**);
|
static void reduce_nodes(struct parser_params*,NODE**);
|
||||||
|
@ -3898,7 +3897,7 @@ primary : literal
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0;
|
if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0;
|
||||||
$$ = NEW_BEGIN($2, &@$);
|
$$ = NEW_BLOCK($2, &@$);
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: paren!($2) %*/
|
/*% ripper: paren!($2) %*/
|
||||||
}
|
}
|
||||||
|
@ -5561,7 +5560,7 @@ p_var_ref : '^' tIDENTIFIER
|
||||||
p_expr_ref : '^' tLPAREN expr_value rparen
|
p_expr_ref : '^' tLPAREN expr_value rparen
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
$$ = NEW_BEGIN($3, &@$);
|
$$ = NEW_BLOCK($3, &@$);
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: begin!($3) %*/
|
/*% ripper: begin!($3) %*/
|
||||||
}
|
}
|
||||||
|
@ -12881,7 +12880,19 @@ kwd_append(rb_node_kw_arg_t *kwlist, rb_node_kw_arg_t *kw)
|
||||||
static NODE *
|
static NODE *
|
||||||
new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
|
new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
return NEW_DEFINED(remove_begin_all(expr), loc);
|
NODE *n = expr;
|
||||||
|
while (n) {
|
||||||
|
if (nd_type_p(n, NODE_BEGIN)) {
|
||||||
|
n = RNODE_BEGIN(n)->nd_body;
|
||||||
|
}
|
||||||
|
else if (nd_type_p(n, NODE_BLOCK) && RNODE_BLOCK(n)->nd_end == n) {
|
||||||
|
n = RNODE_BLOCK(n)->nd_head;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NEW_DEFINED(n, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
|
@ -14021,16 +14032,6 @@ remove_begin(NODE *node)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE *
|
|
||||||
remove_begin_all(NODE *node)
|
|
||||||
{
|
|
||||||
NODE **n = &node, *n1 = node;
|
|
||||||
while (n1 && nd_type_p(n1, NODE_BEGIN)) {
|
|
||||||
*n = n1 = RNODE_BEGIN(n1)->nd_body;
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reduce_nodes(struct parser_params *p, NODE **body)
|
reduce_nodes(struct parser_params *p, NODE **body)
|
||||||
{
|
{
|
||||||
|
@ -14200,7 +14201,12 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l
|
||||||
return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
|
return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
|
||||||
|
|
||||||
case NODE_BLOCK:
|
case NODE_BLOCK:
|
||||||
RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head = cond0(p, RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head, type, loc, false);
|
{
|
||||||
|
NODE *end = RNODE_BLOCK(node)->nd_end;
|
||||||
|
NODE **expr = &RNODE_BLOCK(end)->nd_head;
|
||||||
|
if (top) top = node == end;
|
||||||
|
*expr = cond0(p, *expr, type, loc, top);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_AND:
|
case NODE_AND:
|
||||||
|
|
|
@ -73,6 +73,24 @@ class TestWhileuntil < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_begin_while
|
||||||
|
i = 0
|
||||||
|
sum = 0
|
||||||
|
begin
|
||||||
|
i += 1
|
||||||
|
sum += i
|
||||||
|
end while i < 10
|
||||||
|
assert_equal([10, 55], [i, sum])
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
sum = 0
|
||||||
|
(
|
||||||
|
i += 1
|
||||||
|
sum += i
|
||||||
|
) while false
|
||||||
|
assert_equal([0, 0], [i, sum])
|
||||||
|
end
|
||||||
|
|
||||||
def test_until
|
def test_until
|
||||||
i = 0
|
i = 0
|
||||||
until i>4
|
until i>4
|
||||||
|
|
Загрузка…
Ссылка в новой задаче