diff options
-rw-r--r-- | prism/config.yml | 3 | ||||
-rw-r--r-- | prism/prism.c | 19 | ||||
-rw-r--r-- | prism/templates/src/diagnostic.c.erb | 3 |
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 }, |