diff options
author | Kevin Newton <kddnewton@gmail.com> | 2023-08-10 14:16:56 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2023-08-16 17:47:32 -0700 |
commit | bf723b21ccd9d019bca5e33364a21f0219326547 (patch) | |
tree | 13b0d64d9565284efa60f40d3e78d7c2c0caa0f6 | |
parent | fb287fa425514ee26a156e9792e1e6380c0318b5 (diff) | |
download | ruby-bf723b21ccd9d019bca5e33364a21f0219326547.tar.gz |
[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
-rw-r--r-- | test/yarp/fixtures/not.txt | 4 | ||||
-rw-r--r-- | test/yarp/snapshots/not.txt | 82 | ||||
-rw-r--r-- | test/yarp/snapshots/unparser/corpus/literal/flipflop.txt | 4 | ||||
-rw-r--r-- | test/yarp/snapshots/whitequark/cond_eflipflop.txt | 2 | ||||
-rw-r--r-- | test/yarp/snapshots/whitequark/cond_iflipflop.txt | 2 | ||||
-rw-r--r-- | yarp/yarp.c | 13 |
6 files changed, 101 insertions, 6 deletions
diff --git a/test/yarp/fixtures/not.txt b/test/yarp/fixtures/not.txt index a623553613..520b34fa37 100644 --- a/test/yarp/fixtures/not.txt +++ b/test/yarp/fixtures/not.txt @@ -31,3 +31,7 @@ foo ) + +not foo .. bar + +not (foo .. bar) diff --git a/test/yarp/snapshots/not.txt b/test/yarp/snapshots/not.txt index a4be66de26..7bec91e7e7 100644 --- a/test/yarp/snapshots/not.txt +++ b/test/yarp/snapshots/not.txt @@ -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, + "!" )] ) ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt b/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt index b4837b7dc8..ea875e159a 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt @@ -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), diff --git a/test/yarp/snapshots/whitequark/cond_eflipflop.txt b/test/yarp/snapshots/whitequark/cond_eflipflop.txt index dd44ace9a4..889d14d8f3 100644 --- a/test/yarp/snapshots/whitequark/cond_eflipflop.txt +++ b/test/yarp/snapshots/whitequark/cond_eflipflop.txt @@ -18,7 +18,7 @@ ProgramNode(0...31)( "bar" ), (5...8), - 1 + 3 )] ), (1...2), diff --git a/test/yarp/snapshots/whitequark/cond_iflipflop.txt b/test/yarp/snapshots/whitequark/cond_iflipflop.txt index 594d1a9c60..5dee6f321c 100644 --- a/test/yarp/snapshots/whitequark/cond_iflipflop.txt +++ b/test/yarp/snapshots/whitequark/cond_iflipflop.txt @@ -18,7 +18,7 @@ ProgramNode(0...29)( "bar" ), (5...7), - 0 + 2 )] ), (1...2), diff --git a/yarp/yarp.c b/yarp/yarp.c index 9de67f7c62..dcfde47d01 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -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: { |