[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)(
CallNode(0...7)(
CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "foo"),
@ -188,6 +188,84 @@ ProgramNode(0...156)(
nil,
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)
),
(12...14),
0
2
)]
),
(3...4),
@ -133,7 +133,7 @@ ProgramNode(0...68)(
(56...57)
),
(46...49),
1
3
)]
),
(37...38),

View File

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

View File

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

View File

@ -447,6 +447,16 @@ yp_flip_flop(yp_node_t *node) {
yp_flip_flop(cast->right);
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: {
yp_range_node_t *cast = (yp_range_node_t *) node;
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 });
} else {
receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`.");
yp_flip_flop(receiver);
if (!parser->recovering) {
accept(parser, YP_TOKEN_NEWLINE);
@ -11312,6 +11323,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
} else {
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);
@ -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_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!");
yp_flip_flop(receiver);
return (yp_node_t *) node;
}
case YP_TOKEN_TILDE: {