summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prism/config.yml3
-rw-r--r--prism/prism.c19
-rw-r--r--prism/templates/src/diagnostic.c.erb3
3 files changed, 22 insertions, 3 deletions
diff --git a/prism/config.yml b/prism/config.yml
index 8551c95b1f..f59c03ff37 100644
--- a/prism/config.yml
+++ b/prism/config.yml
@@ -134,6 +134,8 @@ errors:
- INVALID_CHARACTER
- INVALID_ENCODING_MAGIC_COMMENT
- INVALID_FLOAT_EXPONENT
+ - INVALID_LOCAL_VARIABLE_READ
+ - INVALID_LOCAL_VARIABLE_WRITE
- INVALID_MULTIBYTE_CHAR
- INVALID_MULTIBYTE_CHARACTER
- INVALID_MULTIBYTE_ESCAPE
@@ -206,6 +208,7 @@ errors:
- PATTERN_HASH_KEY
- PATTERN_HASH_KEY_DUPLICATE
- PATTERN_HASH_KEY_LABEL
+ - PATTERN_HASH_KEY_LOCALS
- PATTERN_IDENT_AFTER_HROCKET
- PATTERN_LABEL_AFTER_COMMA
- PATTERN_REST
diff --git a/prism/prism.c b/prism/prism.c
index 18675b994a..d2fcf3e372 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -13234,9 +13234,15 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
value = (pm_node_t *) pm_constant_read_node_create(parser, &constant);
} else {
- int depth = pm_parser_local_depth(parser, &((pm_token_t) { .type = PM_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 }));
+ int depth = -1;
pm_token_t identifier = { .type = PM_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 };
+ if (identifier.end[-1] == '!' || identifier.end[-1] == '?') {
+ PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, identifier, PM_ERR_INVALID_LOCAL_VARIABLE_READ);
+ } else {
+ depth = pm_parser_local_depth(parser, &identifier);
+ }
+
if (depth == -1) {
value = (pm_node_t *) pm_call_node_variable_call_create(parser, &identifier);
} else {
@@ -15643,8 +15649,15 @@ parse_pattern_hash_implicit_value(pm_parser_t *parser, pm_constant_id_list_t *ca
const pm_location_t *value_loc = &((pm_symbol_node_t *) key)->value_loc;
pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, value_loc->start, value_loc->end);
- int depth;
- if ((depth = pm_parser_local_depth_constant_id(parser, constant_id)) == -1) {
+ int depth = -1;
+ if (value_loc->end[-1] == '!' || value_loc->end[-1] == '?') {
+ pm_parser_err(parser, key->base.location.start, key->base.location.end, PM_ERR_PATTERN_HASH_KEY_LOCALS);
+ PM_PARSER_ERR_LOCATION_FORMAT(parser, value_loc, PM_ERR_INVALID_LOCAL_VARIABLE_WRITE, (int) (value_loc->end - value_loc->start), (const char *) value_loc->start);
+ } else {
+ depth = pm_parser_local_depth_constant_id(parser, constant_id);
+ }
+
+ if (depth == -1) {
pm_parser_local_add(parser, constant_id, value_loc->start, value_loc->end, 0);
}
diff --git a/prism/templates/src/diagnostic.c.erb b/prism/templates/src/diagnostic.c.erb
index 42f8024551..8736fb48a2 100644
--- a/prism/templates/src/diagnostic.c.erb
+++ b/prism/templates/src/diagnostic.c.erb
@@ -216,6 +216,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_INSTANCE_VARIABLE_BARE] = { "'@' without identifiers is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_BLOCK_EXIT] = { "Invalid %s", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_FLOAT_EXPONENT] = { "invalid exponent", PM_ERROR_LEVEL_SYNTAX },
+ [PM_ERR_INVALID_LOCAL_VARIABLE_READ] = { "identifier %.*s is not valid to get", PM_ERROR_LEVEL_SYNTAX },
+ [PM_ERR_INVALID_LOCAL_VARIABLE_WRITE] = { "identifier %.*s is not valid to set", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_NUMBER_BINARY] = { "invalid binary number", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_NUMBER_DECIMAL] = { "invalid decimal number", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_INVALID_NUMBER_HEXADECIMAL] = { "invalid hexadecimal number", PM_ERROR_LEVEL_SYNTAX },
@@ -289,6 +291,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_PATTERN_HASH_KEY] = { "expected a key in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_PATTERN_HASH_KEY_DUPLICATE] = { "duplicated key name", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_PATTERN_HASH_KEY_LABEL] = { "expected a label as the key in the hash pattern", PM_ERROR_LEVEL_SYNTAX }, // TODO // THIS // AND // ABOVE // IS WEIRD
+ [PM_ERR_PATTERN_HASH_KEY_LOCALS] = { "key must be valid as local variables", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_PATTERN_IDENT_AFTER_HROCKET] = { "expected an identifier after the `=>` operator", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_PATTERN_LABEL_AFTER_COMMA] = { "expected a label after the `,` in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_PATTERN_REST] = { "unexpected rest pattern", PM_ERROR_LEVEL_SYNTAX },