@@ -22,14 +22,18 @@ pm_version(void) {
2222/* Helpful AST-related macros */
2323/******************************************************************************/
2424
25+ #define U32(value_) ((uint32_t) (value_))
26+
2527#define FL PM_NODE_FLAGS
2628#define UP PM_NODE_UPCAST
2729
2830#define PM_TOKEN_START(token_) ((token_)->start)
2931#define PM_TOKEN_END(token_) ((token_)->end)
32+ #define PM_TOKEN_LENGTH(token_) U32(PM_TOKEN_END(token_) - PM_TOKEN_START(token_))
3033
3134#define PM_NODE_START(node_) (UP(node_)->location.start)
3235#define PM_NODE_END(node_) (UP(node_)->location.end)
36+ #define PM_NODE_LENGTH(node_) U32(PM_NODE_END(node_) - PM_NODE_START(node_))
3337
3438#define PM_LOCATION_TOKEN_VALUE(token_) ((pm_location_t) { .start = PM_TOKEN_START(token_), .end = PM_TOKEN_END(token_) })
3539
@@ -434,6 +438,12 @@ pm_parser_err(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_
434438#define PM_PARSER_ERR_FORMAT(parser_, start_, end_, diag_id_, ...) \
435439 pm_diagnostic_list_append_format(&(parser_)->error_list, (uint32_t) ((start_) - (parser_)->start), (uint32_t) ((end_) - (start_)), diag_id_, __VA_ARGS__)
436440
441+ /**
442+ * Append an error to the list of errors on the parser using the given slice.
443+ */
444+ #define PM_PARSER_ERR_FORMAT_SLICE(parser_, start_, length_, diag_id_, ...) \
445+ pm_diagnostic_list_append_format(&(parser_)->error_list, (start_), (length_), diag_id_, __VA_ARGS__)
446+
437447/**
438448 * Append an error to the list of errors on the parser using the location of the
439449 * current token.
@@ -5238,18 +5248,23 @@ pm_token_is_it(const uint8_t *start, const uint8_t *end) {
52385248 * are of the form /^_\d$/).
52395249 */
52405250static inline bool
5241- pm_token_is_numbered_parameter(const uint8_t *start, const uint8_t *end) {
5242- return (end - start == 2) && (start[0] == '_') && (start[1] != '0') && (pm_char_is_decimal_digit(start[1]));
5251+ pm_token_is_numbered_parameter(const pm_parser_t *parser, uint32_t start, uint32_t length) {
5252+ return (
5253+ (length == 2) &&
5254+ (parser->start[start] == '_') &&
5255+ (parser->start[start + 1] != '0') &&
5256+ pm_char_is_decimal_digit(parser->start[start + 1])
5257+ );
52435258}
52445259
52455260/**
52465261 * Ensure the given bounds do not comprise a numbered parameter. If they do, add
52475262 * an appropriate error message to the parser.
52485263 */
52495264static inline void
5250- pm_refute_numbered_parameter(pm_parser_t *parser, const uint8_t * start, const uint8_t *end ) {
5251- if (pm_token_is_numbered_parameter(start, end )) {
5252- PM_PARSER_ERR_FORMAT (parser, start, end , PM_ERR_PARAMETER_NUMBERED_RESERVED, start);
5265+ pm_refute_numbered_parameter(pm_parser_t *parser, uint32_t start, uint32_t length ) {
5266+ if (pm_token_is_numbered_parameter(parser, start, length )) {
5267+ PM_PARSER_ERR_FORMAT_SLICE (parser, start, length , PM_ERR_PARAMETER_NUMBERED_RESERVED, parser->start + start);
52535268 }
52545269}
52555270
@@ -5259,7 +5274,7 @@ pm_refute_numbered_parameter(pm_parser_t *parser, const uint8_t *start, const ui
52595274 */
52605275static pm_local_variable_target_node_t *
52615276pm_local_variable_target_node_create(pm_parser_t *parser, const pm_location_t *location, pm_constant_id_t name, uint32_t depth) {
5262- pm_refute_numbered_parameter(parser, location->start, location->end );
5277+ pm_refute_numbered_parameter(parser, U32( location->start - parser->start), PM_TOKEN_LENGTH(location) );
52635278 pm_local_variable_target_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_target_node_t);
52645279
52655280 *node = (pm_local_variable_target_node_t) {
@@ -7145,7 +7160,7 @@ static bool
71457160pm_parser_parameter_name_check(pm_parser_t *parser, const pm_token_t *name) {
71467161 // We want to check whether the parameter name is a numbered parameter or
71477162 // not.
7148- pm_refute_numbered_parameter(parser, name->start, name->end );
7163+ pm_refute_numbered_parameter(parser, (uint32_t) ( name->start - parser->start), PM_TOKEN_LENGTH(name) );
71497164
71507165 // Otherwise we'll fetch the constant id for the parameter name and check
71517166 // whether it's already in the current scope.
@@ -11047,7 +11062,7 @@ parser_lex(pm_parser_t *parser) {
1104711062 !(last_state & (PM_LEX_STATE_DOT | PM_LEX_STATE_FNAME)) &&
1104811063 (type == PM_TOKEN_IDENTIFIER) &&
1104911064 ((pm_parser_local_depth(parser, &parser->current) != -1) ||
11050- pm_token_is_numbered_parameter(parser->current.start, parser->current.end ))
11065+ pm_token_is_numbered_parameter(parser, U32(parser ->current.start - parser->start), PM_TOKEN_LENGTH(& parser->current) ))
1105111066 ) {
1105211067 lex_state_set(parser, PM_LEX_STATE_END | PM_LEX_STATE_LABEL);
1105311068 }
@@ -12667,7 +12682,7 @@ parse_target(pm_parser_t *parser, pm_node_t *target, bool multiple, bool splat_p
1266712682 target->type = PM_GLOBAL_VARIABLE_TARGET_NODE;
1266812683 return target;
1266912684 case PM_LOCAL_VARIABLE_READ_NODE: {
12670- if (pm_token_is_numbered_parameter(target->location.start, target->location.end )) {
12685+ if (pm_token_is_numbered_parameter(parser, U32( target->location.start - parser->start), PM_NODE_LENGTH(target) )) {
1267112686 PM_PARSER_ERR_FORMAT(parser, target->location.start, target->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, target->location.start);
1267212687 pm_node_unreference(parser, target);
1267312688 }
@@ -12861,7 +12876,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1286112876 uint32_t depth = local_read->depth;
1286212877 pm_scope_t *scope = pm_parser_scope_find(parser, depth);
1286312878
12864- if (pm_token_is_numbered_parameter(target->location.start, target->location.end )) {
12879+ if (pm_token_is_numbered_parameter(parser, U32( target->location.start - parser->start), PM_NODE_LENGTH(target) )) {
1286512880 pm_diagnostic_id_t diag_id = (scope->parameters & PM_SCOPE_PARAMETERS_NUMBERED_FOUND) ? PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED : PM_ERR_PARAMETER_NUMBERED_RESERVED;
1286612881 PM_PARSER_ERR_FORMAT(parser, target->location.start, target->location.end, diag_id, target->location.start);
1286712882 pm_node_unreference(parser, target);
@@ -12929,13 +12944,13 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1292912944 .end = parser->start + call->message_loc.start + call->message_loc.length
1293012945 };
1293112946
12947+ pm_refute_numbered_parameter(parser, call->message_loc.start, call->message_loc.length);
1293212948 pm_parser_local_add_slice(parser, &call->message_loc, 0);
1293312949 pm_node_destroy(parser, target);
1293412950
1293512951 pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, message.start, message.end);
1293612952 target = UP(pm_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator));
1293712953
12938- pm_refute_numbered_parameter(parser, message.start, message.end);
1293912954 return target;
1294012955 }
1294112956
@@ -14630,7 +14645,7 @@ parse_blocklike_parameters(pm_parser_t *parser, pm_node_t *parameters, const pm_
1463014645 pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK);
1463114646 } else if (parser->current_scope->parameters & PM_SCOPE_PARAMETERS_NUMBERED_INNER) {
1463214647 pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK);
14633- } else if (pm_token_is_numbered_parameter(node->location.start, node->location.end )) {
14648+ } else if (pm_token_is_numbered_parameter(parser, U32( node->location.start - parser->start), PM_NODE_LENGTH(node) )) {
1463414649 numbered_parameter = MAX(numbered_parameter, (uint8_t) (node->location.start[1] - '0'));
1463514650 } else {
1463614651 assert(false && "unreachable");
@@ -15666,7 +15681,7 @@ static pm_node_t *
1566615681parse_variable(pm_parser_t *parser) {
1566715682 pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &parser->previous);
1566815683 int depth;
15669- bool is_numbered_param = pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end );
15684+ bool is_numbered_param = pm_token_is_numbered_parameter(parser, U32(parser ->previous.start - parser->start), PM_TOKEN_LENGTH(& parser->previous) );
1567015685
1567115686 if (!is_numbered_param && ((depth = pm_parser_local_depth_constant_id(parser, name_id)) != -1)) {
1567215687 return UP(pm_local_variable_read_node_create_constant_id(parser, &parser->previous, name_id, (uint32_t) depth, false));
@@ -15736,7 +15751,7 @@ parse_method_definition_name(pm_parser_t *parser) {
1573615751 parser_lex(parser);
1573715752 return parser->previous;
1573815753 case PM_TOKEN_IDENTIFIER:
15739- pm_refute_numbered_parameter(parser, parser->current.start, parser->current.end );
15754+ pm_refute_numbered_parameter(parser, U32( parser->current.start - parser->start), PM_TOKEN_LENGTH(& parser->current) );
1574015755 parser_lex(parser);
1574115756 return parser->previous;
1574215757 case PM_CASE_OPERATOR:
@@ -17866,7 +17881,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1786617881 // purposes of warnings.
1786717882 assert(PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_READ_NODE));
1786817883
17869- if (pm_token_is_numbered_parameter(identifier.start, identifier.end )) {
17884+ if (pm_token_is_numbered_parameter(parser, U32( identifier.start - parser->start), PM_TOKEN_LENGTH(& identifier) )) {
1787017885 pm_node_unreference(parser, node);
1787117886 } else {
1787217887 pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
@@ -18596,7 +18611,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1859618611 operator = parser->previous;
1859718612 name = parse_method_definition_name(parser);
1859818613 } else {
18599- pm_refute_numbered_parameter(parser, parser->previous.start, parser->previous.end );
18614+ pm_refute_numbered_parameter(parser, U32( parser->previous.start - parser->start), PM_TOKEN_LENGTH(& parser->previous) );
1860018615 pm_parser_scope_push(parser, true);
1860118616
1860218617 name = parser->previous;
@@ -20528,7 +20543,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2052820543 return result;
2052920544 }
2053020545 case PM_LOCAL_VARIABLE_READ_NODE: {
20531- if (pm_token_is_numbered_parameter(node->location.start, node->location.end )) {
20546+ if (pm_token_is_numbered_parameter(parser, U32( node->location.start - parser->start), PM_NODE_LENGTH(node) )) {
2053220547 PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start);
2053320548 pm_node_unreference(parser, node);
2053420549 }
@@ -20549,12 +20564,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2054920564 // receiver that could have been a local variable) then we
2055020565 // will transform it into a local variable write.
2055120566 if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) {
20552- pm_location_t message_loc = {
20553- .start = parser->start + cast->message_loc.start,
20554- .end = parser->start + cast->message_loc.start + cast->message_loc.length
20555- };
20556-
20557- pm_refute_numbered_parameter(parser, message_loc.start, message_loc.end);
20567+ pm_refute_numbered_parameter(parser, cast->message_loc.start, cast->message_loc.length);
2055820568 pm_constant_id_t constant_id = pm_parser_local_add_slice(parser, &cast->message_loc, 1);
2055920569 parser_lex(parser);
2056020570
@@ -20665,7 +20675,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2066520675 return result;
2066620676 }
2066720677 case PM_LOCAL_VARIABLE_READ_NODE: {
20668- if (pm_token_is_numbered_parameter(node->location.start, node->location.end )) {
20678+ if (pm_token_is_numbered_parameter(parser, U32( node->location.start - parser->start), PM_NODE_LENGTH(node) )) {
2066920679 PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start);
2067020680 pm_node_unreference(parser, node);
2067120681 }
@@ -20686,12 +20696,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2068620696 // receiver that could have been a local variable) then we
2068720697 // will transform it into a local variable write.
2068820698 if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) {
20689- pm_location_t message_loc = (pm_location_t) {
20690- .start = parser->start + cast->message_loc.start,
20691- .end = parser->start + cast->message_loc.start + cast->message_loc.length
20692- };
20693-
20694- pm_refute_numbered_parameter(parser, message_loc.start, message_loc.end);
20699+ pm_refute_numbered_parameter(parser, cast->message_loc.start, cast->message_loc.length);
2069520700 pm_constant_id_t constant_id = pm_parser_local_add_slice(parser, &cast->message_loc, 1);
2069620701 parser_lex(parser);
2069720702
@@ -20812,7 +20817,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2081220817 return result;
2081320818 }
2081420819 case PM_LOCAL_VARIABLE_READ_NODE: {
20815- if (pm_token_is_numbered_parameter(node->location.start, node->location.end )) {
20820+ if (pm_token_is_numbered_parameter(parser, U32( node->location.start - parser->start), PM_NODE_LENGTH(node) )) {
2081620821 PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start);
2081720822 pm_node_unreference(parser, node);
2081820823 }
@@ -20834,12 +20839,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2083420839 // receiver that could have been a local variable) then we
2083520840 // will transform it into a local variable write.
2083620841 if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) {
20837- pm_location_t message_loc = (pm_location_t) {
20838- .start = parser->start + cast->message_loc.start,
20839- .end = parser->start + cast->message_loc.start + cast->message_loc.length
20840- };
20841-
20842- pm_refute_numbered_parameter(parser, message_loc.start, message_loc.end);
20842+ pm_refute_numbered_parameter(parser, cast->message_loc.start, cast->message_loc.length);
2084320843 pm_constant_id_t constant_id = pm_parser_local_add_slice(parser, &cast->message_loc, 1);
2084420844 pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
2084520845 pm_node_t *result = UP(pm_local_variable_operator_write_node_create(parser, UP(cast), &token, value, constant_id, 0));
0 commit comments