[ruby/yarp] Add a value to numbered references

https://github.com/ruby/yarp/commit/5d9b048971
This commit is contained in:
Kevin Newton 2023-08-30 17:21:50 -04:00 коммит произвёл git
Родитель 36786cc381
Коммит 4aa98b2760
6 изменённых файлов: 41 добавлений и 4 удалений

Просмотреть файл

@ -57,7 +57,7 @@ ProgramNode(0...299)(
[StringNode(146...147)(nil, (146...147), nil, "a"),
EmbeddedVariableNode(147...150)(
(147...148),
NumberedReferenceReadNode(148...150)()
NumberedReferenceReadNode(148...150)(1)
)],
(150...151)
),

Просмотреть файл

@ -5,7 +5,7 @@ ProgramNode(0...66)(
InstanceVariableReadNode(2...4)(:@a),
ClassVariableReadNode(5...8)(:@@a),
GlobalVariableReadNode(9...11)(),
NumberedReferenceReadNode(12...14)(),
NumberedReferenceReadNode(12...14)(1),
BackReferenceReadNode(15...17)(),
ConstantReadNode(18...23)(),
ConstantPathNode(24...37)(

Просмотреть файл

@ -1,4 +1,4 @@
ProgramNode(0...3)(
[],
StatementsNode(0...3)([NumberedReferenceReadNode(0...3)()])
StatementsNode(0...3)([NumberedReferenceReadNode(0...3)(10)])
)

Просмотреть файл

@ -1703,6 +1703,9 @@ nodes:
^^^^^
end
- name: NumberedReferenceReadNode
fields:
- name: number
type: uint32
comment: |
Represents reading a numbered reference to a capture in the previous match.

Просмотреть файл

@ -613,6 +613,38 @@ yp_scope_node_init(yp_node_t *node, yp_scope_node_t *scope) {
/* Node creation functions */
/******************************************************************************/
// Parse the decimal number represented by the range of bytes. returns
// UINT32_MAX if the number fails to parse. This function assumes that the range
// of bytes has already been validated to contain only decimal digits.
static uint32_t
parse_decimal_number(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) {
ptrdiff_t diff = end - start;
assert(diff > 0 && ((unsigned long) diff < SIZE_MAX));
size_t length = (size_t) diff;
char *digits = calloc(length + 1, sizeof(char));
memcpy(digits, start, length);
digits[length] = '\0';
char *endptr;
errno = 0;
unsigned long value = strtoul(digits, &endptr, 10);
if ((digits == endptr) || (*endptr != '\0') || (errno == ERANGE)) {
yp_diagnostic_list_append(&parser->error_list, start, end, "invalid decimal number");
value = UINT32_MAX;
}
free(digits);
if (value > UINT32_MAX) {
yp_diagnostic_list_append(&parser->error_list, start, end, "invalid decimal number");
value = UINT32_MAX;
}
return (uint32_t) value;
}
// Parse out the options for a regular expression.
static inline yp_node_flags_t
yp_regular_expression_flags_create(const yp_token_t *closing) {
@ -3289,7 +3321,8 @@ yp_numbered_reference_read_node_create(yp_parser_t *parser, const yp_token_t *na
{
.type = YP_NODE_NUMBERED_REFERENCE_READ_NODE,
.location = YP_LOCATION_TOKEN_VALUE(name),
}
},
.number = parse_decimal_number(parser, name->start + 1, name->end)
};
return node;

Просмотреть файл

@ -16,6 +16,7 @@
#include "yarp/version.h"
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>