yarp 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|