diff --git a/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt b/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt index 623be4987e7344..ffb6ee684b84eb 100644 --- a/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt +++ b/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt @@ -7,7 +7,7 @@ ProgramNode(0...16)( CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 0, "a"), CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "b"), (4...6), - 0 + 2 ), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/semantic/and.txt b/test/yarp/snapshots/unparser/corpus/semantic/and.txt index 470615af51c8c8..b082d308f777d2 100644 --- a/test/yarp/snapshots/unparser/corpus/semantic/and.txt +++ b/test/yarp/snapshots/unparser/corpus/semantic/and.txt @@ -38,13 +38,13 @@ ProgramNode(0...77)( CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 0, "a"), CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 0, "b"), (36...39), - 1 + 3 ), RangeNode(44...49)( CallNode(44...45)(nil, nil, (44...45), nil, nil, nil, nil, 0, "c"), CallNode(48...49)(nil, nil, (48...49), nil, nil, nil, nil, 0, "d"), (45...48), - 1 + 3 ), (41...43) ), @@ -59,13 +59,13 @@ ProgramNode(0...77)( CallNode(58...59)(nil, nil, (58...59), nil, nil, nil, nil, 0, "a"), CallNode(62...63)(nil, nil, (62...63), nil, nil, nil, nil, 0, "b"), (59...62), - 1 + 3 ), RangeNode(68...73)( CallNode(68...69)(nil, nil, (68...69), nil, nil, nil, nil, 0, "c"), CallNode(72...73)(nil, nil, (72...73), nil, nil, nil, nil, 0, "d"), (69...72), - 1 + 3 ), (64...67) ), diff --git a/test/yarp/snapshots/whitequark/cond_eflipflop.txt b/test/yarp/snapshots/whitequark/cond_eflipflop.txt index 6e1e6718d50ce7..dd44ace9a40456 100644 --- a/test/yarp/snapshots/whitequark/cond_eflipflop.txt +++ b/test/yarp/snapshots/whitequark/cond_eflipflop.txt @@ -39,7 +39,7 @@ ProgramNode(0...31)( CallNode(17...20)(nil, nil, (17...20), nil, nil, nil, nil, 0, "foo"), CallNode(23...26)(nil, nil, (23...26), nil, nil, nil, nil, 0, "bar"), (20...23), - 1 + 3 ), nil, nil, diff --git a/test/yarp/snapshots/whitequark/cond_iflipflop.txt b/test/yarp/snapshots/whitequark/cond_iflipflop.txt index e45eec8922e86a..594d1a9c60608f 100644 --- a/test/yarp/snapshots/whitequark/cond_iflipflop.txt +++ b/test/yarp/snapshots/whitequark/cond_iflipflop.txt @@ -39,7 +39,7 @@ ProgramNode(0...29)( CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 0, "foo"), CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 0, "bar"), (19...21), - 0 + 2 ), nil, nil, diff --git a/yarp/yarp.c b/yarp/yarp.c index 6f3d8758605b87..9de67f7c62a880 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -431,6 +431,32 @@ yp_parser_constant_id_token(yp_parser_t *parser, const yp_token_t *token) { return yp_parser_constant_id_location(parser, token->start, token->end); } +// Mark any range nodes in this subtree as flipflops. +static void +yp_flip_flop(yp_node_t *node) { + switch (YP_NODE_TYPE(node)) { + case YP_NODE_AND_NODE: { + yp_and_node_t *cast = (yp_and_node_t *) node; + yp_flip_flop(cast->left); + yp_flip_flop(cast->right); + break; + } + case YP_NODE_OR_NODE: { + yp_or_node_t *cast = (yp_or_node_t *) node; + yp_flip_flop(cast->left); + yp_flip_flop(cast->right); + break; + } + case YP_NODE_RANGE_NODE: { + yp_range_node_t *cast = (yp_range_node_t *) node; + cast->flags |= YP_RANGE_NODE_FLAGS_FLIP_FLOP; + break; + } + default: + break; + } +} + // In a lot of places in the tree you can have tokens that are not provided but // that do not cause an error. For example, in a method call without // parentheses. In these cases we set the token to the "not provided" type. For @@ -2274,6 +2300,7 @@ yp_if_node_create(yp_parser_t *parser, yp_node_t *consequent, const yp_token_t *end_keyword ) { + yp_flip_flop(predicate); yp_if_node_t *node = YP_ALLOC_NODE(parser, yp_if_node_t); const char *end; @@ -2309,6 +2336,7 @@ yp_if_node_create(yp_parser_t *parser, // Allocate and initialize new IfNode node in the modifier form. static yp_if_node_t * yp_if_node_modifier_create(yp_parser_t *parser, yp_node_t *statement, const yp_token_t *if_keyword, yp_node_t *predicate) { + yp_flip_flop(predicate); yp_if_node_t *node = YP_ALLOC_NODE(parser, yp_if_node_t); yp_statements_node_t *statements = yp_statements_node_create(parser); @@ -2336,6 +2364,8 @@ yp_if_node_modifier_create(yp_parser_t *parser, yp_node_t *statement, const yp_t // Allocate and initialize an if node from a ternary expression. static yp_if_node_t * yp_if_node_ternary_create(yp_parser_t *parser, yp_node_t *predicate, yp_node_t *true_expression, const yp_token_t *colon, yp_node_t *false_expression) { + yp_flip_flop(predicate); + yp_statements_node_t *if_statements = yp_statements_node_create(parser); yp_statements_node_body_append(if_statements, true_expression); @@ -3974,6 +4004,7 @@ yp_undef_node_append(yp_undef_node_t *node, yp_node_t *name) { // Allocate a new UnlessNode node. static yp_unless_node_t * yp_unless_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements) { + yp_flip_flop(predicate); yp_unless_node_t *node = YP_ALLOC_NODE(parser, yp_unless_node_t); const char *end; @@ -4005,6 +4036,7 @@ yp_unless_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t // Allocate and initialize new UnlessNode node in the modifier form. static yp_unless_node_t * yp_unless_node_modifier_create(yp_parser_t *parser, yp_node_t *statement, const yp_token_t *unless_keyword, yp_node_t *predicate) { + yp_flip_flop(predicate); yp_unless_node_t *node = YP_ALLOC_NODE(parser, yp_unless_node_t); yp_statements_node_t *statements = yp_statements_node_create(parser);