yarp 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -2
- data/Makefile +2 -0
- data/README.md +5 -2
- data/config.yml +54 -267
- data/ext/yarp/api_node.c +135 -579
- data/ext/yarp/extension.c +2 -2
- data/ext/yarp/extension.h +1 -1
- data/include/yarp/ast.h +142 -285
- data/include/yarp/defines.h +5 -0
- data/include/yarp/unescape.h +1 -1
- data/include/yarp/util/yp_buffer.h +9 -1
- data/include/yarp/util/yp_constant_pool.h +3 -0
- data/include/yarp/util/yp_list.h +7 -7
- data/include/yarp/util/yp_newline_list.h +4 -0
- data/include/yarp/util/yp_state_stack.h +1 -1
- data/include/yarp/version.h +2 -2
- data/lib/yarp/ffi.rb +62 -47
- data/lib/yarp/node.rb +504 -1399
- data/lib/yarp/serialize.rb +111 -141
- data/lib/yarp.rb +6 -6
- data/src/node.c +70 -250
- data/src/prettyprint.c +41 -185
- data/src/serialize.c +35 -133
- data/src/unescape.c +29 -35
- data/src/util/yp_buffer.c +18 -0
- data/src/util/yp_list.c +7 -16
- data/src/util/yp_state_stack.c +0 -6
- data/src/yarp.c +265 -670
- data/yarp.gemspec +1 -1
- metadata +2 -2
data/src/yarp.c
CHANGED
@@ -450,8 +450,8 @@ yp_flip_flop(yp_node_t *node) {
|
|
450
450
|
case YP_NODE_PARENTHESES_NODE: {
|
451
451
|
yp_parentheses_node_t *cast = (yp_parentheses_node_t *) node;
|
452
452
|
|
453
|
-
if ((cast->
|
454
|
-
yp_statements_node_t *statements = (yp_statements_node_t *) cast->
|
453
|
+
if ((cast->body != NULL) && YP_NODE_TYPE_P(cast->body, YP_NODE_STATEMENTS_NODE)) {
|
454
|
+
yp_statements_node_t *statements = (yp_statements_node_t *) cast->body;
|
455
455
|
if (statements->body.size == 1) yp_flip_flop(statements->body.nodes[0]);
|
456
456
|
}
|
457
457
|
|
@@ -459,8 +459,12 @@ yp_flip_flop(yp_node_t *node) {
|
|
459
459
|
}
|
460
460
|
case YP_NODE_RANGE_NODE: {
|
461
461
|
yp_range_node_t *cast = (yp_range_node_t *) node;
|
462
|
-
|
463
|
-
|
462
|
+
if (cast->left) {
|
463
|
+
yp_flip_flop(cast->left);
|
464
|
+
}
|
465
|
+
if (cast->right) {
|
466
|
+
yp_flip_flop(cast->right);
|
467
|
+
}
|
464
468
|
|
465
469
|
// Here we change the range node into a flip flop node. We can do
|
466
470
|
// this since the nodes are exactly the same except for the type.
|
@@ -654,6 +658,27 @@ yp_and_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *opera
|
|
654
658
|
return node;
|
655
659
|
}
|
656
660
|
|
661
|
+
// Allocate and initialize a new AndWriteNode.
|
662
|
+
static yp_and_write_node_t *
|
663
|
+
yp_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
664
|
+
yp_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_and_write_node_t);
|
665
|
+
|
666
|
+
*node = (yp_and_write_node_t) {
|
667
|
+
{
|
668
|
+
.type = YP_NODE_AND_WRITE_NODE,
|
669
|
+
.location = {
|
670
|
+
.start = target->location.start,
|
671
|
+
.end = value->location.end
|
672
|
+
},
|
673
|
+
},
|
674
|
+
.target = target,
|
675
|
+
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
676
|
+
.value = value
|
677
|
+
};
|
678
|
+
|
679
|
+
return node;
|
680
|
+
}
|
681
|
+
|
657
682
|
// Allocate an initialize a new arguments node.
|
658
683
|
static yp_arguments_node_t *
|
659
684
|
yp_arguments_node_create(yp_parser_t *parser) {
|
@@ -993,7 +1018,7 @@ yp_block_argument_node_create(yp_parser_t *parser, const yp_token_t *operator, y
|
|
993
1018
|
|
994
1019
|
// Allocate and initialize a new BlockNode node.
|
995
1020
|
static yp_block_node_t *
|
996
|
-
yp_block_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *opening, yp_block_parameters_node_t *parameters, yp_node_t *
|
1021
|
+
yp_block_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *opening, yp_block_parameters_node_t *parameters, yp_node_t *body, const yp_token_t *closing) {
|
997
1022
|
yp_block_node_t *node = YP_ALLOC_NODE(parser, yp_block_node_t);
|
998
1023
|
|
999
1024
|
*node = (yp_block_node_t) {
|
@@ -1003,7 +1028,7 @@ yp_block_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const y
|
|
1003
1028
|
},
|
1004
1029
|
.locals = *locals,
|
1005
1030
|
.parameters = parameters,
|
1006
|
-
.
|
1031
|
+
.body = body,
|
1007
1032
|
.opening_loc = YP_LOCATION_TOKEN_VALUE(opening),
|
1008
1033
|
.closing_loc = YP_LOCATION_TOKEN_VALUE(closing)
|
1009
1034
|
};
|
@@ -1461,7 +1486,7 @@ yp_case_node_end_keyword_loc_set(yp_case_node_t *node, const yp_token_t *end_key
|
|
1461
1486
|
|
1462
1487
|
// Allocate a new ClassNode node.
|
1463
1488
|
static yp_class_node_t *
|
1464
|
-
yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *
|
1489
|
+
yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *body, const yp_token_t *end_keyword) {
|
1465
1490
|
yp_class_node_t *node = YP_ALLOC_NODE(parser, yp_class_node_t);
|
1466
1491
|
|
1467
1492
|
*node = (yp_class_node_t) {
|
@@ -1474,81 +1499,13 @@ yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const y
|
|
1474
1499
|
.constant_path = constant_path,
|
1475
1500
|
.inheritance_operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(inheritance_operator),
|
1476
1501
|
.superclass = superclass,
|
1477
|
-
.
|
1502
|
+
.body = body,
|
1478
1503
|
.end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword)
|
1479
1504
|
};
|
1480
1505
|
|
1481
1506
|
return node;
|
1482
1507
|
}
|
1483
1508
|
|
1484
|
-
// Allocate and initialize a new ClassVariableOperatorAndWriteNode node.
|
1485
|
-
static yp_class_variable_operator_and_write_node_t *
|
1486
|
-
yp_class_variable_operator_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1487
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_CLASS_VARIABLE_READ_NODE));
|
1488
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
1489
|
-
yp_class_variable_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_operator_and_write_node_t);
|
1490
|
-
|
1491
|
-
*node = (yp_class_variable_operator_and_write_node_t) {
|
1492
|
-
{
|
1493
|
-
.type = YP_NODE_CLASS_VARIABLE_OPERATOR_AND_WRITE_NODE,
|
1494
|
-
.location = {
|
1495
|
-
.start = target->location.start,
|
1496
|
-
.end = value->location.end
|
1497
|
-
}
|
1498
|
-
},
|
1499
|
-
.name_loc = target->location,
|
1500
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1501
|
-
.value = value
|
1502
|
-
};
|
1503
|
-
|
1504
|
-
return node;
|
1505
|
-
}
|
1506
|
-
|
1507
|
-
// Allocate and initialize a new ClassVariableOperatorWriteNode node.
|
1508
|
-
static yp_class_variable_operator_write_node_t *
|
1509
|
-
yp_class_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1510
|
-
yp_class_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_operator_write_node_t);
|
1511
|
-
|
1512
|
-
*node = (yp_class_variable_operator_write_node_t) {
|
1513
|
-
{
|
1514
|
-
.type = YP_NODE_CLASS_VARIABLE_OPERATOR_WRITE_NODE,
|
1515
|
-
.location = {
|
1516
|
-
.start = target->location.start,
|
1517
|
-
.end = value->location.end
|
1518
|
-
}
|
1519
|
-
},
|
1520
|
-
.name_loc = target->location,
|
1521
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1522
|
-
.value = value,
|
1523
|
-
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
1524
|
-
};
|
1525
|
-
|
1526
|
-
return node;
|
1527
|
-
}
|
1528
|
-
|
1529
|
-
// Allocate and initialize a new ClassVariableOperatorOrWriteNode node.
|
1530
|
-
static yp_class_variable_operator_or_write_node_t *
|
1531
|
-
yp_class_variable_operator_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1532
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_CLASS_VARIABLE_READ_NODE));
|
1533
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
1534
|
-
yp_class_variable_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_operator_or_write_node_t);
|
1535
|
-
|
1536
|
-
*node = (yp_class_variable_operator_or_write_node_t) {
|
1537
|
-
{
|
1538
|
-
.type = YP_NODE_CLASS_VARIABLE_OPERATOR_OR_WRITE_NODE,
|
1539
|
-
.location = {
|
1540
|
-
.start = target->location.start,
|
1541
|
-
.end = value->location.end
|
1542
|
-
}
|
1543
|
-
},
|
1544
|
-
.name_loc = target->location,
|
1545
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1546
|
-
.value = value
|
1547
|
-
};
|
1548
|
-
|
1549
|
-
return node;
|
1550
|
-
}
|
1551
|
-
|
1552
1509
|
// Allocate and initialize a new ClassVariableReadNode node.
|
1553
1510
|
static yp_class_variable_read_node_t *
|
1554
1511
|
yp_class_variable_read_node_create(yp_parser_t *parser, const yp_token_t *token) {
|
@@ -1579,72 +1536,6 @@ yp_class_variable_read_node_to_class_variable_write_node(yp_parser_t *parser, yp
|
|
1579
1536
|
return node;
|
1580
1537
|
}
|
1581
1538
|
|
1582
|
-
// Allocate and initialize a new ConstantPathOperatorAndWriteNode node.
|
1583
|
-
static yp_constant_path_operator_and_write_node_t *
|
1584
|
-
yp_constant_path_operator_and_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1585
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
1586
|
-
yp_constant_path_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_operator_and_write_node_t);
|
1587
|
-
|
1588
|
-
*node = (yp_constant_path_operator_and_write_node_t) {
|
1589
|
-
{
|
1590
|
-
.type = YP_NODE_CONSTANT_PATH_OPERATOR_AND_WRITE_NODE,
|
1591
|
-
.location = {
|
1592
|
-
.start = target->base.location.start,
|
1593
|
-
.end = value->location.end
|
1594
|
-
}
|
1595
|
-
},
|
1596
|
-
.target = target,
|
1597
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1598
|
-
.value = value
|
1599
|
-
};
|
1600
|
-
|
1601
|
-
return node;
|
1602
|
-
}
|
1603
|
-
|
1604
|
-
// Allocate and initialize a new ConstantPathOperatorWriteNode node.
|
1605
|
-
static yp_constant_path_operator_write_node_t *
|
1606
|
-
yp_constant_path_operator_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1607
|
-
yp_constant_path_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_operator_write_node_t);
|
1608
|
-
|
1609
|
-
*node = (yp_constant_path_operator_write_node_t) {
|
1610
|
-
{
|
1611
|
-
.type = YP_NODE_CONSTANT_PATH_OPERATOR_WRITE_NODE,
|
1612
|
-
.location = {
|
1613
|
-
.start = target->base.location.start,
|
1614
|
-
.end = value->location.end
|
1615
|
-
}
|
1616
|
-
},
|
1617
|
-
.target = target,
|
1618
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1619
|
-
.value = value,
|
1620
|
-
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
1621
|
-
};
|
1622
|
-
|
1623
|
-
return node;
|
1624
|
-
}
|
1625
|
-
|
1626
|
-
// Allocate and initialize a new ConstantPathOperatorOrWriteNode node.
|
1627
|
-
static yp_constant_path_operator_or_write_node_t *
|
1628
|
-
yp_constant_path_operator_or_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1629
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
1630
|
-
yp_constant_path_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_operator_or_write_node_t);
|
1631
|
-
|
1632
|
-
*node = (yp_constant_path_operator_or_write_node_t) {
|
1633
|
-
{
|
1634
|
-
.type = YP_NODE_CONSTANT_PATH_OPERATOR_OR_WRITE_NODE,
|
1635
|
-
.location = {
|
1636
|
-
.start = target->base.location.start,
|
1637
|
-
.end = value->location.end
|
1638
|
-
}
|
1639
|
-
},
|
1640
|
-
.target = target,
|
1641
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1642
|
-
.value = value
|
1643
|
-
};
|
1644
|
-
|
1645
|
-
return node;
|
1646
|
-
}
|
1647
|
-
|
1648
1539
|
// Allocate and initialize a new ConstantPathNode node.
|
1649
1540
|
static yp_constant_path_node_t *
|
1650
1541
|
yp_constant_path_node_create(yp_parser_t *parser, yp_node_t *parent, const yp_token_t *delimiter, yp_node_t *child) {
|
@@ -1687,74 +1578,6 @@ yp_constant_path_write_node_create(yp_parser_t *parser, yp_constant_path_node_t
|
|
1687
1578
|
return node;
|
1688
1579
|
}
|
1689
1580
|
|
1690
|
-
// Allocate and initialize a new ConstantOperatorAndWriteNode node.
|
1691
|
-
static yp_constant_operator_and_write_node_t *
|
1692
|
-
yp_constant_operator_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1693
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_CONSTANT_READ_NODE));
|
1694
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
1695
|
-
yp_constant_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_operator_and_write_node_t);
|
1696
|
-
|
1697
|
-
*node = (yp_constant_operator_and_write_node_t) {
|
1698
|
-
{
|
1699
|
-
.type = YP_NODE_CONSTANT_OPERATOR_AND_WRITE_NODE,
|
1700
|
-
.location = {
|
1701
|
-
.start = target->location.start,
|
1702
|
-
.end = value->location.end
|
1703
|
-
}
|
1704
|
-
},
|
1705
|
-
.name_loc = target->location,
|
1706
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1707
|
-
.value = value
|
1708
|
-
};
|
1709
|
-
|
1710
|
-
return node;
|
1711
|
-
}
|
1712
|
-
|
1713
|
-
// Allocate and initialize a new ConstantOperatorWriteNode node.
|
1714
|
-
static yp_constant_operator_write_node_t *
|
1715
|
-
yp_constant_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1716
|
-
yp_constant_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_operator_write_node_t);
|
1717
|
-
|
1718
|
-
*node = (yp_constant_operator_write_node_t) {
|
1719
|
-
{
|
1720
|
-
.type = YP_NODE_CONSTANT_OPERATOR_WRITE_NODE,
|
1721
|
-
.location = {
|
1722
|
-
.start = target->location.start,
|
1723
|
-
.end = value->location.end
|
1724
|
-
}
|
1725
|
-
},
|
1726
|
-
.name_loc = target->location,
|
1727
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1728
|
-
.value = value,
|
1729
|
-
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
1730
|
-
};
|
1731
|
-
|
1732
|
-
return node;
|
1733
|
-
}
|
1734
|
-
|
1735
|
-
// Allocate and initialize a new ConstantOperatorOrWriteNode node.
|
1736
|
-
static yp_constant_operator_or_write_node_t *
|
1737
|
-
yp_constant_operator_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
1738
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_CONSTANT_READ_NODE));
|
1739
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
1740
|
-
yp_constant_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_operator_or_write_node_t);
|
1741
|
-
|
1742
|
-
*node = (yp_constant_operator_or_write_node_t) {
|
1743
|
-
{
|
1744
|
-
.type = YP_NODE_CONSTANT_OPERATOR_OR_WRITE_NODE,
|
1745
|
-
.location = {
|
1746
|
-
.start = target->location.start,
|
1747
|
-
.end = value->location.end
|
1748
|
-
}
|
1749
|
-
},
|
1750
|
-
.name_loc = target->location,
|
1751
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
1752
|
-
.value = value
|
1753
|
-
};
|
1754
|
-
|
1755
|
-
return node;
|
1756
|
-
}
|
1757
|
-
|
1758
1581
|
// Allocate and initialize a new ConstantReadNode node.
|
1759
1582
|
static yp_constant_read_node_t *
|
1760
1583
|
yp_constant_read_node_create(yp_parser_t *parser, const yp_token_t *name) {
|
@@ -1793,7 +1616,7 @@ yp_def_node_create(
|
|
1793
1616
|
const yp_token_t *name,
|
1794
1617
|
yp_node_t *receiver,
|
1795
1618
|
yp_parameters_node_t *parameters,
|
1796
|
-
yp_node_t *
|
1619
|
+
yp_node_t *body,
|
1797
1620
|
yp_constant_id_list_t *locals,
|
1798
1621
|
const yp_token_t *def_keyword,
|
1799
1622
|
const yp_token_t *operator,
|
@@ -1806,7 +1629,7 @@ yp_def_node_create(
|
|
1806
1629
|
const char *end;
|
1807
1630
|
|
1808
1631
|
if (end_keyword->type == YP_TOKEN_NOT_PROVIDED) {
|
1809
|
-
end =
|
1632
|
+
end = body->location.end;
|
1810
1633
|
} else {
|
1811
1634
|
end = end_keyword->end;
|
1812
1635
|
}
|
@@ -1819,7 +1642,7 @@ yp_def_node_create(
|
|
1819
1642
|
.name_loc = YP_LOCATION_TOKEN_VALUE(name),
|
1820
1643
|
.receiver = receiver,
|
1821
1644
|
.parameters = parameters,
|
1822
|
-
.
|
1645
|
+
.body = body,
|
1823
1646
|
.locals = *locals,
|
1824
1647
|
.def_keyword_loc = YP_LOCATION_TOKEN_VALUE(def_keyword),
|
1825
1648
|
.operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
|
@@ -2189,74 +2012,6 @@ yp_hash_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *assoc
|
|
2189
2012
|
return node;
|
2190
2013
|
}
|
2191
2014
|
|
2192
|
-
// Allocate and initialize a new GlobalVariableOperatorAndWriteNode node.
|
2193
|
-
static yp_global_variable_operator_and_write_node_t *
|
2194
|
-
yp_global_variable_operator_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2195
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_GLOBAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_NUMBERED_REFERENCE_READ_NODE));
|
2196
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
2197
|
-
yp_global_variable_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_operator_and_write_node_t);
|
2198
|
-
|
2199
|
-
*node = (yp_global_variable_operator_and_write_node_t) {
|
2200
|
-
{
|
2201
|
-
.type = YP_NODE_GLOBAL_VARIABLE_OPERATOR_AND_WRITE_NODE,
|
2202
|
-
.location = {
|
2203
|
-
.start = target->location.start,
|
2204
|
-
.end = value->location.end
|
2205
|
-
}
|
2206
|
-
},
|
2207
|
-
.name_loc = target->location,
|
2208
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2209
|
-
.value = value
|
2210
|
-
};
|
2211
|
-
|
2212
|
-
return node;
|
2213
|
-
}
|
2214
|
-
|
2215
|
-
// Allocate and initialize a new GlobalVariableOperatorWriteNode node.
|
2216
|
-
static yp_global_variable_operator_write_node_t *
|
2217
|
-
yp_global_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2218
|
-
yp_global_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_operator_write_node_t);
|
2219
|
-
|
2220
|
-
*node = (yp_global_variable_operator_write_node_t) {
|
2221
|
-
{
|
2222
|
-
.type = YP_NODE_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE,
|
2223
|
-
.location = {
|
2224
|
-
.start = target->location.start,
|
2225
|
-
.end = value->location.end
|
2226
|
-
}
|
2227
|
-
},
|
2228
|
-
.name_loc = target->location,
|
2229
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2230
|
-
.value = value,
|
2231
|
-
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
2232
|
-
};
|
2233
|
-
|
2234
|
-
return node;
|
2235
|
-
}
|
2236
|
-
|
2237
|
-
// Allocate and initialize a new GlobalVariableOperatorOrWriteNode node.
|
2238
|
-
static yp_global_variable_operator_or_write_node_t *
|
2239
|
-
yp_global_variable_operator_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2240
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_GLOBAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_NUMBERED_REFERENCE_READ_NODE));
|
2241
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
2242
|
-
yp_global_variable_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_operator_or_write_node_t);
|
2243
|
-
|
2244
|
-
*node = (yp_global_variable_operator_or_write_node_t) {
|
2245
|
-
{
|
2246
|
-
.type = YP_NODE_GLOBAL_VARIABLE_OPERATOR_OR_WRITE_NODE,
|
2247
|
-
.location = {
|
2248
|
-
.start = target->location.start,
|
2249
|
-
.end = value->location.end
|
2250
|
-
}
|
2251
|
-
},
|
2252
|
-
.name_loc = target->location,
|
2253
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2254
|
-
.value = value
|
2255
|
-
};
|
2256
|
-
|
2257
|
-
return node;
|
2258
|
-
}
|
2259
|
-
|
2260
2015
|
// Allocate a new GlobalVariableReadNode node.
|
2261
2016
|
static yp_global_variable_read_node_t *
|
2262
2017
|
yp_global_variable_read_node_create(yp_parser_t *parser, const yp_token_t *name) {
|
@@ -2547,74 +2302,6 @@ yp_in_node_create(yp_parser_t *parser, yp_node_t *pattern, yp_statements_node_t
|
|
2547
2302
|
return node;
|
2548
2303
|
}
|
2549
2304
|
|
2550
|
-
// Allocate and initialize a new InstanceVariableOperatorAndWriteNode node.
|
2551
|
-
static yp_instance_variable_operator_and_write_node_t *
|
2552
|
-
yp_instance_variable_operator_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2553
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_INSTANCE_VARIABLE_READ_NODE));
|
2554
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
2555
|
-
yp_instance_variable_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_operator_and_write_node_t);
|
2556
|
-
|
2557
|
-
*node = (yp_instance_variable_operator_and_write_node_t) {
|
2558
|
-
{
|
2559
|
-
.type = YP_NODE_INSTANCE_VARIABLE_OPERATOR_AND_WRITE_NODE,
|
2560
|
-
.location = {
|
2561
|
-
.start = target->location.start,
|
2562
|
-
.end = value->location.end
|
2563
|
-
}
|
2564
|
-
},
|
2565
|
-
.name_loc = target->location,
|
2566
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2567
|
-
.value = value
|
2568
|
-
};
|
2569
|
-
|
2570
|
-
return node;
|
2571
|
-
}
|
2572
|
-
|
2573
|
-
// Allocate and initialize a new InstanceVariableOperatorWriteNode node.
|
2574
|
-
static yp_instance_variable_operator_write_node_t *
|
2575
|
-
yp_instance_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2576
|
-
yp_instance_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_operator_write_node_t);
|
2577
|
-
|
2578
|
-
*node = (yp_instance_variable_operator_write_node_t) {
|
2579
|
-
{
|
2580
|
-
.type = YP_NODE_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE,
|
2581
|
-
.location = {
|
2582
|
-
.start = target->location.start,
|
2583
|
-
.end = value->location.end
|
2584
|
-
}
|
2585
|
-
},
|
2586
|
-
.name_loc = target->location,
|
2587
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2588
|
-
.value = value,
|
2589
|
-
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
2590
|
-
};
|
2591
|
-
|
2592
|
-
return node;
|
2593
|
-
}
|
2594
|
-
|
2595
|
-
// Allocate and initialize a new InstanceVariableOperatorOrWriteNode node.
|
2596
|
-
static yp_instance_variable_operator_or_write_node_t *
|
2597
|
-
yp_instance_variable_operator_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2598
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_INSTANCE_VARIABLE_READ_NODE));
|
2599
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
2600
|
-
yp_instance_variable_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_operator_or_write_node_t);
|
2601
|
-
|
2602
|
-
*node = (yp_instance_variable_operator_or_write_node_t) {
|
2603
|
-
{
|
2604
|
-
.type = YP_NODE_INSTANCE_VARIABLE_OPERATOR_OR_WRITE_NODE,
|
2605
|
-
.location = {
|
2606
|
-
.start = target->location.start,
|
2607
|
-
.end = value->location.end
|
2608
|
-
}
|
2609
|
-
},
|
2610
|
-
.name_loc = target->location,
|
2611
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2612
|
-
.value = value
|
2613
|
-
};
|
2614
|
-
|
2615
|
-
return node;
|
2616
|
-
}
|
2617
|
-
|
2618
2305
|
// Allocate and initialize a new InstanceVariableReadNode node.
|
2619
2306
|
static yp_instance_variable_read_node_t *
|
2620
2307
|
yp_instance_variable_read_node_create(yp_parser_t *parser, const yp_token_t *token) {
|
@@ -2706,6 +2393,10 @@ yp_interpolated_string_node_create(yp_parser_t *parser, const yp_token_t *openin
|
|
2706
2393
|
// Append a part to an InterpolatedStringNode node.
|
2707
2394
|
static inline void
|
2708
2395
|
yp_interpolated_string_node_append(yp_interpolated_string_node_t *node, yp_node_t *part) {
|
2396
|
+
if (node->parts.size == 0 && node->opening_loc.start == NULL) {
|
2397
|
+
node->base.location.start = part->location.start;
|
2398
|
+
}
|
2399
|
+
|
2709
2400
|
yp_node_list_append(&node->parts, part);
|
2710
2401
|
node->base.location.end = part->location.end;
|
2711
2402
|
}
|
@@ -2862,7 +2553,7 @@ yp_lambda_node_create(
|
|
2862
2553
|
yp_constant_id_list_t *locals,
|
2863
2554
|
const yp_token_t *opening,
|
2864
2555
|
yp_block_parameters_node_t *parameters,
|
2865
|
-
yp_node_t *
|
2556
|
+
yp_node_t *body,
|
2866
2557
|
const yp_token_t *closing
|
2867
2558
|
) {
|
2868
2559
|
yp_lambda_node_t *node = YP_ALLOC_NODE(parser, yp_lambda_node_t);
|
@@ -2878,78 +2569,7 @@ yp_lambda_node_create(
|
|
2878
2569
|
.locals = *locals,
|
2879
2570
|
.opening_loc = YP_LOCATION_TOKEN_VALUE(opening),
|
2880
2571
|
.parameters = parameters,
|
2881
|
-
.
|
2882
|
-
};
|
2883
|
-
|
2884
|
-
return node;
|
2885
|
-
}
|
2886
|
-
|
2887
|
-
// Allocate and initialize a new LocalVariableOperatorAndWriteNode node.
|
2888
|
-
static yp_local_variable_operator_and_write_node_t *
|
2889
|
-
yp_local_variable_operator_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t constant_id) {
|
2890
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_LOCAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_CALL_NODE));
|
2891
|
-
assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
|
2892
|
-
yp_local_variable_operator_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_operator_and_write_node_t);
|
2893
|
-
|
2894
|
-
*node = (yp_local_variable_operator_and_write_node_t) {
|
2895
|
-
{
|
2896
|
-
.type = YP_NODE_LOCAL_VARIABLE_OPERATOR_AND_WRITE_NODE,
|
2897
|
-
.location = {
|
2898
|
-
.start = target->location.start,
|
2899
|
-
.end = value->location.end
|
2900
|
-
}
|
2901
|
-
},
|
2902
|
-
.name_loc = target->location,
|
2903
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2904
|
-
.value = value,
|
2905
|
-
.constant_id = constant_id
|
2906
|
-
};
|
2907
|
-
|
2908
|
-
return node;
|
2909
|
-
}
|
2910
|
-
|
2911
|
-
// Allocate and initialize a new LocalVariableOperatorWriteNode node.
|
2912
|
-
static yp_local_variable_operator_write_node_t *
|
2913
|
-
yp_local_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t constant_id) {
|
2914
|
-
yp_local_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_operator_write_node_t);
|
2915
|
-
|
2916
|
-
*node = (yp_local_variable_operator_write_node_t) {
|
2917
|
-
{
|
2918
|
-
.type = YP_NODE_LOCAL_VARIABLE_OPERATOR_WRITE_NODE,
|
2919
|
-
.location = {
|
2920
|
-
.start = target->location.start,
|
2921
|
-
.end = value->location.end
|
2922
|
-
}
|
2923
|
-
},
|
2924
|
-
.name_loc = target->location,
|
2925
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2926
|
-
.value = value,
|
2927
|
-
.constant_id = constant_id,
|
2928
|
-
.operator_id = yp_parser_constant_id_location(parser, operator->start, operator->end - 1)
|
2929
|
-
};
|
2930
|
-
|
2931
|
-
return node;
|
2932
|
-
}
|
2933
|
-
|
2934
|
-
// Allocate and initialize a new LocalVariableOperatorOrWriteNode node.
|
2935
|
-
static yp_local_variable_operator_or_write_node_t *
|
2936
|
-
yp_local_variable_operator_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t constant_id) {
|
2937
|
-
assert(YP_NODE_TYPE_P(target, YP_NODE_LOCAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_NODE_CALL_NODE));
|
2938
|
-
assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL);
|
2939
|
-
yp_local_variable_operator_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_operator_or_write_node_t);
|
2940
|
-
|
2941
|
-
*node = (yp_local_variable_operator_or_write_node_t) {
|
2942
|
-
{
|
2943
|
-
.type = YP_NODE_LOCAL_VARIABLE_OPERATOR_OR_WRITE_NODE,
|
2944
|
-
.location = {
|
2945
|
-
.start = target->location.start,
|
2946
|
-
.end = value->location.end
|
2947
|
-
}
|
2948
|
-
},
|
2949
|
-
.name_loc = target->location,
|
2950
|
-
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2951
|
-
.value = value,
|
2952
|
-
.constant_id = constant_id
|
2572
|
+
.body = body
|
2953
2573
|
};
|
2954
2574
|
|
2955
2575
|
return node;
|
@@ -3059,7 +2679,7 @@ yp_match_required_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t *
|
|
3059
2679
|
|
3060
2680
|
// Allocate a new ModuleNode node.
|
3061
2681
|
static yp_module_node_t *
|
3062
|
-
yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, yp_node_t *
|
2682
|
+
yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, yp_node_t *body, const yp_token_t *end_keyword) {
|
3063
2683
|
yp_module_node_t *node = YP_ALLOC_NODE(parser, yp_module_node_t);
|
3064
2684
|
|
3065
2685
|
*node = (yp_module_node_t) {
|
@@ -3073,7 +2693,7 @@ yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const
|
|
3073
2693
|
.locals = (locals == NULL ? ((yp_constant_id_list_t) { .ids = NULL, .size = 0, .capacity = 0 }) : *locals),
|
3074
2694
|
.module_keyword_loc = YP_LOCATION_TOKEN_VALUE(module_keyword),
|
3075
2695
|
.constant_path = constant_path,
|
3076
|
-
.
|
2696
|
+
.body = body,
|
3077
2697
|
.end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword)
|
3078
2698
|
};
|
3079
2699
|
|
@@ -3188,6 +2808,28 @@ yp_numbered_reference_read_node_create(yp_parser_t *parser, const yp_token_t *na
|
|
3188
2808
|
return node;
|
3189
2809
|
}
|
3190
2810
|
|
2811
|
+
// Allocate and initialize a new OperatorWriteNode.
|
2812
|
+
static yp_operator_write_node_t *
|
2813
|
+
yp_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2814
|
+
yp_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_operator_write_node_t);
|
2815
|
+
|
2816
|
+
*node = (yp_operator_write_node_t) {
|
2817
|
+
{
|
2818
|
+
.type = YP_NODE_OPERATOR_WRITE_NODE,
|
2819
|
+
.location = {
|
2820
|
+
.start = target->location.start,
|
2821
|
+
.end = value->location.end
|
2822
|
+
},
|
2823
|
+
},
|
2824
|
+
.target = target,
|
2825
|
+
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2826
|
+
.operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1),
|
2827
|
+
.value = value
|
2828
|
+
};
|
2829
|
+
|
2830
|
+
return node;
|
2831
|
+
}
|
2832
|
+
|
3191
2833
|
// Allocate a new OptionalParameterNode node.
|
3192
2834
|
static yp_optional_parameter_node_t *
|
3193
2835
|
yp_optional_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, const yp_token_t *operator, yp_node_t *value) {
|
@@ -3231,6 +2873,27 @@ yp_or_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *operat
|
|
3231
2873
|
return node;
|
3232
2874
|
}
|
3233
2875
|
|
2876
|
+
// Allocate and initialize a new OrWriteNode.
|
2877
|
+
static yp_or_write_node_t *
|
2878
|
+
yp_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) {
|
2879
|
+
yp_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_or_write_node_t);
|
2880
|
+
|
2881
|
+
*node = (yp_or_write_node_t) {
|
2882
|
+
{
|
2883
|
+
.type = YP_NODE_OR_WRITE_NODE,
|
2884
|
+
.location = {
|
2885
|
+
.start = target->location.start,
|
2886
|
+
.end = value->location.end
|
2887
|
+
},
|
2888
|
+
},
|
2889
|
+
.target = target,
|
2890
|
+
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
2891
|
+
.value = value
|
2892
|
+
};
|
2893
|
+
|
2894
|
+
return node;
|
2895
|
+
}
|
2896
|
+
|
3234
2897
|
// Allocate and initialize a new ParametersNode node.
|
3235
2898
|
static yp_parameters_node_t *
|
3236
2899
|
yp_parameters_node_create(yp_parser_t *parser) {
|
@@ -3343,7 +3006,7 @@ yp_program_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, yp_st
|
|
3343
3006
|
|
3344
3007
|
// Allocate and initialize new ParenthesesNode node.
|
3345
3008
|
static yp_parentheses_node_t *
|
3346
|
-
yp_parentheses_node_create(yp_parser_t *parser, const yp_token_t *opening, yp_node_t *
|
3009
|
+
yp_parentheses_node_create(yp_parser_t *parser, const yp_token_t *opening, yp_node_t *body, const yp_token_t *closing) {
|
3347
3010
|
yp_parentheses_node_t *node = YP_ALLOC_NODE(parser, yp_parentheses_node_t);
|
3348
3011
|
|
3349
3012
|
*node = (yp_parentheses_node_t) {
|
@@ -3354,7 +3017,7 @@ yp_parentheses_node_create(yp_parser_t *parser, const yp_token_t *opening, yp_no
|
|
3354
3017
|
.end = closing->end
|
3355
3018
|
}
|
3356
3019
|
},
|
3357
|
-
.
|
3020
|
+
.body = body,
|
3358
3021
|
.opening_loc = YP_LOCATION_TOKEN_VALUE(opening),
|
3359
3022
|
.closing_loc = YP_LOCATION_TOKEN_VALUE(closing)
|
3360
3023
|
};
|
@@ -3700,7 +3363,7 @@ yp_self_node_create(yp_parser_t *parser, const yp_token_t *token) {
|
|
3700
3363
|
|
3701
3364
|
// Allocate a new SingletonClassNode node.
|
3702
3365
|
static yp_singleton_class_node_t *
|
3703
|
-
yp_singleton_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, const yp_token_t *operator, yp_node_t *expression, yp_node_t *
|
3366
|
+
yp_singleton_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, const yp_token_t *operator, yp_node_t *expression, yp_node_t *body, const yp_token_t *end_keyword) {
|
3704
3367
|
yp_singleton_class_node_t *node = YP_ALLOC_NODE(parser, yp_singleton_class_node_t);
|
3705
3368
|
|
3706
3369
|
*node = (yp_singleton_class_node_t) {
|
@@ -3715,7 +3378,7 @@ yp_singleton_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *local
|
|
3715
3378
|
.class_keyword_loc = YP_LOCATION_TOKEN_VALUE(class_keyword),
|
3716
3379
|
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
|
3717
3380
|
.expression = expression,
|
3718
|
-
.
|
3381
|
+
.body = body,
|
3719
3382
|
.end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword)
|
3720
3383
|
};
|
3721
3384
|
|
@@ -3934,10 +3597,10 @@ yp_symbol_node_label_create(yp_parser_t *parser, const yp_token_t *token) {
|
|
3934
3597
|
yp_token_t label = { .type = YP_TOKEN_LABEL, .start = token->start, .end = token->end - 1 };
|
3935
3598
|
node = yp_symbol_node_create(parser, &opening, &label, &closing);
|
3936
3599
|
|
3937
|
-
|
3938
|
-
|
3600
|
+
assert((label.end - label.start) >= 0);
|
3601
|
+
yp_string_shared_init(&node->unescaped, label.start, label.end);
|
3939
3602
|
|
3940
|
-
yp_unescape_manipulate_string(parser,
|
3603
|
+
yp_unescape_manipulate_string(parser, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list);
|
3941
3604
|
break;
|
3942
3605
|
}
|
3943
3606
|
case YP_TOKEN_MISSING: {
|
@@ -5645,13 +5308,23 @@ parser_lex(yp_parser_t *parser) {
|
|
5645
5308
|
break;
|
5646
5309
|
case '\\':
|
5647
5310
|
if (peek_at(parser, 1) == '\n') {
|
5648
|
-
|
5649
|
-
|
5650
|
-
|
5651
|
-
|
5652
|
-
|
5653
|
-
|
5654
|
-
|
5311
|
+
if (parser->heredoc_end) {
|
5312
|
+
parser->current.end = parser->heredoc_end;
|
5313
|
+
parser->heredoc_end = NULL;
|
5314
|
+
} else {
|
5315
|
+
yp_newline_list_append(&parser->newline_list, parser->current.end + 1);
|
5316
|
+
parser->current.end += 2;
|
5317
|
+
space_seen = true;
|
5318
|
+
}
|
5319
|
+
} else if (peek_at(parser, 1) == '\r' && peek_at(parser, 2) == '\n') {
|
5320
|
+
if (parser->heredoc_end) {
|
5321
|
+
parser->current.end = parser->heredoc_end;
|
5322
|
+
parser->heredoc_end = NULL;
|
5323
|
+
} else {
|
5324
|
+
yp_newline_list_append(&parser->newline_list, parser->current.end + 2);
|
5325
|
+
parser->current.end += 3;
|
5326
|
+
space_seen = true;
|
5327
|
+
}
|
5655
5328
|
} else if (yp_char_is_inline_whitespace(*parser->current.end)) {
|
5656
5329
|
parser->current.end += 2;
|
5657
5330
|
} else {
|
@@ -6486,13 +6159,11 @@ parser_lex(yp_parser_t *parser) {
|
|
6486
6159
|
|
6487
6160
|
// % %= %i %I %q %Q %w %W
|
6488
6161
|
case '%': {
|
6489
|
-
//
|
6490
|
-
//
|
6491
|
-
//
|
6492
|
-
|
6493
|
-
|
6494
|
-
if (lex_state_beg_p(parser) && (parser->current.end >= parser->end)) {
|
6495
|
-
yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "unexpected end of input");
|
6162
|
+
// If there is no subsequent character then we have an invalid token. We're
|
6163
|
+
// going to say it's the percent operator because we don't want to move into the
|
6164
|
+
// string lex mode unnecessarily.
|
6165
|
+
if ((lex_state_beg_p(parser) || lex_state_arg_p(parser)) && (parser->current.end >= parser->end)) {
|
6166
|
+
yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected end of input");
|
6496
6167
|
LEX(YP_TOKEN_PERCENT);
|
6497
6168
|
}
|
6498
6169
|
|
@@ -6665,7 +6336,7 @@ parser_lex(yp_parser_t *parser) {
|
|
6665
6336
|
((parser->current.end - parser->current.start) == 7) &&
|
6666
6337
|
current_token_starts_line(parser) &&
|
6667
6338
|
(strncmp(parser->current.start, "__END__", 7) == 0) &&
|
6668
|
-
(*parser->current.end == '\n' || (*parser->current.end == '\r' && parser->current.end[1] == '\n'))
|
6339
|
+
(parser->current.end == parser->end || *parser->current.end == '\n' || (*parser->current.end == '\r' && parser->current.end[1] == '\n'))
|
6669
6340
|
) {
|
6670
6341
|
parser->current.end = parser->end;
|
6671
6342
|
parser->current.type = YP_TOKEN___END__;
|
@@ -7082,6 +6753,7 @@ parser_lex(yp_parser_t *parser) {
|
|
7082
6753
|
} else {
|
7083
6754
|
parser->current.start = parser->next_start;
|
7084
6755
|
parser->current.end = parser->next_start;
|
6756
|
+
parser->heredoc_end = NULL;
|
7085
6757
|
parser->next_start = NULL;
|
7086
6758
|
}
|
7087
6759
|
|
@@ -7203,11 +6875,16 @@ parser_lex(yp_parser_t *parser) {
|
|
7203
6875
|
break;
|
7204
6876
|
}
|
7205
6877
|
case '\\': {
|
7206
|
-
// If we hit
|
7207
|
-
//
|
7208
|
-
//
|
7209
|
-
|
6878
|
+
// If we hit an escape, then we need to skip past
|
6879
|
+
// however many characters the escape takes up. However
|
6880
|
+
// it's important that if \n or \r\n are escaped that we
|
6881
|
+
// stop looping before the newline and not after the
|
6882
|
+
// newline so that we can still potentially find the
|
6883
|
+
// terminator of the heredoc.
|
6884
|
+
if (breakpoint + 1 < parser->end && breakpoint[1] == '\n') {
|
7210
6885
|
breakpoint++;
|
6886
|
+
} else if (breakpoint + 2 < parser->end && breakpoint[1] == '\r' && breakpoint[2] == '\n') {
|
6887
|
+
breakpoint += 2;
|
7211
6888
|
} else {
|
7212
6889
|
yp_unescape_type_t unescape_type = (quote == YP_HEREDOC_QUOTE_SINGLE) ? YP_UNESCAPE_MINIMAL : YP_UNESCAPE_ALL;
|
7213
6890
|
size_t difference = yp_unescape_calculate_difference(breakpoint, parser->end, unescape_type, false, &parser->error_list);
|
@@ -7218,6 +6895,7 @@ parser_lex(yp_parser_t *parser) {
|
|
7218
6895
|
|
7219
6896
|
breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference));
|
7220
6897
|
}
|
6898
|
+
|
7221
6899
|
break;
|
7222
6900
|
}
|
7223
6901
|
case '#': {
|
@@ -7264,10 +6942,10 @@ static yp_regular_expression_node_t *
|
|
7264
6942
|
yp_regular_expression_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) {
|
7265
6943
|
yp_regular_expression_node_t *node = yp_regular_expression_node_create(parser, opening, content, closing);
|
7266
6944
|
|
7267
|
-
|
7268
|
-
|
6945
|
+
assert((content->end - content->start) >= 0);
|
6946
|
+
yp_string_shared_init(&node->unescaped, content->start, content->end);
|
7269
6947
|
|
7270
|
-
yp_unescape_manipulate_string(parser,
|
6948
|
+
yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type, &parser->error_list);
|
7271
6949
|
return node;
|
7272
6950
|
}
|
7273
6951
|
|
@@ -7275,10 +6953,10 @@ static yp_symbol_node_t *
|
|
7275
6953
|
yp_symbol_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) {
|
7276
6954
|
yp_symbol_node_t *node = yp_symbol_node_create(parser, opening, content, closing);
|
7277
6955
|
|
7278
|
-
|
7279
|
-
|
6956
|
+
assert((content->end - content->start) >= 0);
|
6957
|
+
yp_string_shared_init(&node->unescaped, content->start, content->end);
|
7280
6958
|
|
7281
|
-
yp_unescape_manipulate_string(parser,
|
6959
|
+
yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type, &parser->error_list);
|
7282
6960
|
return node;
|
7283
6961
|
}
|
7284
6962
|
|
@@ -7286,10 +6964,10 @@ static yp_string_node_t *
|
|
7286
6964
|
yp_string_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) {
|
7287
6965
|
yp_string_node_t *node = yp_string_node_create(parser, opening, content, closing);
|
7288
6966
|
|
7289
|
-
|
7290
|
-
|
6967
|
+
assert((content->end - content->start) >= 0);
|
6968
|
+
yp_string_shared_init(&node->unescaped, content->start, content->end);
|
7291
6969
|
|
7292
|
-
yp_unescape_manipulate_string(parser,
|
6970
|
+
yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type, &parser->error_list);
|
7293
6971
|
return node;
|
7294
6972
|
}
|
7295
6973
|
|
@@ -7297,10 +6975,10 @@ static yp_x_string_node_t *
|
|
7297
6975
|
yp_xstring_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing) {
|
7298
6976
|
yp_x_string_node_t *node = yp_xstring_node_create(parser, opening, content, closing);
|
7299
6977
|
|
7300
|
-
|
7301
|
-
|
6978
|
+
assert((content->end - content->start) >= 0);
|
6979
|
+
yp_string_shared_init(&node->unescaped, content->start, content->end);
|
7302
6980
|
|
7303
|
-
yp_unescape_manipulate_string(parser,
|
6981
|
+
yp_unescape_manipulate_string(parser, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list);
|
7304
6982
|
return node;
|
7305
6983
|
}
|
7306
6984
|
|
@@ -8999,7 +8677,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
|
|
8999
8677
|
}
|
9000
8678
|
|
9001
8679
|
yp_token_t end_keyword = not_provided(parser);
|
9002
|
-
yp_node_t *parent;
|
8680
|
+
yp_node_t *parent = NULL;
|
9003
8681
|
|
9004
8682
|
switch (context) {
|
9005
8683
|
case YP_CONTEXT_IF:
|
@@ -9009,7 +8687,6 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
|
|
9009
8687
|
parent = (yp_node_t *) yp_unless_node_create(parser, &keyword, predicate, statements);
|
9010
8688
|
break;
|
9011
8689
|
default:
|
9012
|
-
parent = NULL;
|
9013
8690
|
assert(false && "unreachable");
|
9014
8691
|
break;
|
9015
8692
|
}
|
@@ -9055,50 +8732,49 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
|
|
9055
8732
|
switch (context) {
|
9056
8733
|
case YP_CONTEXT_IF:
|
9057
8734
|
((yp_if_node_t *) current)->consequent = (yp_node_t *) else_node;
|
9058
|
-
// Recurse down if nodes setting the appropriate end location in
|
9059
|
-
// all cases.
|
9060
|
-
yp_node_t *recursing_node = parent;
|
9061
|
-
bool recursing = true;
|
9062
|
-
|
9063
|
-
while (recursing) {
|
9064
|
-
switch (YP_NODE_TYPE(recursing_node)) {
|
9065
|
-
case YP_NODE_IF_NODE:
|
9066
|
-
yp_if_node_end_keyword_loc_set((yp_if_node_t *) recursing_node, &parser->previous);
|
9067
|
-
recursing_node = ((yp_if_node_t *) recursing_node)->consequent;
|
9068
|
-
break;
|
9069
|
-
case YP_NODE_ELSE_NODE:
|
9070
|
-
yp_else_node_end_keyword_loc_set((yp_else_node_t *) recursing_node, &parser->previous);
|
9071
|
-
recursing = false;
|
9072
|
-
break;
|
9073
|
-
default: {
|
9074
|
-
recursing = false;
|
9075
|
-
break;
|
9076
|
-
}
|
9077
|
-
}
|
9078
|
-
}
|
9079
8735
|
break;
|
9080
8736
|
case YP_CONTEXT_UNLESS:
|
9081
8737
|
((yp_unless_node_t *) parent)->consequent = else_node;
|
9082
|
-
yp_unless_node_end_keyword_loc_set((yp_unless_node_t *) parent, &parser->previous);
|
9083
8738
|
break;
|
9084
8739
|
default:
|
9085
8740
|
assert(false && "unreachable");
|
9086
8741
|
break;
|
9087
8742
|
}
|
9088
8743
|
} else {
|
9089
|
-
expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close
|
8744
|
+
expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close conditional statement.");
|
8745
|
+
}
|
9090
8746
|
|
9091
|
-
|
9092
|
-
|
9093
|
-
|
9094
|
-
|
9095
|
-
|
9096
|
-
|
9097
|
-
|
9098
|
-
|
9099
|
-
|
9100
|
-
|
8747
|
+
// Set the appropriate end location for all of the nodes in the subtree.
|
8748
|
+
switch (context) {
|
8749
|
+
case YP_CONTEXT_IF: {
|
8750
|
+
yp_node_t *current = parent;
|
8751
|
+
bool recursing = true;
|
8752
|
+
|
8753
|
+
while (recursing) {
|
8754
|
+
switch (YP_NODE_TYPE(current)) {
|
8755
|
+
case YP_NODE_IF_NODE:
|
8756
|
+
yp_if_node_end_keyword_loc_set((yp_if_node_t *) current, &parser->previous);
|
8757
|
+
current = ((yp_if_node_t *) current)->consequent;
|
8758
|
+
recursing = current != NULL;
|
8759
|
+
break;
|
8760
|
+
case YP_NODE_ELSE_NODE:
|
8761
|
+
yp_else_node_end_keyword_loc_set((yp_else_node_t *) current, &parser->previous);
|
8762
|
+
recursing = false;
|
8763
|
+
break;
|
8764
|
+
default: {
|
8765
|
+
recursing = false;
|
8766
|
+
break;
|
8767
|
+
}
|
8768
|
+
}
|
8769
|
+
}
|
8770
|
+
break;
|
9101
8771
|
}
|
8772
|
+
case YP_CONTEXT_UNLESS:
|
8773
|
+
yp_unless_node_end_keyword_loc_set((yp_unless_node_t *) parent, &parser->previous);
|
8774
|
+
break;
|
8775
|
+
default:
|
8776
|
+
assert(false && "unreachable");
|
8777
|
+
break;
|
9102
8778
|
}
|
9103
8779
|
|
9104
8780
|
return parent;
|
@@ -9172,7 +8848,12 @@ parse_string_part(yp_parser_t *parser) {
|
|
9172
8848
|
yp_unescape_type_t unescape_type = YP_UNESCAPE_ALL;
|
9173
8849
|
|
9174
8850
|
if (parser->lex_modes.current->mode == YP_LEX_HEREDOC) {
|
9175
|
-
if (parser->lex_modes.current->as.heredoc.
|
8851
|
+
if (parser->lex_modes.current->as.heredoc.indent == YP_HEREDOC_INDENT_TILDE) {
|
8852
|
+
// If we're in a tilde heredoc, we want to unescape it later
|
8853
|
+
// because we don't want unescaped newlines to disappear
|
8854
|
+
// before we handle them in the dedent.
|
8855
|
+
unescape_type = YP_UNESCAPE_NONE;
|
8856
|
+
} else if (parser->lex_modes.current->as.heredoc.quote == YP_HEREDOC_QUOTE_SINGLE) {
|
9176
8857
|
unescape_type = YP_UNESCAPE_MINIMAL;
|
9177
8858
|
}
|
9178
8859
|
}
|
@@ -9545,14 +9226,30 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu
|
|
9545
9226
|
int common_whitespace;
|
9546
9227
|
if ((common_whitespace = parse_heredoc_common_whitespace(parser, nodes)) <= 0) return;
|
9547
9228
|
|
9548
|
-
//
|
9549
|
-
|
9550
|
-
|
9551
|
-
|
9229
|
+
// The next node should be dedented if it's the first node in the list or if
|
9230
|
+
// if follows a string node.
|
9231
|
+
bool dedent_next = true;
|
9232
|
+
|
9233
|
+
// Iterate over all nodes, and trim whitespace accordingly. We're going to
|
9234
|
+
// keep around two indices: a read and a write. If we end up trimming all of
|
9235
|
+
// the whitespace from a node, then we'll drop it from the list entirely.
|
9236
|
+
size_t write_index = 0;
|
9237
|
+
|
9238
|
+
for (size_t read_index = 0; read_index < nodes->size; read_index++) {
|
9239
|
+
yp_node_t *node = nodes->nodes[read_index];
|
9240
|
+
|
9241
|
+
// We're not manipulating child nodes that aren't strings. In this case
|
9242
|
+
// we'll skip past it and indicate that the subsequent node should not
|
9243
|
+
// be dedented.
|
9244
|
+
if (!YP_NODE_TYPE_P(node, YP_NODE_STRING_NODE)) {
|
9245
|
+
nodes->nodes[write_index++] = node;
|
9246
|
+
dedent_next = false;
|
9247
|
+
continue;
|
9248
|
+
}
|
9552
9249
|
|
9553
9250
|
// Get a reference to the string struct that is being held by the string
|
9554
9251
|
// node. This is the value we're going to actual manipulate.
|
9555
|
-
yp_string_t *string = &((yp_string_node_t *) node)->unescaped;
|
9252
|
+
yp_string_t *string = &(((yp_string_node_t *) node)->unescaped);
|
9556
9253
|
yp_string_ensure_owned(string);
|
9557
9254
|
|
9558
9255
|
// Now get the bounds of the existing string. We'll use this as a
|
@@ -9568,7 +9265,6 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu
|
|
9568
9265
|
// whitespace, so we'll maintain a pointer to the current position in the
|
9569
9266
|
// string that we're writing to.
|
9570
9267
|
char *dest_cursor = source_start;
|
9571
|
-
bool dedent_next = (index == 0) || YP_NODE_TYPE_P(nodes->nodes[index - 1], YP_NODE_STRING_NODE);
|
9572
9268
|
|
9573
9269
|
while (source_cursor < source_end) {
|
9574
9270
|
// If we need to dedent the next element within the heredoc or the next
|
@@ -9613,8 +9309,20 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu
|
|
9613
9309
|
dedent_next = true;
|
9614
9310
|
}
|
9615
9311
|
|
9616
|
-
|
9312
|
+
// We only want to write this node into the list if it has any content.
|
9313
|
+
if (dest_length == 0) {
|
9314
|
+
yp_node_destroy(parser, node);
|
9315
|
+
} else {
|
9316
|
+
string->length = dest_length;
|
9317
|
+
yp_unescape_manipulate_string(parser, string, (quote == YP_HEREDOC_QUOTE_SINGLE) ? YP_UNESCAPE_MINIMAL : YP_UNESCAPE_ALL, &parser->error_list);
|
9318
|
+
nodes->nodes[write_index++] = node;
|
9319
|
+
}
|
9320
|
+
|
9321
|
+
// We always dedent the next node if it follows a string node.
|
9322
|
+
dedent_next = true;
|
9617
9323
|
}
|
9324
|
+
|
9325
|
+
nodes->size = write_index;
|
9618
9326
|
}
|
9619
9327
|
|
9620
9328
|
static yp_node_t *
|
@@ -10673,12 +10381,15 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
|
|
10673
10381
|
|
10674
10382
|
lex_state_set(parser, YP_LEX_STATE_END);
|
10675
10383
|
expect(parser, YP_TOKEN_HEREDOC_END, "Expected a closing delimiter for heredoc.");
|
10384
|
+
|
10676
10385
|
if (quote == YP_HEREDOC_QUOTE_BACKTICK) {
|
10677
10386
|
assert(YP_NODE_TYPE_P(node, YP_NODE_INTERPOLATED_X_STRING_NODE));
|
10678
10387
|
yp_interpolated_xstring_node_closing_set(((yp_interpolated_x_string_node_t *) node), &parser->previous);
|
10388
|
+
node->location = ((yp_interpolated_x_string_node_t *) node)->opening_loc;
|
10679
10389
|
} else {
|
10680
10390
|
assert(YP_NODE_TYPE_P(node, YP_NODE_INTERPOLATED_STRING_NODE));
|
10681
10391
|
yp_interpolated_string_node_closing_set((yp_interpolated_string_node_t *) node, &parser->previous);
|
10392
|
+
node->location = ((yp_interpolated_string_node_t *) node)->opening_loc;
|
10682
10393
|
}
|
10683
10394
|
|
10684
10395
|
// If this is a heredoc that is indented with a ~, then we need to dedent
|
@@ -12394,14 +12105,19 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12394
12105
|
case YP_NODE_NUMBERED_REFERENCE_READ_NODE:
|
12395
12106
|
yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
|
12396
12107
|
/* fallthrough */
|
12397
|
-
case
|
12108
|
+
case YP_NODE_CLASS_VARIABLE_READ_NODE:
|
12109
|
+
case YP_NODE_CONSTANT_PATH_NODE:
|
12110
|
+
case YP_NODE_CONSTANT_READ_NODE:
|
12111
|
+
case YP_NODE_GLOBAL_VARIABLE_READ_NODE:
|
12112
|
+
case YP_NODE_INSTANCE_VARIABLE_READ_NODE:
|
12113
|
+
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12398
12114
|
parser_lex(parser);
|
12399
12115
|
|
12400
|
-
|
12401
|
-
|
12116
|
+
yp_token_t operator = not_provided(parser);
|
12117
|
+
node = parse_target(parser, node, &operator, NULL);
|
12402
12118
|
|
12403
|
-
|
12404
|
-
return
|
12119
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12120
|
+
return (yp_node_t *) yp_and_write_node_create(parser, node, &token, value);
|
12405
12121
|
}
|
12406
12122
|
case YP_NODE_CALL_NODE: {
|
12407
12123
|
yp_call_node_t *call_node = (yp_call_node_t *) node;
|
@@ -12419,12 +12135,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12419
12135
|
|
12420
12136
|
parser_lex(parser);
|
12421
12137
|
|
12422
|
-
|
12423
|
-
|
12424
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_and_write_node_create(parser, node, &token, value, constant_id);
|
12138
|
+
yp_token_t operator = not_provided(parser);
|
12139
|
+
node = parse_target(parser, node, &operator, NULL);
|
12425
12140
|
|
12426
|
-
|
12427
|
-
return
|
12141
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12142
|
+
return (yp_node_t *) yp_and_write_node_create(parser, node, &token, value);
|
12428
12143
|
}
|
12429
12144
|
|
12430
12145
|
parser_lex(parser);
|
@@ -12435,49 +12150,6 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12435
12150
|
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12436
12151
|
return (yp_node_t *) yp_call_operator_and_write_node_create(parser, (yp_call_node_t *) node, &token, value);
|
12437
12152
|
}
|
12438
|
-
case YP_NODE_CLASS_VARIABLE_READ_NODE: {
|
12439
|
-
parser_lex(parser);
|
12440
|
-
|
12441
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12442
|
-
yp_node_t *result = (yp_node_t *) yp_class_variable_operator_and_write_node_create(parser, node, &token, value);
|
12443
|
-
|
12444
|
-
yp_node_destroy(parser, node);
|
12445
|
-
return result;
|
12446
|
-
}
|
12447
|
-
case YP_NODE_CONSTANT_PATH_NODE: {
|
12448
|
-
parser_lex(parser);
|
12449
|
-
|
12450
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12451
|
-
return (yp_node_t *) yp_constant_path_operator_and_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
|
12452
|
-
}
|
12453
|
-
case YP_NODE_CONSTANT_READ_NODE: {
|
12454
|
-
parser_lex(parser);
|
12455
|
-
|
12456
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12457
|
-
yp_node_t *result = (yp_node_t *) yp_constant_operator_and_write_node_create(parser, node, &token, value);
|
12458
|
-
|
12459
|
-
yp_node_destroy(parser, node);
|
12460
|
-
return result;
|
12461
|
-
}
|
12462
|
-
case YP_NODE_INSTANCE_VARIABLE_READ_NODE: {
|
12463
|
-
parser_lex(parser);
|
12464
|
-
|
12465
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12466
|
-
yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_and_write_node_create(parser, node, &token, value);
|
12467
|
-
|
12468
|
-
yp_node_destroy(parser, node);
|
12469
|
-
return result;
|
12470
|
-
}
|
12471
|
-
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12472
|
-
parser_lex(parser);
|
12473
|
-
|
12474
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12475
|
-
yp_constant_id_t constant_id = ((yp_local_variable_read_node_t *) node)->constant_id;
|
12476
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_and_write_node_create(parser, node, &token, value, constant_id);
|
12477
|
-
|
12478
|
-
yp_node_destroy(parser, node);
|
12479
|
-
return result;
|
12480
|
-
}
|
12481
12153
|
case YP_NODE_MULTI_WRITE_NODE: {
|
12482
12154
|
parser_lex(parser);
|
12483
12155
|
yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `&&=' on a multi-write.");
|
@@ -12499,14 +12171,19 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12499
12171
|
case YP_NODE_NUMBERED_REFERENCE_READ_NODE:
|
12500
12172
|
yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
|
12501
12173
|
/* fallthrough */
|
12502
|
-
case
|
12174
|
+
case YP_NODE_CLASS_VARIABLE_READ_NODE:
|
12175
|
+
case YP_NODE_CONSTANT_PATH_NODE:
|
12176
|
+
case YP_NODE_CONSTANT_READ_NODE:
|
12177
|
+
case YP_NODE_GLOBAL_VARIABLE_READ_NODE:
|
12178
|
+
case YP_NODE_INSTANCE_VARIABLE_READ_NODE:
|
12179
|
+
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12503
12180
|
parser_lex(parser);
|
12504
12181
|
|
12505
|
-
|
12506
|
-
|
12182
|
+
yp_token_t operator = not_provided(parser);
|
12183
|
+
node = parse_target(parser, node, &operator, NULL);
|
12507
12184
|
|
12508
|
-
|
12509
|
-
return
|
12185
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12186
|
+
return (yp_node_t *) yp_or_write_node_create(parser, node, &token, value);
|
12510
12187
|
}
|
12511
12188
|
case YP_NODE_CALL_NODE: {
|
12512
12189
|
yp_call_node_t *call_node = (yp_call_node_t *) node;
|
@@ -12524,12 +12201,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12524
12201
|
|
12525
12202
|
parser_lex(parser);
|
12526
12203
|
|
12527
|
-
|
12528
|
-
|
12529
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_or_write_node_create(parser, node, &token, value, constant_id);
|
12204
|
+
yp_token_t operator = not_provided(parser);
|
12205
|
+
node = parse_target(parser, node, &operator, NULL);
|
12530
12206
|
|
12531
|
-
|
12532
|
-
return
|
12207
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12208
|
+
return (yp_node_t *) yp_or_write_node_create(parser, node, &token, value);
|
12533
12209
|
}
|
12534
12210
|
|
12535
12211
|
parser_lex(parser);
|
@@ -12540,49 +12216,6 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12540
12216
|
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12541
12217
|
return (yp_node_t *) yp_call_operator_or_write_node_create(parser, (yp_call_node_t *) node, &token, value);
|
12542
12218
|
}
|
12543
|
-
case YP_NODE_CLASS_VARIABLE_READ_NODE: {
|
12544
|
-
parser_lex(parser);
|
12545
|
-
|
12546
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12547
|
-
yp_node_t *result = (yp_node_t *) yp_class_variable_operator_or_write_node_create(parser, node, &token, value);
|
12548
|
-
|
12549
|
-
yp_node_destroy(parser, node);
|
12550
|
-
return result;
|
12551
|
-
}
|
12552
|
-
case YP_NODE_CONSTANT_PATH_NODE: {
|
12553
|
-
parser_lex(parser);
|
12554
|
-
|
12555
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12556
|
-
return (yp_node_t *) yp_constant_path_operator_or_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
|
12557
|
-
}
|
12558
|
-
case YP_NODE_CONSTANT_READ_NODE: {
|
12559
|
-
parser_lex(parser);
|
12560
|
-
|
12561
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12562
|
-
yp_node_t *result = (yp_node_t *) yp_constant_operator_or_write_node_create(parser, node, &token, value);
|
12563
|
-
|
12564
|
-
yp_node_destroy(parser, node);
|
12565
|
-
return result;
|
12566
|
-
}
|
12567
|
-
case YP_NODE_INSTANCE_VARIABLE_READ_NODE: {
|
12568
|
-
parser_lex(parser);
|
12569
|
-
|
12570
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12571
|
-
yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_or_write_node_create(parser, node, &token, value);
|
12572
|
-
|
12573
|
-
yp_node_destroy(parser, node);
|
12574
|
-
return result;
|
12575
|
-
}
|
12576
|
-
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12577
|
-
parser_lex(parser);
|
12578
|
-
|
12579
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
|
12580
|
-
yp_constant_id_t constant_id = ((yp_local_variable_read_node_t *) node)->constant_id;
|
12581
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_or_write_node_create(parser, node, &token, value, constant_id);
|
12582
|
-
|
12583
|
-
yp_node_destroy(parser, node);
|
12584
|
-
return result;
|
12585
|
-
}
|
12586
12219
|
case YP_NODE_MULTI_WRITE_NODE: {
|
12587
12220
|
parser_lex(parser);
|
12588
12221
|
yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `||=' on a multi-write.");
|
@@ -12614,14 +12247,19 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12614
12247
|
case YP_NODE_NUMBERED_REFERENCE_READ_NODE:
|
12615
12248
|
yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
|
12616
12249
|
/* fallthrough */
|
12617
|
-
case
|
12250
|
+
case YP_NODE_CLASS_VARIABLE_READ_NODE:
|
12251
|
+
case YP_NODE_CONSTANT_PATH_NODE:
|
12252
|
+
case YP_NODE_CONSTANT_READ_NODE:
|
12253
|
+
case YP_NODE_GLOBAL_VARIABLE_READ_NODE:
|
12254
|
+
case YP_NODE_INSTANCE_VARIABLE_READ_NODE:
|
12255
|
+
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12618
12256
|
parser_lex(parser);
|
12619
12257
|
|
12620
|
-
|
12621
|
-
|
12258
|
+
yp_token_t operator = not_provided(parser);
|
12259
|
+
node = parse_target(parser, node, &operator, NULL);
|
12622
12260
|
|
12623
|
-
|
12624
|
-
return
|
12261
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator");
|
12262
|
+
return (yp_node_t *) yp_operator_write_node_create(parser, node, &token, value);
|
12625
12263
|
}
|
12626
12264
|
case YP_NODE_CALL_NODE: {
|
12627
12265
|
yp_call_node_t *call_node = (yp_call_node_t *) node;
|
@@ -12639,12 +12277,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12639
12277
|
|
12640
12278
|
parser_lex(parser);
|
12641
12279
|
|
12642
|
-
|
12643
|
-
|
12644
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, constant_id);
|
12280
|
+
yp_token_t operator = not_provided(parser);
|
12281
|
+
node = parse_target(parser, node, &operator, NULL);
|
12645
12282
|
|
12646
|
-
|
12647
|
-
return
|
12283
|
+
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
|
12284
|
+
return (yp_node_t *) yp_operator_write_node_create(parser, node, &token, value);
|
12648
12285
|
}
|
12649
12286
|
|
12650
12287
|
yp_token_t operator = not_provided(parser);
|
@@ -12654,49 +12291,6 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
|
|
12654
12291
|
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12655
12292
|
return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value);
|
12656
12293
|
}
|
12657
|
-
case YP_NODE_CLASS_VARIABLE_READ_NODE: {
|
12658
|
-
parser_lex(parser);
|
12659
|
-
|
12660
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12661
|
-
yp_node_t *result = (yp_node_t *) yp_class_variable_operator_write_node_create(parser, node, &token, value);
|
12662
|
-
|
12663
|
-
yp_node_destroy(parser, node);
|
12664
|
-
return result;
|
12665
|
-
}
|
12666
|
-
case YP_NODE_CONSTANT_PATH_NODE: {
|
12667
|
-
parser_lex(parser);
|
12668
|
-
|
12669
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12670
|
-
return (yp_node_t *) yp_constant_path_operator_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
|
12671
|
-
}
|
12672
|
-
case YP_NODE_CONSTANT_READ_NODE: {
|
12673
|
-
parser_lex(parser);
|
12674
|
-
|
12675
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12676
|
-
yp_node_t *result = (yp_node_t *) yp_constant_operator_write_node_create(parser, node, &token, value);
|
12677
|
-
|
12678
|
-
yp_node_destroy(parser, node);
|
12679
|
-
return result;
|
12680
|
-
}
|
12681
|
-
case YP_NODE_INSTANCE_VARIABLE_READ_NODE: {
|
12682
|
-
parser_lex(parser);
|
12683
|
-
|
12684
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12685
|
-
yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_write_node_create(parser, node, &token, value);
|
12686
|
-
|
12687
|
-
yp_node_destroy(parser, node);
|
12688
|
-
return result;
|
12689
|
-
}
|
12690
|
-
case YP_NODE_LOCAL_VARIABLE_READ_NODE: {
|
12691
|
-
parser_lex(parser);
|
12692
|
-
|
12693
|
-
yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
|
12694
|
-
yp_constant_id_t constant_id = ((yp_local_variable_read_node_t *) node)->constant_id;
|
12695
|
-
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, constant_id);
|
12696
|
-
|
12697
|
-
yp_node_destroy(parser, node);
|
12698
|
-
return result;
|
12699
|
-
}
|
12700
12294
|
case YP_NODE_MULTI_WRITE_NODE: {
|
12701
12295
|
parser_lex(parser);
|
12702
12296
|
yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected operator.");
|
@@ -13190,6 +12784,8 @@ yp_parser_init(yp_parser_t *parser, const char *source, size_t size, const char
|
|
13190
12784
|
.enclosure_nesting = 0,
|
13191
12785
|
.lambda_enclosure_nesting = -1,
|
13192
12786
|
.brace_nesting = 0,
|
12787
|
+
.do_loop_stack = YP_STATE_STACK_EMPTY,
|
12788
|
+
.accepts_block_stack = YP_STATE_STACK_EMPTY,
|
13193
12789
|
.lex_modes = {
|
13194
12790
|
.index = 0,
|
13195
12791
|
.stack = {{ .mode = YP_LEX_DEFAULT }},
|
@@ -13201,6 +12797,9 @@ yp_parser_init(yp_parser_t *parser, const char *source, size_t size, const char
|
|
13201
12797
|
.current = { .type = YP_TOKEN_EOF, .start = source, .end = source },
|
13202
12798
|
.next_start = NULL,
|
13203
12799
|
.heredoc_end = NULL,
|
12800
|
+
.comment_list = YP_LIST_EMPTY,
|
12801
|
+
.warning_list = YP_LIST_EMPTY,
|
12802
|
+
.error_list = YP_LIST_EMPTY,
|
13204
12803
|
.current_scope = NULL,
|
13205
12804
|
.current_context = NULL,
|
13206
12805
|
.recovering = false,
|
@@ -13213,16 +12812,12 @@ yp_parser_init(yp_parser_t *parser, const char *source, size_t size, const char
|
|
13213
12812
|
.pattern_matching_newlines = false,
|
13214
12813
|
.in_keyword_arg = false,
|
13215
12814
|
.filepath_string = filepath_string,
|
12815
|
+
.constant_pool = YP_CONSTANT_POOL_EMPTY,
|
12816
|
+
.newline_list = YP_NEWLINE_LIST_EMPTY
|
13216
12817
|
};
|
13217
12818
|
|
13218
|
-
yp_state_stack_init(&parser->do_loop_stack);
|
13219
|
-
yp_state_stack_init(&parser->accepts_block_stack);
|
13220
12819
|
yp_accepts_block_stack_push(parser, true);
|
13221
12820
|
|
13222
|
-
yp_list_init(&parser->warning_list);
|
13223
|
-
yp_list_init(&parser->error_list);
|
13224
|
-
yp_list_init(&parser->comment_list);
|
13225
|
-
|
13226
12821
|
// Initialize the constant pool. We're going to completely guess as to the
|
13227
12822
|
// number of constants that we'll need based on the size of the input. The
|
13228
12823
|
// ratio we chose here is actually less arbitrary than you might think.
|