[ruby/yarp] More flip flop flags

Whenever you see a `not` or a `!`, the receiver of that method should
potentially be marked as a flip-flop.

https://github.com/ruby/yarp/commit/ba5977a40a
This commit is contained in:
Kevin Newton 2023-08-10 14:16:56 -04:00 committed by Takashi Kokubun
parent fb287fa425
commit bf723b21cc
Notes: git 2023-08-17 00:47:59 +00:00
6 changed files with 101 additions and 6 deletions

View File

@ -31,3 +31,7 @@ foo
) )
not foo .. bar
not (foo .. bar)

View File

@ -1,6 +1,6 @@
ProgramNode(0...156)( ProgramNode(0...190)(
[], [],
StatementsNode(0...156)( StatementsNode(0...190)(
[AndNode(0...19)( [AndNode(0...19)(
CallNode(0...7)( CallNode(0...7)(
CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "foo"), CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "foo"),
@ -188,6 +188,84 @@ ProgramNode(0...156)(
nil, nil,
0, 0,
"!" "!"
),
CallNode(158...172)(
RangeNode(162...172)(
CallNode(162...165)(
nil,
nil,
(162...165),
nil,
nil,
nil,
nil,
2,
"foo"
),
CallNode(169...172)(
nil,
nil,
(169...172),
nil,
nil,
nil,
nil,
2,
"bar"
),
(166...168),
2
),
nil,
(158...161),
nil,
nil,
nil,
nil,
0,
"!"
),
CallNode(174...190)(
ParenthesesNode(178...190)(
StatementsNode(179...189)(
[RangeNode(179...189)(
CallNode(179...182)(
nil,
nil,
(179...182),
nil,
nil,
nil,
nil,
2,
"foo"
),
CallNode(186...189)(
nil,
nil,
(186...189),
nil,
nil,
nil,
nil,
2,
"bar"
),
(183...185),
2
)]
),
(178...179),
(189...190)
),
nil,
(174...177),
nil,
nil,
nil,
nil,
0,
"!"
)] )]
) )
) )

View File

@ -61,7 +61,7 @@ ProgramNode(0...68)(
(21...22) (21...22)
), ),
(12...14), (12...14),
0 2
)] )]
), ),
(3...4), (3...4),
@ -133,7 +133,7 @@ ProgramNode(0...68)(
(56...57) (56...57)
), ),
(46...49), (46...49),
1 3
)] )]
), ),
(37...38), (37...38),

View File

@ -18,7 +18,7 @@ ProgramNode(0...31)(
"bar" "bar"
), ),
(5...8), (5...8),
1 3
)] )]
), ),
(1...2), (1...2),

View File

@ -18,7 +18,7 @@ ProgramNode(0...29)(
"bar" "bar"
), ),
(5...7), (5...7),
0 2
)] )]
), ),
(1...2), (1...2),

View File

@ -447,6 +447,16 @@ yp_flip_flop(yp_node_t *node) {
yp_flip_flop(cast->right); yp_flip_flop(cast->right);
break; break;
} }
case YP_NODE_PARENTHESES_NODE: {
yp_parentheses_node_t *cast = (yp_parentheses_node_t *) node;
if ((cast->statements != NULL) && YP_NODE_TYPE_P(cast->statements, YP_NODE_STATEMENTS_NODE)) {
yp_statements_node_t *statements = (yp_statements_node_t *) cast->statements;
if (statements->body.size == 1) yp_flip_flop(statements->body.nodes[0]);
}
break;
}
case YP_NODE_RANGE_NODE: { case YP_NODE_RANGE_NODE: {
yp_range_node_t *cast = (yp_range_node_t *) node; yp_range_node_t *cast = (yp_range_node_t *) node;
cast->flags |= YP_RANGE_NODE_FLAGS_FLIP_FLOP; cast->flags |= YP_RANGE_NODE_FLAGS_FLIP_FLOP;
@ -11303,6 +11313,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end });
} else { } else {
receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`."); receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`.");
yp_flip_flop(receiver);
if (!parser->recovering) { if (!parser->recovering) {
accept(parser, YP_TOKEN_NEWLINE); accept(parser, YP_TOKEN_NEWLINE);
@ -11312,6 +11323,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
} }
} else { } else {
receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `not`."); receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `not`.");
yp_flip_flop(receiver);
} }
return (yp_node_t *) yp_call_node_not_create(parser, receiver, &message, &arguments); return (yp_node_t *) yp_call_node_not_create(parser, receiver, &message, &arguments);
@ -11889,6 +11901,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary !."); yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary !.");
yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!"); yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!");
yp_flip_flop(receiver);
return (yp_node_t *) node; return (yp_node_t *) node;
} }
case YP_TOKEN_TILDE: { case YP_TOKEN_TILDE: {