summaryrefslogtreecommitdiff
path: root/yarp
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-09-11 12:05:14 -0400
committergit <svn-admin@ruby-lang.org>2023-09-11 21:49:51 +0000
commit8953fc774c542a8bf3c9a2be39bcbd1d5341e3a8 (patch)
treea674097c759c25b9d3b666625d3a23040ce148ab /yarp
parentb7ffa74d583100bb41b43bfdc8d883aea2e1fcad (diff)
[ruby/yarp] Provide a flag for the integer base
https://github.com/ruby/yarp/commit/45dd046b83
Diffstat (limited to 'yarp')
-rw-r--r--yarp/config.yml14
-rw-r--r--yarp/parser.h6
-rw-r--r--yarp/templates/ext/yarp/api_node.c.erb2
-rw-r--r--yarp/yarp.c54
4 files changed, 58 insertions, 18 deletions
diff --git a/yarp/config.yml b/yarp/config.yml
index ae63472bd7..257a5bfc25 100644
--- a/yarp/config.yml
+++ b/yarp/config.yml
@@ -333,6 +333,16 @@ flags:
comment: "&. operator"
- name: VARIABLE_CALL
comment: "a call that could have been a local variable"
+ - name: IntegerBaseFlags
+ values:
+ - name: BINARY
+ comment: "0b prefix"
+ - name: OCTAL
+ comment: "0o or 0 prefix"
+ - name: DECIMAL
+ comment: "0d or no prefix"
+ - name: HEXADECIMAL
+ comment: "0x prefix"
- name: LoopFlags
values:
- name: BEGIN_MODIFIER
@@ -1483,6 +1493,10 @@ nodes:
@foo = 1
^^^^^^^^
- name: IntegerNode
+ fields:
+ - name: flags
+ type: flags
+ kind: IntegerBaseFlags
comment: |
Represents an integer number literal.
diff --git a/yarp/parser.h b/yarp/parser.h
index 0ae01f78da..486faa2f40 100644
--- a/yarp/parser.h
+++ b/yarp/parser.h
@@ -384,6 +384,12 @@ struct yp_parser {
// This is the list of newline offsets in the source file.
yp_newline_list_t newline_list;
+
+ // We want to add a flag to integer nodes that indicates their base. We only
+ // want to parse these once, but we don't have space on the token itself to
+ // communicate this information. So we store it here and pass it through
+ // when we find tokens that we need it for.
+ yp_node_flags_t integer_base;
};
#endif // YARP_PARSER_H
diff --git a/yarp/templates/ext/yarp/api_node.c.erb b/yarp/templates/ext/yarp/api_node.c.erb
index a9f5115d7f..a0d528996a 100644
--- a/yarp/templates/ext/yarp/api_node.c.erb
+++ b/yarp/templates/ext/yarp/api_node.c.erb
@@ -135,7 +135,7 @@ yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) {
<%- nodes.each do |node| -%>
#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
case <%= node.type %>: {
- <%- if node.fields.any? { |field| ![YARP::NodeField, YARP::OptionalNodeField].include?(field.class) } -%>
+ <%- if node.fields.any? { |field| ![YARP::NodeField, YARP::OptionalNodeField, YARP::FlagsField].include?(field.class) } -%>
yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node;
<%- end -%>
VALUE argv[<%= node.fields.length + 1 %>];
diff --git a/yarp/yarp.c b/yarp/yarp.c
index b2fecf9c0a..730bf8274b 100644
--- a/yarp/yarp.c
+++ b/yarp/yarp.c
@@ -2697,16 +2697,22 @@ yp_else_node_end_keyword_loc_set(yp_else_node_t *node, const yp_token_t *keyword
// Allocate and initialize a new IntegerNode node.
static yp_integer_node_t *
-yp_integer_node_create(yp_parser_t *parser, const yp_token_t *token) {
+yp_integer_node_create(yp_parser_t *parser, yp_node_flags_t base, const yp_token_t *token) {
assert(token->type == YP_TOKEN_INTEGER);
yp_integer_node_t *node = YP_ALLOC_NODE(parser, yp_integer_node_t);
- *node = (yp_integer_node_t) {{ .type = YP_INTEGER_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }};
+
+ *node = (yp_integer_node_t) {{
+ .type = YP_INTEGER_NODE,
+ .flags = base,
+ .location = YP_LOCATION_TOKEN_VALUE(token)
+ }};
+
return node;
}
// Allocate and initialize a new IntegerNode node from an INTEGER_IMAGINARY token.
static yp_imaginary_node_t *
-yp_integer_node_imaginary_create(yp_parser_t *parser, const yp_token_t *token) {
+yp_integer_node_imaginary_create(yp_parser_t *parser, yp_node_flags_t base, const yp_token_t *token) {
assert(token->type == YP_TOKEN_INTEGER_IMAGINARY);
yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t);
@@ -2715,7 +2721,7 @@ yp_integer_node_imaginary_create(yp_parser_t *parser, const yp_token_t *token) {
.type = YP_IMAGINARY_NODE,
.location = YP_LOCATION_TOKEN_VALUE(token)
},
- .numeric = (yp_node_t *) yp_integer_node_create(parser, &((yp_token_t) {
+ .numeric = (yp_node_t *) yp_integer_node_create(parser, base, &((yp_token_t) {
.type = YP_TOKEN_INTEGER,
.start = token->start,
.end = token->end - 1
@@ -2727,7 +2733,7 @@ yp_integer_node_imaginary_create(yp_parser_t *parser, const yp_token_t *token) {
// Allocate and initialize a new IntegerNode node from an INTEGER_RATIONAL token.
static yp_rational_node_t *
-yp_integer_node_rational_create(yp_parser_t *parser, const yp_token_t *token) {
+yp_integer_node_rational_create(yp_parser_t *parser, yp_node_flags_t base, const yp_token_t *token) {
assert(token->type == YP_TOKEN_INTEGER_RATIONAL);
yp_rational_node_t *node = YP_ALLOC_NODE(parser, yp_rational_node_t);
@@ -2736,7 +2742,7 @@ yp_integer_node_rational_create(yp_parser_t *parser, const yp_token_t *token) {
.type = YP_RATIONAL_NODE,
.location = YP_LOCATION_TOKEN_VALUE(token)
},
- .numeric = (yp_node_t *) yp_integer_node_create(parser, &((yp_token_t) {
+ .numeric = (yp_node_t *) yp_integer_node_create(parser, base, &((yp_token_t) {
.type = YP_TOKEN_INTEGER,
.start = token->start,
.end = token->end - 1
@@ -2748,7 +2754,7 @@ yp_integer_node_rational_create(yp_parser_t *parser, const yp_token_t *token) {
// Allocate and initialize a new IntegerNode node from an INTEGER_RATIONAL_IMAGINARY token.
static yp_imaginary_node_t *
-yp_integer_node_rational_imaginary_create(yp_parser_t *parser, const yp_token_t *token) {
+yp_integer_node_rational_imaginary_create(yp_parser_t *parser, yp_node_flags_t base, const yp_token_t *token) {
assert(token->type == YP_TOKEN_INTEGER_RATIONAL_IMAGINARY);
yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t);
@@ -2757,7 +2763,7 @@ yp_integer_node_rational_imaginary_create(yp_parser_t *parser, const yp_token_t
.type = YP_IMAGINARY_NODE,
.location = YP_LOCATION_TOKEN_VALUE(token)
},
- .numeric = (yp_node_t *) yp_integer_node_rational_create(parser, &((yp_token_t) {
+ .numeric = (yp_node_t *) yp_integer_node_rational_create(parser, base, &((yp_token_t) {
.type = YP_TOKEN_INTEGER_RATIONAL,
.start = token->start,
.end = token->end - 1
@@ -5217,6 +5223,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_BINARY);
}
+ parser->integer_base = YP_INTEGER_BASE_FLAGS_BINARY;
break;
// 0o1111 is an octal number
@@ -5229,6 +5236,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_OCTAL);
}
+ parser->integer_base = YP_INTEGER_BASE_FLAGS_OCTAL;
break;
// 01111 is an octal number
@@ -5242,6 +5250,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
case '6':
case '7':
parser->current.end += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end);
+ parser->integer_base = YP_INTEGER_BASE_FLAGS_OCTAL;
break;
// 0x1111 is a hexadecimal number
@@ -5254,6 +5263,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_HEXADECIMAL);
}
+ parser->integer_base = YP_INTEGER_BASE_FLAGS_HEXADECIMAL;
break;
// 0.xxx is a float
@@ -5290,6 +5300,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
static yp_token_type_t
lex_numeric(yp_parser_t *parser) {
yp_token_type_t type = YP_TOKEN_INTEGER;
+ parser->integer_base = YP_INTEGER_BASE_FLAGS_DECIMAL;
if (parser->current.end < parser->end) {
type = lex_numeric_prefix(parser);
@@ -11296,18 +11307,26 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
return node;
}
- case YP_TOKEN_INTEGER:
+ case YP_TOKEN_INTEGER: {
+ yp_node_flags_t base = parser->integer_base;
parser_lex(parser);
- return (yp_node_t *) yp_integer_node_create(parser, &parser->previous);
- case YP_TOKEN_INTEGER_IMAGINARY:
+ return (yp_node_t *) yp_integer_node_create(parser, base, &parser->previous);
+ }
+ case YP_TOKEN_INTEGER_IMAGINARY: {
+ yp_node_flags_t base = parser->integer_base;
parser_lex(parser);
- return (yp_node_t *) yp_integer_node_imaginary_create(parser, &parser->previous);
- case YP_TOKEN_INTEGER_RATIONAL:
+ return (yp_node_t *) yp_integer_node_imaginary_create(parser, base, &parser->previous);
+ }
+ case YP_TOKEN_INTEGER_RATIONAL: {
+ yp_node_flags_t base = parser->integer_base;
parser_lex(parser);
- return (yp_node_t *) yp_integer_node_rational_create(parser, &parser->previous);
- case YP_TOKEN_INTEGER_RATIONAL_IMAGINARY:
+ return (yp_node_t *) yp_integer_node_rational_create(parser, base, &parser->previous);
+ }
+ case YP_TOKEN_INTEGER_RATIONAL_IMAGINARY: {
+ yp_node_flags_t base = parser->integer_base;
parser_lex(parser);
- return (yp_node_t *) yp_integer_node_rational_imaginary_create(parser, &parser->previous);
+ return (yp_node_t *) yp_integer_node_rational_imaginary_create(parser, base, &parser->previous);
+ }
case YP_TOKEN_KEYWORD___ENCODING__:
parser_lex(parser);
return (yp_node_t *) yp_source_encoding_node_create(parser, &parser->previous);
@@ -13840,7 +13859,8 @@ yp_parser_init(yp_parser_t *parser, const uint8_t *source, size_t size, const ch
.in_keyword_arg = false,
.filepath_string = filepath_string,
.constant_pool = YP_CONSTANT_POOL_EMPTY,
- .newline_list = YP_NEWLINE_LIST_EMPTY
+ .newline_list = YP_NEWLINE_LIST_EMPTY,
+ .integer_base = 0
};
yp_accepts_block_stack_push(parser, true);