summaryrefslogtreecommitdiff
path: root/yarp
diff options
context:
space:
mode:
authorMike Dalessio <mike.dalessio@gmail.com>2023-09-03 21:27:43 -0400
committergit <svn-admin@ruby-lang.org>2023-09-07 16:36:56 +0000
commit4efcaf956e27df365a1cf9e0cbb8d9a68eeb6995 (patch)
tree532e041de8290eb5c8e242b249084abfca331bda /yarp
parent2d37b44603f2031f0e95073ab77b418142c9eddd (diff)
[ruby/yarp] Extract error messages into diagnostic.c and use canonical message IDs
The parser now passes around `yp_diagnostic_id_t` for diagnostic messages instead of character strings, and we rely on the function `diagnostic_message()` to resolve that to a string. In addition, many messages were edited so that the parser expresses coordinate ideas in similar form [1] using consistent voice and typographic conventions. Closes https://github.com/ruby/yarp/pull/1379, and makes progress on #941. [1] Strunk & White rule 19 https://github.com/ruby/yarp/commit/0b6dd85bf1
Diffstat (limited to 'yarp')
-rw-r--r--yarp/diagnostic.c256
-rw-r--r--yarp/diagnostic.h199
-rw-r--r--yarp/unescape.c40
-rw-r--r--yarp/yarp.c608
4 files changed, 777 insertions, 326 deletions
diff --git a/yarp/diagnostic.c b/yarp/diagnostic.c
index b216d96a33..e92a1ee491 100644
--- a/yarp/diagnostic.c
+++ b/yarp/diagnostic.c
@@ -1,12 +1,264 @@
#include "yarp/diagnostic.h"
+/*
+ ## Message composition
+
+ When composing an error message, use sentence fragments.
+
+ Try describing the property of the code that caused the error, rather than the rule that is being
+ violated. It may help to use a fragment that completes a sentence beginning, "The parser
+ encountered (a) ...". If appropriate, add a description of the rule violation (or other helpful
+ context) after a semicolon.
+
+ For example:, instead of "Control escape sequence cannot be doubled", prefer:
+
+ > "Invalid control escape sequence; control cannot be repeated"
+
+ In some cases, where the failure is more general or syntax expectations are violated, it may make
+ more sense to use a fragment that completes a sentence beginning, "The parser ...".
+
+ For example:
+
+ > "Expected an expression after `(`"
+ > "Cannot parse the expression"
+
+
+ ## Message style guide
+
+ - Use articles like "a", "an", and "the" when appropriate.
+ - e.g., prefer "Cannot parse the expression" to "Cannot parse expression".
+ - Use the common name for tokens and nodes.
+ - e.g., prefer "keyword splat" to "assoc splat"
+ - e.g., prefer "embedded document" to "embdoc"
+ - Capitalize the initial word of the message.
+ - Use back ticks around token literals
+ - e.g., "Expected a `=>` between the hash key and value"
+ - Do not use `.` or other punctuation at the end of the message.
+ - Do not use contractions like "can't". Prefer "cannot" to "can not".
+ - For tokens that can have multiple meanings, reference the token and its meaning.
+ - e.g., "`*` splat argument" is clearer and more complete than "splat argument" or "`*` argument"
+
+
+ ## Error names (YP_ERR_*)
+
+ - When appropriate, prefer node name to token name.
+ - e.g., prefer "SPLAT" to "STAR" in the context of argument parsing.
+ - Prefer token name to common name.
+ - e.g., prefer "STAR" to "ASTERISK".
+ - Try to order the words in the name from more general to more specific,
+ - e.g., "INVALID_NUMBER_DECIMAL" is better than "DECIMAL_INVALID_NUMBER".
+ - When in doubt, look for similar patterns and name them so that they are grouped when lexically
+ sorted. See YP_ERR_ARGUMENT_NO_FORWARDING_* for an example.
+*/
+
+static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = {
+ [YP_ERR_ALIAS_ARGUMENT] = "Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable",
+ [YP_ERR_AMPAMPEQ_MULTI_ASSIGN] = "Unexpected `&&=` in a multiple assignment",
+ [YP_ERR_ARGUMENT_AFTER_BLOCK] = "Unexpected argument after a block argument",
+ [YP_ERR_ARGUMENT_BARE_HASH] = "Unexpected bare hash argument",
+ [YP_ERR_ARGUMENT_BLOCK_MULTI] = "Multiple block arguments; only one block is allowed",
+ [YP_ERR_ARGUMENT_FORMAL_CLASS] = "Invalid formal argument; formal argument cannot be a class variable",
+ [YP_ERR_ARGUMENT_FORMAL_CONSTANT] = "Invalid formal argument; formal argument cannot be a constant",
+ [YP_ERR_ARGUMENT_FORMAL_GLOBAL] = "Invalid formal argument; formal argument cannot be a global variable",
+ [YP_ERR_ARGUMENT_FORMAL_IVAR] = "Invalid formal argument; formal argument cannot be an instance variable",
+ [YP_ERR_ARGUMENT_NO_FORWARDING_AMP] = "Unexpected `&` when the parent method is not forwarding",
+ [YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "Unexpected `...` when the parent method is not forwarding",
+ [YP_ERR_ARGUMENT_NO_FORWARDING_STAR] = "Unexpected `*` when the parent method is not forwarding",
+ [YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = "Unexpected `*` splat argument after a `**` keyword splat argument",
+ [YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = "Unexpected `*` splat argument after a `*` splat argument",
+ [YP_ERR_ARGUMENT_TERM_PAREN] = "Expected a `)` to close the arguments",
+ [YP_ERR_ARRAY_ELEMENT] = "Expected an element for the array",
+ [YP_ERR_ARRAY_EXPRESSION] = "Expected an expression for the array element",
+ [YP_ERR_ARRAY_EXPRESSION_AFTER_STAR] = "Expected an expression after `*` in the array",
+ [YP_ERR_ARRAY_SEPARATOR] = "Expected a `,` separator for the array elements",
+ [YP_ERR_ARRAY_TERM] = "Expected a `]` to close the array",
+ [YP_ERR_BEGIN_LONELY_ELSE] = "Unexpected `else` in `begin` block; a `rescue` clause must precede `else`",
+ [YP_ERR_BEGIN_TERM] = "Expected an `end` to close the `begin` statement",
+ [YP_ERR_BEGIN_UPCASE_BRACE] = "Expected a `{` after `BEGIN`",
+ [YP_ERR_BEGIN_UPCASE_TERM] = "Expected a `}` to close the `BEGIN` statement",
+ [YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE] = "Expected a local variable name in the block parameters",
+ [YP_ERR_BLOCK_PARAM_PIPE_TERM] = "Expected the block parameters to end with `|`",
+ [YP_ERR_BLOCK_TERM_BRACE] = "Expected a block beginning with `{` to end with `}`",
+ [YP_ERR_BLOCK_TERM_END] = "Expected a block beginning with `do` to end with `end`",
+ [YP_ERR_CANNOT_PARSE_EXPRESSION] = "Cannot parse the expression",
+ [YP_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part",
+ [YP_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`",
+ [YP_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`",
+ [YP_ERR_CASE_LONELY_ELSE] = "Unexpected `else` in `case` statement; a `when` clause must precede `else`",
+ [YP_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement",
+ [YP_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body",
+ [YP_ERR_CLASS_NAME] = "Expected a constant name after `class`",
+ [YP_ERR_CLASS_SUPERCLASS] = "Expected a superclass after `<`",
+ [YP_ERR_CLASS_TERM] = "Expected an `end` to close the `class` statement",
+ [YP_ERR_CONDITIONAL_ELSIF_PREDICATE] = "Expected a predicate expression for the `elsif` statement",
+ [YP_ERR_CONDITIONAL_IF_PREDICATE] = "Expected a predicate expression for the `if` statement",
+ [YP_ERR_CONDITIONAL_TERM] = "Expected an `end` to close the conditional clause",
+ [YP_ERR_CONDITIONAL_TERM_ELSE] = "Expected an `end` to close the `else` clause",
+ [YP_ERR_CONDITIONAL_UNLESS_PREDICATE] = "Expected a predicate expression for the `unless` statement",
+ [YP_ERR_CONDITIONAL_UNTIL_PREDICATE] = "Expected a predicate expression for the `until` statement",
+ [YP_ERR_CONDITIONAL_WHILE_PREDICATE] = "Expected a predicate expression for the `while` statement",
+ [YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = "Expected a constant after the `::` operator",
+ [YP_ERR_DEF_ENDLESS] = "Could not parse the endless method body",
+ [YP_ERR_DEF_ENDLESS_SETTER] = "Invalid method name; a setter method cannot be defined in an endless method definition",
+ [YP_ERR_DEF_NAME] = "Expected a method name",
+ [YP_ERR_DEF_NAME_AFTER_RECEIVER] = "Expected a method name after the receiver",
+ [YP_ERR_DEF_PARAMS_TERM] = "Expected a delimiter to close the parameters",
+ [YP_ERR_DEF_PARAMS_TERM_PAREN] = "Expected a `)` to close the parameters",
+ [YP_ERR_DEF_RECEIVER] = "Expected a receiver for the method definition",
+ [YP_ERR_DEF_RECEIVER_TERM] = "Expected a `.` or `::` after the receiver in a method definition",
+ [YP_ERR_DEF_TERM] = "Expected an `end` to close the `def` statement",
+ [YP_ERR_DEFINED_EXPRESSION] = "Expected an expression after `defined?`",
+ [YP_ERR_EMBDOC_TERM] = "Could not find a terminator for the embedded document",
+ [YP_ERR_EMBEXPR_END] = "Expected a `}` to close the embedded expression",
+ [YP_ERR_EMBVAR_INVALID] = "Invalid embedded variable",
+ [YP_ERR_END_UPCASE_BRACE] = "Expected a `{` after `END`",
+ [YP_ERR_END_UPCASE_TERM] = "Expected a `}` to close the `END` statement",
+ [YP_ERR_ESCAPE_INVALID_CONTROL] = "Invalid control escape sequence",
+ [YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = "Invalid control escape sequence; control cannot be repeated",
+ [YP_ERR_ESCAPE_INVALID_HEXADECIMAL] = "Invalid hexadecimal escape sequence",
+ [YP_ERR_ESCAPE_INVALID_META] = "Invalid meta escape sequence",
+ [YP_ERR_ESCAPE_INVALID_META_REPEAT] = "Invalid meta escape sequence; meta cannot be repeated",
+ [YP_ERR_ESCAPE_INVALID_UNICODE] = "Invalid Unicode escape sequence",
+ [YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = "Invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags",
+ [YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = "Invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal",
+ [YP_ERR_ESCAPE_INVALID_UNICODE_LONG] = "Invalid Unicode escape sequence; maximum length is 6 digits",
+ [YP_ERR_ESCAPE_INVALID_UNICODE_TERM] = "Invalid Unicode escape sequence; needs closing `}`",
+ [YP_ERR_EXPECT_ARGUMENT] = "Expected an argument",
+ [YP_ERR_EXPECT_EOL_AFTER_STATEMENT] = "Expected a newline or semicolon after the statement",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = "Expected an expression after `&&=`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = "Expected an expression after `||=`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA] = "Expected an expression after `,`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL] = "Expected an expression after `=`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS] = "Expected an expression after `<<`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN] = "Expected an expression after `(`",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR] = "Expected an expression after the operator",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = "Expected an expression after `*` splat in an argument",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = "Expected an expression after `**` in a hash",
+ [YP_ERR_EXPECT_EXPRESSION_AFTER_STAR] = "Expected an expression after `*`",
+ [YP_ERR_EXPECT_IDENT_REQ_PARAMETER] = "Expected an identifier for the required parameter",
+ [YP_ERR_EXPECT_LPAREN_REQ_PARAMETER] = "Expected a `(` to start a required parameter",
+ [YP_ERR_EXPECT_RBRACKET] = "Expected a matching `]`",
+ [YP_ERR_EXPECT_RPAREN] = "Expected a matching `)`",
+ [YP_ERR_EXPECT_RPAREN_AFTER_MULTI] = "Expected a `)` after multiple assignment",
+ [YP_ERR_EXPECT_RPAREN_REQ_PARAMETER] = "Expected a `)` to end a required parameter",
+ [YP_ERR_EXPECT_STRING_CONTENT] = "Expected string content after opening string delimiter",
+ [YP_ERR_EXPECT_WHEN_DELIMITER] = "Expected a delimiter after the predicates of a `when` clause",
+ [YP_ERR_EXPRESSION_BARE_HASH] = "Unexpected bare hash in expression",
+ [YP_ERR_FOR_COLLECTION] = "Expected a collection after the `in` in a `for` statement",
+ [YP_ERR_FOR_INDEX] = "Expected an index after `for`",
+ [YP_ERR_FOR_IN] = "Expected an `in` after the index in a `for` statement",
+ [YP_ERR_FOR_TERM] = "Expected an `end` to close the `for` loop",
+ [YP_ERR_HASH_EXPRESSION_AFTER_LABEL] = "Expected an expression after the label in a hash",
+ [YP_ERR_HASH_KEY] = "Expected a key in the hash literal",
+ [YP_ERR_HASH_ROCKET] = "Expected a `=>` between the hash key and value",
+ [YP_ERR_HASH_TERM] = "Expected a `}` to close the hash literal",
+ [YP_ERR_HASH_VALUE] = "Expected a value in the hash literal",
+ [YP_ERR_HEREDOC_TERM] = "Could not find a terminator for the heredoc",
+ [YP_ERR_INCOMPLETE_QUESTION_MARK] = "Incomplete expression at `?`",
+ [YP_ERR_INCOMPLETE_VARIABLE_CLASS] = "Incomplete class variable",
+ [YP_ERR_INCOMPLETE_VARIABLE_INSTANCE] = "Incomplete instance variable",
+ [YP_ERR_INVALID_ENCODING_MAGIC_COMMENT] = "Unknown or invalid encoding in the magic comment",
+ [YP_ERR_INVALID_FLOAT_EXPONENT] = "Invalid exponent",
+ [YP_ERR_INVALID_NUMBER_BINARY] = "Invalid binary number",
+ [YP_ERR_INVALID_NUMBER_DECIMAL] = "Invalid decimal number",
+ [YP_ERR_INVALID_NUMBER_HEXADECIMAL] = "Invalid hexadecimal number",
+ [YP_ERR_INVALID_NUMBER_OCTAL] = "Invalid octal number",
+ [YP_ERR_INVALID_PERCENT] = "Invalid `%` token", // TODO WHAT?
+ [YP_ERR_INVALID_TOKEN] = "Invalid token", // TODO WHAT?
+ [YP_ERR_INVALID_VARIABLE_GLOBAL] = "Invalid global variable",
+ [YP_ERR_LAMBDA_OPEN] = "Expected a `do` keyword or a `{` to open the lambda block",
+ [YP_ERR_LAMBDA_TERM_BRACE] = "Expected a lambda block beginning with `{` to end with `}`",
+ [YP_ERR_LAMBDA_TERM_END] = "Expected a lambda block beginning with `do` to end with `end`",
+ [YP_ERR_LIST_I_LOWER_ELEMENT] = "Expected a symbol in a `%i` list",
+ [YP_ERR_LIST_I_LOWER_TERM] = "Expected a closing delimiter for the `%i` list",
+ [YP_ERR_LIST_I_UPPER_ELEMENT] = "Expected a symbol in a `%I` list",
+ [YP_ERR_LIST_I_UPPER_TERM] = "Expected a closing delimiter for the `%I` list",
+ [YP_ERR_LIST_W_LOWER_ELEMENT] = "Expected a string in a `%w` list",
+ [YP_ERR_LIST_W_LOWER_TERM] = "Expected a closing delimiter for the `%w` list",
+ [YP_ERR_LIST_W_UPPER_ELEMENT] = "Expected a string in a `%W` list",
+ [YP_ERR_LIST_W_UPPER_TERM] = "Expected a closing delimiter for the `%W` list",
+ [YP_ERR_MALLOC_FAILED] = "Failed to allocate memory",
+ [YP_ERR_MODULE_IN_METHOD] = "Unexpected module definition in a method body",
+ [YP_ERR_MODULE_NAME] = "Expected a constant name after `module`",
+ [YP_ERR_MODULE_TERM] = "Expected an `end` to close the `module` statement",
+ [YP_ERR_MULTI_ASSIGN_MULTI_SPLATS] = "Multiple splats in multiple assignment",
+ [YP_ERR_NOT_EXPRESSION] = "Expected an expression after `not`",
+ [YP_ERR_NUMBER_LITERAL_UNDERSCORE] = "Number literal ending with a `_`",
+ [YP_ERR_OPERATOR_MULTI_ASSIGN] = "Unexpected operator for a multiple assignment",
+ [YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters",
+ [YP_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed",
+ [YP_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name",
+ [YP_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter",
+ [YP_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter",
+ [YP_ERR_PARAMETER_NUMBERED_RESERVED] = "Token reserved for a numbered parameter",
+ [YP_ERR_PARAMETER_ORDER] = "Unexpected parameter order",
+ [YP_ERR_PARAMETER_SPLAT_MULTI] = "Unexpected multiple `*` splat parameters",
+ [YP_ERR_PARAMETER_STAR] = "Unexpected parameter `*`",
+ [YP_ERR_PARAMETER_WILD_LOOSE_COMMA] = "Unexpected `,` in parameters",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = "Expected a pattern expression after the `[` operator",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = "Expected a pattern expression after `,`",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = "Expected a pattern expression after `=>`",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_IN] = "Expected a pattern expression after the `in` keyword",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_KEY] = "Expected a pattern expression after the key",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN] = "Expected a pattern expression after the `(` operator",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_PIN] = "Expected a pattern expression after the `^` pin operator",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = "Expected a pattern expression after the `|` operator",
+ [YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = "Expected a pattern expression after the range operator",
+ [YP_ERR_PATTERN_HASH_KEY] = "Expected a key in the hash pattern",
+ [YP_ERR_PATTERN_HASH_KEY_LABEL] = "Expected a label as the key in the hash pattern", // TODO // THIS // AND // ABOVE // IS WEIRD
+ [YP_ERR_PATTERN_IDENT_AFTER_HROCKET] = "Expected an identifier after the `=>` operator",
+ [YP_ERR_PATTERN_LABEL_AFTER_COMMA] = "Expected a label after the `,` in the hash pattern",
+ [YP_ERR_PATTERN_REST] = "Unexpected rest pattern",
+ [YP_ERR_PATTERN_TERM_BRACE] = "Expected a `}` to close the pattern expression",
+ [YP_ERR_PATTERN_TERM_BRACKET] = "Expected a `]` to close the pattern expression",
+ [YP_ERR_PATTERN_TERM_PAREN] = "Expected a `)` to close the pattern expression",
+ [YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN] = "Unexpected `||=` in a multiple assignment",
+ [YP_ERR_REGEXP_TERM] = "Expected a closing delimiter for the regular expression",
+ [YP_ERR_RESCUE_EXPRESSION] = "Expected a rescued expression",
+ [YP_ERR_RESCUE_MODIFIER_VALUE] = "Expected a value after the `rescue` modifier",
+ [YP_ERR_RESCUE_TERM] = "Expected a closing delimiter for the `rescue` clause",
+ [YP_ERR_RESCUE_VARIABLE] = "Expected an exception variable after `=>` in a rescue statement",
+ [YP_ERR_RETURN_INVALID] = "Invalid `return` in a class or module body",
+ [YP_ERR_STRING_CONCATENATION] = "Expected a string for concatenation",
+ [YP_ERR_STRING_INTERPOLATED_TERM] = "Expected a closing delimiter for the interpolated string",
+ [YP_ERR_STRING_LITERAL_TERM] = "Expected a closing delimiter for the string literal",
+ [YP_ERR_SYMBOL_INVALID] = "Invalid symbol", // TODO expected symbol? yarp.c ~9719
+ [YP_ERR_SYMBOL_TERM_DYNAMIC] = "Expected a closing delimiter for the dynamic symbol",
+ [YP_ERR_SYMBOL_TERM_INTERPOLATED] = "Expected a closing delimiter for the interpolated symbol",
+ [YP_ERR_TERNARY_COLON] = "Expected a `:` after the true expression of a ternary operator",
+ [YP_ERR_TERNARY_EXPRESSION_FALSE] = "Expected an expression after `:` in the ternary operator",
+ [YP_ERR_TERNARY_EXPRESSION_TRUE] = "Expected an expression after `?` in the ternary operator",
+ [YP_ERR_UNDEF_ARGUMENT] = "Invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument",
+ [YP_ERR_UNARY_RECEIVER_BANG] = "Expected a receiver for unary `!`",
+ [YP_ERR_UNARY_RECEIVER_MINUS] = "Expected a receiver for unary `-`",
+ [YP_ERR_UNARY_RECEIVER_PLUS] = "Expected a receiver for unary `+`",
+ [YP_ERR_UNARY_RECEIVER_TILDE] = "Expected a receiver for unary `~`",
+ [YP_ERR_UNTIL_TERM] = "Expected an `end` to close the `until` statement",
+ [YP_ERR_WHILE_TERM] = "Expected an `end` to close the `while` statement",
+ [YP_ERR_WRITE_TARGET_READONLY] = "Immutable variable as a write target",
+ [YP_ERR_WRITE_TARGET_UNEXPECTED] = "Unexpected write target",
+ [YP_ERR_XSTRING_TERM] = "Expected a closing delimiter for the `%x` or backtick string",
+ [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = "Ambiguous first argument; put parentheses or a space even after `-` operator",
+ [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = "Ambiguous first argument; put parentheses or a space even after `+` operator",
+ [YP_WARN_AMBIGUOUS_PREFIX_STAR] = "Ambiguous `*` has been interpreted as an argument prefix",
+ [YP_WARN_AMBIGUOUS_SLASH] = "Ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator",
+};
+
+static const char*
+yp_diagnostic_message(yp_diagnostic_id_t diag_id) {
+ assert(diag_id < YP_DIAGNOSTIC_ID_LEN);
+ const char *message = diagnostic_messages[diag_id];
+ assert(message);
+ return message;
+}
+
// Append an error to the given list of diagnostic.
bool
-yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, const char *message) {
+yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id) {
yp_diagnostic_t *diagnostic = (yp_diagnostic_t *) malloc(sizeof(yp_diagnostic_t));
if (diagnostic == NULL) return false;
- *diagnostic = (yp_diagnostic_t) { .start = start, .end = end, .message = message };
+ *diagnostic = (yp_diagnostic_t) { .start = start, .end = end, .message = yp_diagnostic_message(diag_id) };
yp_list_append(list, (yp_list_node_t *) diagnostic);
return true;
}
diff --git a/yarp/diagnostic.h b/yarp/diagnostic.h
index 58228d8493..fd17945e0d 100644
--- a/yarp/diagnostic.h
+++ b/yarp/diagnostic.h
@@ -6,6 +6,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include <assert.h>
// This struct represents a diagnostic found during parsing.
typedef struct {
@@ -15,8 +16,204 @@ typedef struct {
const char *message;
} yp_diagnostic_t;
+typedef enum {
+ YP_ERR_ALIAS_ARGUMENT,
+ YP_ERR_AMPAMPEQ_MULTI_ASSIGN,
+ YP_ERR_ARGUMENT_AFTER_BLOCK,
+ YP_ERR_ARGUMENT_BARE_HASH,
+ YP_ERR_ARGUMENT_BLOCK_MULTI,
+ YP_ERR_ARGUMENT_FORMAL_CLASS,
+ YP_ERR_ARGUMENT_FORMAL_CONSTANT,
+ YP_ERR_ARGUMENT_FORMAL_GLOBAL,
+ YP_ERR_ARGUMENT_FORMAL_IVAR,
+ YP_ERR_ARGUMENT_NO_FORWARDING_AMP,
+ YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
+ YP_ERR_ARGUMENT_NO_FORWARDING_STAR,
+ YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT,
+ YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT,
+ YP_ERR_ARGUMENT_TERM_PAREN,
+ YP_ERR_ARRAY_ELEMENT,
+ YP_ERR_ARRAY_EXPRESSION,
+ YP_ERR_ARRAY_EXPRESSION_AFTER_STAR,
+ YP_ERR_ARRAY_SEPARATOR,
+ YP_ERR_ARRAY_TERM,
+ YP_ERR_BEGIN_LONELY_ELSE,
+ YP_ERR_BEGIN_TERM,
+ YP_ERR_BEGIN_UPCASE_BRACE,
+ YP_ERR_BEGIN_UPCASE_TERM,
+ YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE,
+ YP_ERR_BLOCK_PARAM_PIPE_TERM,
+ YP_ERR_BLOCK_TERM_BRACE,
+ YP_ERR_BLOCK_TERM_END,
+ YP_ERR_CANNOT_PARSE_EXPRESSION,
+ YP_ERR_CANNOT_PARSE_STRING_PART,
+ YP_ERR_CASE_EXPRESSION_AFTER_CASE,
+ YP_ERR_CASE_EXPRESSION_AFTER_WHEN,
+ YP_ERR_CASE_LONELY_ELSE,
+ YP_ERR_CASE_TERM,
+ YP_ERR_CLASS_IN_METHOD,
+ YP_ERR_CLASS_NAME,
+ YP_ERR_CLASS_SUPERCLASS,
+ YP_ERR_CLASS_TERM,
+ YP_ERR_CONDITIONAL_ELSIF_PREDICATE,
+ YP_ERR_CONDITIONAL_IF_PREDICATE,
+ YP_ERR_CONDITIONAL_TERM,
+ YP_ERR_CONDITIONAL_TERM_ELSE,
+ YP_ERR_CONDITIONAL_UNLESS_PREDICATE,
+ YP_ERR_CONDITIONAL_UNTIL_PREDICATE,
+ YP_ERR_CONDITIONAL_WHILE_PREDICATE,
+ YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
+ YP_ERR_DEF_ENDLESS,
+ YP_ERR_DEF_ENDLESS_SETTER,
+ YP_ERR_DEF_NAME,
+ YP_ERR_DEF_NAME_AFTER_RECEIVER,
+ YP_ERR_DEF_PARAMS_TERM,
+ YP_ERR_DEF_PARAMS_TERM_PAREN,
+ YP_ERR_DEF_RECEIVER,
+ YP_ERR_DEF_RECEIVER_TERM,
+ YP_ERR_DEF_TERM,
+ YP_ERR_DEFINED_EXPRESSION,
+ YP_ERR_EMBDOC_TERM,
+ YP_ERR_EMBEXPR_END,
+ YP_ERR_EMBVAR_INVALID,
+ YP_ERR_END_UPCASE_BRACE,
+ YP_ERR_END_UPCASE_TERM,
+ YP_ERR_ESCAPE_INVALID_CONTROL,
+ YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT,
+ YP_ERR_ESCAPE_INVALID_HEXADECIMAL,
+ YP_ERR_ESCAPE_INVALID_META,
+ YP_ERR_ESCAPE_INVALID_META_REPEAT,
+ YP_ERR_ESCAPE_INVALID_UNICODE,
+ YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS,
+ YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL,
+ YP_ERR_ESCAPE_INVALID_UNICODE_LONG,
+ YP_ERR_ESCAPE_INVALID_UNICODE_TERM,
+ YP_ERR_EXPECT_ARGUMENT,
+ YP_ERR_EXPECT_EOL_AFTER_STATEMENT,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_QUESTION,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH,
+ YP_ERR_EXPECT_EXPRESSION_AFTER_STAR,
+ YP_ERR_EXPECT_IDENT_REQ_PARAMETER,
+ YP_ERR_EXPECT_LPAREN_REQ_PARAMETER,
+ YP_ERR_EXPECT_RBRACKET,
+ YP_ERR_EXPECT_RPAREN,
+ YP_ERR_EXPECT_RPAREN_AFTER_MULTI,
+ YP_ERR_EXPECT_RPAREN_REQ_PARAMETER,
+ YP_ERR_EXPECT_STRING_CONTENT,
+ YP_ERR_EXPECT_WHEN_DELIMITER,
+ YP_ERR_EXPRESSION_BARE_HASH,
+ YP_ERR_FOR_COLLECTION,
+ YP_ERR_FOR_IN,
+ YP_ERR_FOR_INDEX,
+ YP_ERR_FOR_TERM,
+ YP_ERR_HASH_EXPRESSION_AFTER_LABEL,
+ YP_ERR_HASH_KEY,
+ YP_ERR_HASH_ROCKET,
+ YP_ERR_HASH_TERM,
+ YP_ERR_HASH_VALUE,
+ YP_ERR_HEREDOC_TERM,
+ YP_ERR_INCOMPLETE_QUESTION_MARK,
+ YP_ERR_INCOMPLETE_VARIABLE_CLASS,
+ YP_ERR_INCOMPLETE_VARIABLE_INSTANCE,
+ YP_ERR_INVALID_ENCODING_MAGIC_COMMENT,
+ YP_ERR_INVALID_FLOAT_EXPONENT,
+ YP_ERR_INVALID_NUMBER_BINARY,
+ YP_ERR_INVALID_NUMBER_DECIMAL,
+ YP_ERR_INVALID_NUMBER_HEXADECIMAL,
+ YP_ERR_INVALID_NUMBER_OCTAL,
+ YP_ERR_INVALID_PERCENT,
+ YP_ERR_INVALID_TOKEN,
+ YP_ERR_INVALID_VARIABLE_GLOBAL,
+ YP_ERR_LAMBDA_OPEN,
+ YP_ERR_LAMBDA_TERM_BRACE,
+ YP_ERR_LAMBDA_TERM_END,
+ YP_ERR_LIST_I_LOWER_ELEMENT,
+ YP_ERR_LIST_I_LOWER_TERM,
+ YP_ERR_LIST_I_UPPER_ELEMENT,
+ YP_ERR_LIST_I_UPPER_TERM,
+ YP_ERR_LIST_W_LOWER_ELEMENT,
+ YP_ERR_LIST_W_LOWER_TERM,
+ YP_ERR_LIST_W_UPPER_ELEMENT,
+ YP_ERR_LIST_W_UPPER_TERM,
+ YP_ERR_MALLOC_FAILED,
+ YP_ERR_MODULE_IN_METHOD,
+ YP_ERR_MODULE_NAME,
+ YP_ERR_MODULE_TERM,
+ YP_ERR_MULTI_ASSIGN_MULTI_SPLATS,
+ YP_ERR_NOT_EXPRESSION,
+ YP_ERR_NUMBER_LITERAL_UNDERSCORE,
+ YP_ERR_OPERATOR_MULTI_ASSIGN,
+ YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
+ YP_ERR_PARAMETER_BLOCK_MULTI,
+ YP_ERR_PARAMETER_NAME_REPEAT,
+ YP_ERR_PARAMETER_NO_DEFAULT,
+ YP_ERR_PARAMETER_NO_DEFAULT_KW,
+ YP_ERR_PARAMETER_NUMBERED_RESERVED,
+ YP_ERR_PARAMETER_ORDER,
+ YP_ERR_PARAMETER_SPLAT_MULTI,
+ YP_ERR_PARAMETER_STAR,
+ YP_ERR_PARAMETER_WILD_LOOSE_COMMA,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_IN,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_KEY,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_PIN,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE,
+ YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE,
+ YP_ERR_PATTERN_HASH_KEY,
+ YP_ERR_PATTERN_HASH_KEY_LABEL,
+ YP_ERR_PATTERN_IDENT_AFTER_HROCKET,
+ YP_ERR_PATTERN_LABEL_AFTER_COMMA,
+ YP_ERR_PATTERN_REST,
+ YP_ERR_PATTERN_TERM_BRACE,
+ YP_ERR_PATTERN_TERM_BRACKET,
+ YP_ERR_PATTERN_TERM_PAREN,
+ YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN,
+ YP_ERR_REGEXP_TERM,
+ YP_ERR_RESCUE_EXPRESSION,
+ YP_ERR_RESCUE_MODIFIER_VALUE,
+ YP_ERR_RESCUE_TERM,
+ YP_ERR_RESCUE_VARIABLE,
+ YP_ERR_RETURN_INVALID,
+ YP_ERR_STRING_CONCATENATION,
+ YP_ERR_STRING_INTERPOLATED_TERM,
+ YP_ERR_STRING_LITERAL_TERM,
+ YP_ERR_SYMBOL_INVALID,
+ YP_ERR_SYMBOL_TERM_DYNAMIC,
+ YP_ERR_SYMBOL_TERM_INTERPOLATED,
+ YP_ERR_TERNARY_COLON,
+ YP_ERR_TERNARY_EXPRESSION_FALSE,
+ YP_ERR_TERNARY_EXPRESSION_TRUE,
+ YP_ERR_UNDEF_ARGUMENT,
+ YP_ERR_UNARY_RECEIVER_BANG,
+ YP_ERR_UNARY_RECEIVER_MINUS,
+ YP_ERR_UNARY_RECEIVER_PLUS,
+ YP_ERR_UNARY_RECEIVER_TILDE,
+ YP_ERR_UNTIL_TERM,
+ YP_ERR_WHILE_TERM,
+ YP_ERR_WRITE_TARGET_READONLY,
+ YP_ERR_WRITE_TARGET_UNEXPECTED,
+ YP_ERR_XSTRING_TERM,
+ YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS,
+ YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS,
+ YP_WARN_AMBIGUOUS_PREFIX_STAR,
+ YP_WARN_AMBIGUOUS_SLASH,
+ /* This must be the last member. */
+ YP_DIAGNOSTIC_ID_LEN,
+} yp_diagnostic_id_t;
+
// Append a diagnostic to the given list of diagnostics.
-bool yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, const char *message);
+bool yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id);
// Deallocate the internal state of the given diagnostic list.
void yp_diagnostic_list_free(yp_list_t *list);
diff --git a/yarp/unescape.c b/yarp/unescape.c
index 830c5996ae..9da52eaea9 100644
--- a/yarp/unescape.c
+++ b/yarp/unescape.c
@@ -94,7 +94,7 @@ static inline size_t
unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end, yp_list_t *error_list) {
*value = 0;
if (backslash + 2 >= end || !yp_char_is_hexadecimal_digit(backslash[2])) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid hex escape.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_HEXADECIMAL);
return 2;
}
*value = unescape_hexadecimal_digit(backslash[2]);
@@ -157,7 +157,7 @@ unescape_unicode_write(uint8_t *dest, uint32_t value, const uint8_t *start, cons
// If we get here, then the value is too big. This is an error, but we don't
// want to just crash, so instead we'll add an error to the error list and put
// in a replacement character instead.
- if (error_list) yp_diagnostic_list_append(error_list, start, end, "Invalid Unicode escape sequence.");
+ if (error_list) yp_diagnostic_list_append(error_list, start, end, YP_ERR_ESCAPE_INVALID_UNICODE);
dest[0] = 0xEF;
dest[1] = 0xBF;
dest[2] = 0xBD;
@@ -235,7 +235,7 @@ unescape(
// \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F])
case 'u': {
if ((flags & YP_UNESCAPE_FLAG_CONTROL) | (flags & YP_UNESCAPE_FLAG_META)) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Unicode escape sequence cannot be used with control or meta flags.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS);
return backslash + 2;
}
@@ -252,11 +252,11 @@ unescape(
// \u{nnnn} character literal allows only 1-6 hexadecimal digits
if (hexadecimal_length > 6) {
- if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "invalid Unicode escape.");
+ if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE_LONG);
}
// there are not hexadecimal characters
else if (hexadecimal_length == 0) {
- if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "unterminated Unicode escape");
+ if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE);
return unicode_cursor;
}
@@ -277,13 +277,13 @@ unescape(
// ?\u{nnnn} character literal should contain only one codepoint and cannot be like ?\u{nnnn mmmm}
if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1) {
- if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, "Multiple codepoints at single character literal");
+ if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL);
}
if (unicode_cursor < end && *unicode_cursor == '}') {
unicode_cursor++;
} else {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, "invalid Unicode escape.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, YP_ERR_ESCAPE_INVALID_UNICODE_TERM);
}
return unicode_cursor;
@@ -298,7 +298,7 @@ unescape(
return backslash + 6;
}
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid Unicode escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE);
return backslash + 2;
}
// \c\M-x meta control character, where x is an ASCII printable character
@@ -306,12 +306,12 @@ unescape(
// \cx control character, where x is an ASCII printable character
case 'c':
if (backslash + 2 >= end) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
return end;
}
if (flags & YP_UNESCAPE_FLAG_CONTROL) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
return backslash + 2;
}
@@ -325,7 +325,7 @@ unescape(
return backslash + 3;
default: {
if (!char_is_ascii_printable(backslash[2])) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
return backslash + 2;
}
@@ -339,17 +339,17 @@ unescape(
// \C-? delete, ASCII 7Fh (DEL)
case 'C':
if (backslash + 3 >= end) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
return end;
}
if (flags & YP_UNESCAPE_FLAG_CONTROL) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
return backslash + 2;
}
if (backslash[2] != '-') {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
return backslash + 2;
}
@@ -363,7 +363,7 @@ unescape(
return backslash + 4;
default:
if (!char_is_ascii_printable(backslash[3])) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_CONTROL);
return backslash + 2;
}
@@ -377,17 +377,17 @@ unescape(
// \M-x meta character, where x is an ASCII printable character
case 'M': {
if (backslash + 3 >= end) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_META);
return end;
}
if (flags & YP_UNESCAPE_FLAG_META) {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Meta escape sequence cannot be doubled.");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META_REPEAT);
return backslash + 2;
}
if (backslash[2] != '-') {
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META);
return backslash + 2;
}
@@ -402,7 +402,7 @@ unescape(
return backslash + 4;
}
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence");
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META);
return backslash + 3;
}
// \n
@@ -474,7 +474,7 @@ yp_unescape_manipulate_string_or_char_literal(yp_parser_t *parser, yp_string_t *
// within the string.
uint8_t *allocated = malloc(string->length);
if (allocated == NULL) {
- yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, "Failed to allocate memory for unescaping.");
+ yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, YP_ERR_MALLOC_FAILED);
return;
}
diff --git a/yarp/yarp.c b/yarp/yarp.c
index cb2bf18597..07ee4d8a8f 100644
--- a/yarp/yarp.c
+++ b/yarp/yarp.c
@@ -549,7 +549,7 @@ yp_arguments_validate(yp_parser_t *parser, yp_arguments_t *arguments) {
&parser->error_list,
arguments->block->base.location.start,
arguments->block->base.location.end,
- "both block arg and actual block given"
+ YP_ERR_ARGUMENT_BLOCK_MULTI
);
}
}
@@ -643,14 +643,14 @@ parse_decimal_number(yp_parser_t *parser, const uint8_t *start, const uint8_t *e
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");
+ yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL);
value = UINT32_MAX;
}
free(digits);
if (value > UINT32_MAX) {
- yp_diagnostic_list_append(&parser->error_list, start, end, "invalid decimal number");
+ yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL);
value = UINT32_MAX;
}
@@ -4637,7 +4637,7 @@ yp_parser_parameter_name_check(yp_parser_t *parser, yp_token_t *name) {
yp_constant_id_t constant_id = yp_parser_constant_id_token(parser, name);
if (yp_constant_id_list_includes(&parser->current_scope->locals, constant_id)) {
- yp_diagnostic_list_append(&parser->error_list, name->start, name->end, "Duplicated parameter name.");
+ yp_diagnostic_list_append(&parser->error_list, name->start, name->end, YP_ERR_PARAMETER_NAME_REPEAT);
}
}
@@ -4980,7 +4980,7 @@ parser_lex_encoding_comment(yp_parser_t *parser) {
// didn't understand the encoding that the user was trying to use. In this
// case we'll keep using the default encoding but add an error to the
// parser to indicate an unsuccessful parse.
- yp_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, "Could not understand the encoding specified in the magic comment.");
+ yp_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, YP_ERR_INVALID_ENCODING_MAGIC_COMMENT);
}
/******************************************************************************/
@@ -5140,7 +5140,7 @@ lex_optional_float_suffix(yp_parser_t *parser) {
parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end);
type = YP_TOKEN_FLOAT;
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Missing exponent.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_FLOAT_EXPONENT);
type = YP_TOKEN_FLOAT;
}
}
@@ -5161,7 +5161,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
if (yp_char_is_decimal_digit(peek(parser))) {
parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end);
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid decimal number.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_DECIMAL);
}
break;
@@ -5173,7 +5173,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
if (yp_char_is_binary_digit(peek(parser))) {
parser->current.end += yp_strspn_binary_number(parser->current.end, parser->end - parser->current.end);
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid binary number.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_BINARY);
}
break;
@@ -5185,7 +5185,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
if (yp_char_is_octal_digit(peek(parser))) {
parser->current.end += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end);
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid octal number.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_OCTAL);
}
break;
@@ -5210,7 +5210,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
if (yp_char_is_hexadecimal_digit(peek(parser))) {
parser->current.end += yp_strspn_hexadecimal_number(parser->current.end, parser->end - parser->current.end);
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid hexadecimal number.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_HEXADECIMAL);
}
break;
@@ -5240,7 +5240,7 @@ lex_numeric_prefix(yp_parser_t *parser) {
// If the last character that we consumed was an underscore, then this is
// actually an invalid integer value, and we should return an invalid token.
if (peek_offset(parser, -1) == '_') {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Number literal cannot end with a `_`.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_NUMBER_LITERAL_UNDERSCORE);
}
return type;
@@ -5292,7 +5292,7 @@ lex_numeric(yp_parser_t *parser) {
static yp_token_type_t
lex_global_variable(yp_parser_t *parser) {
if (parser->current.end >= parser->end) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL);
return YP_TOKEN_GLOBAL_VARIABLE;
}
@@ -5333,7 +5333,7 @@ lex_global_variable(yp_parser_t *parser) {
} while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0);
// $0 isn't allowed to be followed by anything.
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL);
}
return YP_TOKEN_GLOBAL_VARIABLE;
@@ -5364,7 +5364,7 @@ lex_global_variable(yp_parser_t *parser) {
} else {
// If we get here, then we have a $ followed by something that isn't
// recognized as a global variable.
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL);
}
return YP_TOKEN_GLOBAL_VARIABLE;
@@ -5704,7 +5704,7 @@ lex_question_mark(yp_parser_t *parser) {
}
if (parser->current.end >= parser->end) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete character syntax.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_QUESTION_MARK);
return YP_TOKEN_CHARACTER_LITERAL;
}
@@ -5755,9 +5755,9 @@ lex_at_variable(yp_parser_t *parser) {
parser->current.end += width;
}
} else if (type == YP_TOKEN_CLASS_VARIABLE) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete class variable.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_VARIABLE_CLASS);
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete instance variable.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_VARIABLE_INSTANCE);
}
// If we're lexing an embedded variable, then we need to pop back into the
@@ -5856,7 +5856,7 @@ lex_embdoc(yp_parser_t *parser) {
parser_lex_callback(parser);
}
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unterminated embdoc");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EMBDOC_TERM);
comment->end = parser->current.end;
yp_list_append(&parser->comment_list, (yp_list_node_t *) comment);
@@ -6286,7 +6286,7 @@ parser_lex(yp_parser_t *parser) {
yp_token_type_t type = YP_TOKEN_STAR;
if (lex_state_spcarg_p(parser, space_seen)) {
- yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, "`*' interpreted as argument prefix");
+ yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_PREFIX_STAR);
type = YP_TOKEN_USTAR;
} else if (lex_state_beg_p(parser)) {
type = YP_TOKEN_USTAR;
@@ -6430,7 +6430,7 @@ parser_lex(yp_parser_t *parser) {
// this is not a valid heredoc declaration. In this case we
// will add an error, but we will still return a heredoc
// start.
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unterminated heredoc.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EMBDOC_TERM);
body_start = parser->end;
} else {
// Otherwise, we want to indicate that the body of the
@@ -6627,7 +6627,7 @@ parser_lex(yp_parser_t *parser) {
&parser->warning_list,
parser->current.start,
parser->current.end,
- "ambiguous first argument; put parentheses or a space even after `+` operator"
+ YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS
);
}
@@ -6676,7 +6676,7 @@ parser_lex(yp_parser_t *parser) {
&parser->warning_list,
parser->current.start,
parser->current.end,
- "ambiguous first argument; put parentheses or a space even after `-` operator"
+ YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS
);
}
@@ -6774,7 +6774,7 @@ parser_lex(yp_parser_t *parser) {
}
if (lex_state_spcarg_p(parser, space_seen)) {
- yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, "ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `/' operator");
+ yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_SLASH);
lex_mode_push_regexp(parser, '\0', '/');
LEX(YP_TOKEN_REGEXP_BEGIN);
}
@@ -6813,7 +6813,7 @@ parser_lex(yp_parser_t *parser) {
// going to say it's the percent operator because we don't want to move into the
// string lex mode unnecessarily.
if ((lex_state_beg_p(parser) || lex_state_arg_p(parser)) && (parser->current.end >= parser->end)) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected end of input");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT);
LEX(YP_TOKEN_PERCENT);
}
@@ -6938,7 +6938,7 @@ parser_lex(yp_parser_t *parser) {
// unparseable. In this case we'll just drop it from the parser
// and skip past it and hope that the next token is something
// that we can parse.
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid %% token");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT);
goto lex_next_token;
}
}
@@ -6974,7 +6974,7 @@ parser_lex(yp_parser_t *parser) {
// token as we've exhausted all of the other options. We'll skip past
// it and return the next token.
if (!width) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid token.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_TOKEN);
goto lex_next_token;
}
@@ -7920,17 +7920,17 @@ accept_any(yp_parser_t *parser, size_t count, ...) {
// valid) and create an artificial token instead. This allows us to recover from
// the fact that the token isn't present and continue parsing.
static void
-expect(yp_parser_t *parser, yp_token_type_t type, const char *message) {
+expect(yp_parser_t *parser, yp_token_type_t type, yp_diagnostic_id_t diag_id) {
if (accept(parser, type)) return;
- yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, message);
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id);
parser->previous =
(yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
}
static void
-expect_any(yp_parser_t *parser, const char*message, size_t count, ...) {
+expect_any(yp_parser_t *parser, yp_diagnostic_id_t diag_id, size_t count, ...) {
va_list types;
va_start(types, count);
@@ -7943,13 +7943,13 @@ expect_any(yp_parser_t *parser, const char*message, size_t count, ...) {
va_end(types);
- yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, message);
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id);
parser->previous =
(yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
}
static yp_node_t *
-parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message);
+parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id);
// This function controls whether or not we will attempt to parse an expression
// beginning at the subsequent token. It is used when we are in a context where
@@ -8026,14 +8026,14 @@ token_begins_expression_p(yp_token_type_t type) {
// Parse an expression with the given binding power that may be optionally
// prefixed by the * operator.
static yp_node_t *
-parse_starred_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message) {
+parse_starred_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) {
if (accept(parser, YP_TOKEN_USTAR)) {
yp_token_t operator = parser->previous;
- yp_node_t *expression = parse_expression(parser, binding_power, "Expected expression after `*'.");
+ yp_node_t *expression = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR);
return (yp_node_t *) yp_splat_node_create(parser, &operator, expression);
}
- return parse_expression(parser, binding_power, message);
+ return parse_expression(parser, binding_power, diag_id);
}
// Convert the given node into a valid target node.
@@ -8059,7 +8059,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) {
/* fallthrough */
case YP_NUMBERED_REFERENCE_READ_NODE:
assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_numbered_reference_read_node_t));
- yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Can't set variable");
+ yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY);
/* fallthrough */
case YP_GLOBAL_VARIABLE_READ_NODE:
assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_global_variable_read_node_t));
@@ -8122,7 +8122,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) {
target->type = YP_LOCAL_VARIABLE_TARGET_NODE;
if (token_is_numbered_parameter(message.start, message.end)) {
- yp_diagnostic_list_append(&parser->error_list, message.start, message.end, "reserved for numbered parameter");
+ yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED);
}
return target;
@@ -8166,7 +8166,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) {
// In this case we have a node that we don't know how to convert
// into a target. We need to treat it as an error. For now, we'll
// mark it as an error and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Unexpected write target.");
+ yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_UNEXPECTED);
return target;
}
}
@@ -8191,7 +8191,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod
}
case YP_BACK_REFERENCE_READ_NODE:
case YP_NUMBERED_REFERENCE_READ_NODE:
- yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Can't set variable");
+ yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY);
/* fallthrough */
case YP_GLOBAL_VARIABLE_READ_NODE: {
yp_global_variable_write_node_t *node = yp_global_variable_write_node_create(parser, target, operator, value);
@@ -8263,7 +8263,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod
target = (yp_node_t *) yp_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator);
if (token_is_numbered_parameter(message.start, message.end)) {
- yp_diagnostic_list_append(&parser->error_list, message.start, message.end, "reserved for numbered parameter");
+ yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED);
}
return target;
@@ -8336,7 +8336,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod
// In this case we have a node that we don't know how to convert into a
// target. We need to treat it as an error. For now, we'll mark it as an
// error and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, "Unexpected `='.");
+ yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
return target;
}
}
@@ -8381,14 +8381,14 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b
// others yet.
if (has_splat) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Multiple splats in multi-assignment.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_MULTI_ASSIGN_MULTI_SPLATS);
}
yp_token_t star_operator = parser->previous;
yp_node_t *name = NULL;
if (token_begins_expression_p(parser->current.type)) {
- name = parse_expression(parser, binding_power, "Expected an expression after '*'.");
+ name = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR);
name = parse_target(parser, name);
}
@@ -8401,10 +8401,10 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b
// the node when it returns.
yp_token_t lparen = parser->previous;
- yp_node_t *first_child_target = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected an expression after '('.");
+ yp_node_t *first_child_target = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN);
yp_node_t *child_target = parse_targets(parser, first_child_target, YP_BINDING_POWER_STATEMENT);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected an ')' after multi-assignment.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_AFTER_MULTI);
yp_token_t rparen = parser->previous;
if (YP_NODE_TYPE_P(child_target, YP_MULTI_WRITE_NODE) && first_target == NULL && result->targets.size == 0) {
@@ -8447,7 +8447,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b
// If we get here, then we weren't able to parse anything at all, so
// we need to return a missing node.
yp_node_destroy(parser, (yp_node_t *) result);
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected index after for.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_FOR_INDEX);
return (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end);
}
@@ -8459,7 +8459,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b
return (yp_node_t *) result;
}
- yp_node_t *target = parse_expression(parser, binding_power, "Expected another expression after ','.");
+ yp_node_t *target = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
target = parse_target(parser, target);
yp_multi_write_node_targets_append(result, target);
@@ -8487,7 +8487,7 @@ parse_statements(yp_parser_t *parser, yp_context_t context) {
context_push(parser, context);
while (true) {
- yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression.");
+ yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION);
yp_statements_node_body_append(statements, node);
// If we're recovering from a syntax error, then we need to stop parsing the
@@ -8532,7 +8532,7 @@ parse_statements(yp_parser_t *parser, yp_context_t context) {
while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON));
if (context_terminator(context, &parser->current)) break;
} else {
- expect(parser, YP_TOKEN_NEWLINE, "Expected a newline or semicolon after statement.");
+ expect(parser, YP_TOKEN_NEWLINE, YP_ERR_EXPECT_EOL_AFTER_STATEMENT);
}
}
@@ -8555,9 +8555,9 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) {
yp_node_t *value = NULL;
if (token_begins_expression_p(parser->current.type)) {
- value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after ** in hash.");
+ value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
} else if (yp_parser_local_depth(parser, &operator) == -1) {
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected an expression after ** in hash.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
}
element = (yp_node_t *) yp_assoc_splat_node_create(parser, value, &operator);
@@ -8571,24 +8571,24 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) {
yp_node_t *value = NULL;
if (token_begins_expression_p(parser->current.type)) {
- value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after the label in hash.");
+ value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_EXPRESSION_AFTER_LABEL);
}
element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value);
break;
}
default: {
- yp_node_t *key = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a key in the hash literal.");
+ yp_node_t *key = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_KEY);
yp_token_t operator;
if (yp_symbol_node_label_p(key)) {
operator = not_provided(parser);
} else {
- expect(parser, YP_TOKEN_EQUAL_GREATER, "Expected a => between the key and the value in the hash.");
+ expect(parser, YP_TOKEN_EQUAL_GREATER, YP_ERR_HASH_ROCKET);
operator = parser->previous;
}
- yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal.");
+ yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE);
element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value);
break;
}
@@ -8636,7 +8636,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
while (!match_type_p(parser, YP_TOKEN_EOF)) {
if (parsed_block_argument) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected argument after block argument.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_AFTER_BLOCK);
}
yp_node_t *argument = NULL;
@@ -8645,7 +8645,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
case YP_TOKEN_USTAR_STAR:
case YP_TOKEN_LABEL: {
if (parsed_bare_hash) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected bare hash.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_BARE_HASH);
}
yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser);
@@ -8664,9 +8664,9 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
yp_node_t *expression = NULL;
if (token_begins_expression_p(parser->current.type)) {
- expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to be able to parse an argument.");
+ expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT);
} else if (yp_parser_local_depth(parser, &operator) == -1) {
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "unexpected & when parent method is not forwarding.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_AMP);
}
argument = (yp_node_t *)yp_block_argument_node_create(parser, &operator, expression);
@@ -8680,15 +8680,15 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
if (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_COMMA)) {
if (yp_parser_local_depth(parser, &parser->previous) == -1) {
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "unexpected * when parent method is not forwarding.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_STAR);
}
argument = (yp_node_t *) yp_splat_node_create(parser, &operator, NULL);
} else {
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after '*' in argument.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
if (parsed_bare_hash) {
- yp_diagnostic_list_append(&parser->error_list, operator.start, expression->location.end, "Unexpected splat argument after double splat.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, expression->location.end, YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT);
}
argument = (yp_node_t *) yp_splat_node_create(parser, &operator, expression);
@@ -8704,11 +8704,11 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
// If the token begins an expression then this ... was not actually
// argument forwarding but was instead a range.
yp_token_t operator = parser->previous;
- yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_RANGE, "Expected a value after the operator.");
+ yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_RANGE, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
argument = (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right);
} else {
if (yp_parser_local_depth(parser, &parser->previous) == -1) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "unexpected ... when parent method is not forwarding.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
}
argument = (yp_node_t *)yp_forwarding_arguments_node_create(parser, &parser->previous);
@@ -8719,12 +8719,12 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
/* fallthrough */
default: {
if (argument == NULL) {
- argument = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to be able to parse an argument.");
+ argument = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT);
}
if (yp_symbol_node_label_p(argument) || accept(parser, YP_TOKEN_EQUAL_GREATER)) {
if (parsed_bare_hash) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected bare hash argument.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_BARE_HASH);
}
yp_token_t operator;
@@ -8737,7 +8737,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
yp_keyword_hash_node_t *bare_hash = yp_keyword_hash_node_create(parser);
// Finish parsing the one we are part way through
- yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal.");
+ yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE);
argument = (yp_node_t *) yp_assoc_node_create(parser, argument, &operator, value);
yp_keyword_hash_node_elements_append(bare_hash, argument);
@@ -8793,7 +8793,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
// It can recurse infinitely down, and splats are allowed to group arguments.
static yp_required_destructured_parameter_node_t *
parse_required_destructured_parameter(yp_parser_t *parser) {
- expect(parser, YP_TOKEN_PARENTHESIS_LEFT, "Expected '(' to start a required parameter.");
+ expect(parser, YP_TOKEN_PARENTHESIS_LEFT, YP_ERR_EXPECT_LPAREN_REQ_PARAMETER);
yp_token_t opening = parser->previous;
yp_required_destructured_parameter_node_t *node = yp_required_destructured_parameter_node_create(parser, &opening);
@@ -8804,7 +8804,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) {
if (node->parameters.size > 0 && match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) {
if (parsed_splat) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected splat after splat.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT);
}
param = (yp_node_t *) yp_splat_node_create(parser, &parser->previous, NULL);
@@ -8816,7 +8816,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) {
param = (yp_node_t *) parse_required_destructured_parameter(parser);
} else if (accept(parser, YP_TOKEN_USTAR)) {
if (parsed_splat) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected splat after splat.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT);
}
yp_token_t star = parser->previous;
@@ -8831,7 +8831,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) {
param = (yp_node_t *) yp_splat_node_create(parser, &star, value);
parsed_splat = true;
} else {
- expect(parser, YP_TOKEN_IDENTIFIER, "Expected an identifier for a required parameter.");
+ expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EXPECT_IDENT_REQ_PARAMETER);
yp_token_t name = parser->previous;
param = (yp_node_t *) yp_required_parameter_node_create(parser, &name);
@@ -8841,7 +8841,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) {
yp_required_destructured_parameter_node_append_parameter(node, param);
} while (accept(parser, YP_TOKEN_COMMA));
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' to end a required parameter.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_REQ_PARAMETER);
yp_required_destructured_parameter_node_closing_set(node, &parser->previous);
return node;
@@ -8896,12 +8896,12 @@ update_parameter_state(yp_parser_t *parser, yp_token_t *token, yp_parameters_ord
}
if (token->type == YP_TOKEN_USTAR && *current == YP_PARAMETERS_ORDER_AFTER_OPTIONAL) {
- yp_diagnostic_list_append(&parser->error_list, token->start, token->end, "Unexpected parameter *");
+ yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_STAR);
}
if (*current == YP_PARAMETERS_ORDER_NOTHING_AFTER || state > *current) {
// We know what transition we failed on, so we can provide a better error here.
- yp_diagnostic_list_append(&parser->error_list, token->start, token->end, "Unexpected parameter order");
+ yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_ORDER);
} else if (state < *current) {
*current = state;
}
@@ -8956,7 +8956,7 @@ parse_parameters(
if (params->block == NULL) {
yp_parameters_node_block_set(params, param);
} else {
- yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple block parameter");
+ yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_BLOCK_MULTI);
yp_parameters_node_posts_append(params, (yp_node_t *) param);
}
@@ -8964,7 +8964,7 @@ parse_parameters(
}
case YP_TOKEN_UDOT_DOT_DOT: {
if (!allows_forwarding_parameter) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected ...");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
}
if (order > YP_PARAMETERS_ORDER_NOTHING_AFTER) {
update_parameter_state(parser, &parser->current, &order);
@@ -8987,16 +8987,16 @@ parse_parameters(
parser_lex(parser);
switch (parser->previous.type) {
case YP_TOKEN_CONSTANT:
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a constant");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CONSTANT);
break;
case YP_TOKEN_INSTANCE_VARIABLE:
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be an instance variable");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_IVAR);
break;
case YP_TOKEN_GLOBAL_VARIABLE:
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a global variable");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_GLOBAL);
break;
case YP_TOKEN_CLASS_VARIABLE:
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a class variable");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CLASS);
break;
default: break;
}
@@ -9014,7 +9014,7 @@ parse_parameters(
if (accept(parser, YP_TOKEN_EQUAL)) {
yp_token_t operator = parser->previous;
context_push(parser, YP_CONTEXT_DEFAULT_PARAMS);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected to find a default value for the parameter.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT);
yp_optional_parameter_node_t *param = yp_optional_parameter_node_create(parser, &name, &operator, value);
yp_parameters_node_optionals_append(params, param);
@@ -9072,7 +9072,7 @@ parse_parameters(
yp_node_t *value = NULL;
if (token_begins_expression_p(parser->current.type)) {
context_push(parser, YP_CONTEXT_DEFAULT_PARAMS);
- value = parse_expression(parser, binding_power, "Expected to find a default value for the keyword parameter.");
+ value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT_KW);
context_pop(parser);
}
@@ -9113,7 +9113,7 @@ parse_parameters(
if (params->rest == NULL) {
yp_parameters_node_rest_set(params, param);
} else {
- yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple splat parameters.");
+ yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI);
yp_parameters_node_posts_append(params, (yp_node_t *) param);
}
@@ -9147,7 +9147,7 @@ parse_parameters(
if (params->keyword_rest == NULL) {
yp_parameters_node_keyword_rest_set(params, param);
} else {
- yp_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, "Unexpected multiple double splat parameters.");
+ yp_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI);
yp_parameters_node_posts_append(params, param);
}
@@ -9165,11 +9165,11 @@ parse_parameters(
if (params->rest == NULL) {
yp_parameters_node_rest_set(params, param);
} else {
- yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple splat parameters.");
+ yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI);
yp_parameters_node_posts_append(params, (yp_node_t *) param);
}
} else {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected ','.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PARAMETER_WILD_LOOSE_COMMA);
}
}
@@ -9210,7 +9210,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) {
parser_lex(parser);
yp_rescue_node_operator_set(rescue, &parser->previous);
- yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an exception variable after `=>` in rescue statement.");
+ yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE);
reference = parse_target(parser, reference);
yp_rescue_node_reference_set(rescue, reference);
@@ -9228,7 +9228,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) {
// we'll attempt to parse it here and any others delimited by commas.
do {
- yp_node_t *expression = parse_starred_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to find a rescued expression.");
+ yp_node_t *expression = parse_starred_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_RESCUE_EXPRESSION);
yp_rescue_node_exceptions_append(rescue, expression);
// If we hit a newline, then this is the end of the rescue expression. We
@@ -9240,7 +9240,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) {
if (accept(parser, YP_TOKEN_EQUAL_GREATER)) {
yp_rescue_node_operator_set(rescue, &parser->previous);
- yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an exception variable after `=>` in rescue statement.");
+ yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE);
reference = parse_target(parser, reference);
yp_rescue_node_reference_set(rescue, reference);
@@ -9254,7 +9254,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) {
if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) {
accept(parser, YP_TOKEN_KEYWORD_THEN);
} else {
- expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a terminator after rescue clause.");
+ expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_RESCUE_TERM);
}
if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) {
@@ -9374,7 +9374,7 @@ parse_block_parameters(
yp_block_parameters_node_t *block_parameters = yp_block_parameters_node_create(parser, parameters, opening);
if (accept(parser, YP_TOKEN_SEMICOLON)) {
do {
- expect(parser, YP_TOKEN_IDENTIFIER, "Expected a local variable name.");
+ expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE);
yp_parser_local_add_token(parser, &parser->previous);
yp_block_local_variable_node_t *local = yp_block_local_variable_node_create(parser, &parser->previous);
@@ -9406,7 +9406,7 @@ parse_block(yp_parser_t *parser) {
parameters = parse_block_parameters(parser, true, &block_parameters_opening, false);
accept(parser, YP_TOKEN_NEWLINE);
parser->command_start = true;
- expect(parser, YP_TOKEN_PIPE, "Expected block parameters to end with '|'.");
+ expect(parser, YP_TOKEN_PIPE, YP_ERR_BLOCK_PARAM_PIPE_TERM);
}
yp_block_parameters_node_closing_set(parameters, &parser->previous);
@@ -9420,7 +9420,7 @@ parse_block(yp_parser_t *parser) {
statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_BLOCK_BRACES);
}
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected block beginning with '{' to end with '}'.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BLOCK_TERM_BRACE);
} else {
if (!match_type_p(parser, YP_TOKEN_KEYWORD_END)) {
if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE)) {
@@ -9435,7 +9435,7 @@ parse_block(yp_parser_t *parser) {
}
}
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected block beginning with 'do' to end with 'end'.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BLOCK_TERM_END);
}
yp_constant_id_list_t locals = parser->current_scope->locals;
@@ -9462,7 +9462,7 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept
yp_accepts_block_stack_push(parser, true);
parse_arguments(parser, arguments, true, YP_TOKEN_PARENTHESIS_RIGHT);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ')' to close the argument list.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_ARGUMENT_TERM_PAREN);
yp_accepts_block_stack_pop(parser);
arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
@@ -9502,7 +9502,8 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
yp_token_t keyword = parser->previous;
context_push(parser, YP_CONTEXT_PREDICATE);
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, "Expected to find a predicate for the conditional.");
+ yp_diagnostic_id_t error_id = context == YP_CONTEXT_IF ? YP_ERR_CONDITIONAL_IF_PREDICATE : YP_ERR_CONDITIONAL_UNLESS_PREDICATE;
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, error_id);
// Predicates are closed by a term, a "then", or a term and then a "then".
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
@@ -9540,7 +9541,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
if (context == YP_CONTEXT_IF) {
while (accept(parser, YP_TOKEN_KEYWORD_ELSIF)) {
yp_token_t elsif_keyword = parser->previous;
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, "Expected to find a predicate for the elsif clause.");
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, YP_ERR_CONDITIONAL_ELSIF_PREDICATE);
// Predicates are closed by a term, a "then", or a term and then a "then".
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
@@ -9567,7 +9568,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
yp_accepts_block_stack_pop(parser);
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `else` clause.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM_ELSE);
yp_else_node_t *else_node = yp_else_node_create(parser, &else_keyword, else_statements, &parser->previous);
@@ -9583,7 +9584,8 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) {
break;
}
} else {
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close conditional statement.");
+ // We should specialize this error message to refer to 'if' or 'unless' explicitly.
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM);
}
// Set the appropriate end location for all of the nodes in the subtree.
@@ -9733,7 +9735,7 @@ parse_string_part(yp_parser_t *parser) {
parser->brace_nesting = brace_nesting;
lex_state_set(parser, state);
- expect(parser, YP_TOKEN_EMBEXPR_END, "Expected a closing delimiter for an embedded expression.");
+ expect(parser, YP_TOKEN_EMBEXPR_END, YP_ERR_EMBEXPR_END);
yp_token_t closing = parser->previous;
return (yp_node_t *) yp_embedded_statements_node_create(parser, &opening, statements, &closing);
@@ -9787,7 +9789,7 @@ parse_string_part(yp_parser_t *parser) {
// we'll not attempt to lex this token and instead just return a
// missing node.
default:
- expect(parser, YP_TOKEN_IDENTIFIER, "Expected a valid embedded variable.");
+ expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EMBVAR_INVALID);
variable = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end);
break;
}
@@ -9796,7 +9798,7 @@ parse_string_part(yp_parser_t *parser) {
}
default:
parser_lex(parser);
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Could not understand string part");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CANNOT_PARSE_STRING_PART);
return NULL;
}
}
@@ -9827,7 +9829,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
symbol = parser->previous;
break;
default:
- expect(parser, YP_TOKEN_IDENTIFIER, "Expected symbol.");
+ expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_SYMBOL_INVALID);
symbol = parser->previous;
break;
}
@@ -9871,7 +9873,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
}
if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state);
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated symbol.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_INTERPOLATED);
return (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous);
}
@@ -9886,7 +9888,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
if (next_state != YP_LEX_STATE_NONE) {
lex_state_set(parser, next_state);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a dynamic symbol.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_DYNAMIC);
return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL);
}
@@ -9914,7 +9916,7 @@ parse_undef_argument(yp_parser_t *parser) {
return parse_symbol(parser, &lex_mode, YP_LEX_STATE_NONE);
}
default:
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a bare word or symbol argument.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_UNDEF_ARGUMENT);
return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end);
}
}
@@ -9956,7 +9958,7 @@ parse_alias_argument(yp_parser_t *parser, bool first) {
parser_lex(parser);
return (yp_node_t *) yp_global_variable_read_node_create(parser, &parser->previous);
default:
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a bare word, symbol or global variable argument.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ALIAS_ARGUMENT);
return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end);
}
}
@@ -10175,7 +10177,7 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu
}
static yp_node_t *
-parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message);
+parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id);
// Accept any number of constants joined by :: delimiters.
static yp_node_t *
@@ -10184,7 +10186,7 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) {
// path nodes.
while (accept(parser, YP_TOKEN_COLON_COLON)) {
yp_token_t delimiter = parser->previous;
- expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after the :: operator.");
+ expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous);
node = (yp_node_t *)yp_constant_path_node_create(parser, node, &delimiter, child);
@@ -10206,9 +10208,9 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) {
accept(parser, YP_TOKEN_NEWLINE);
if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) {
- inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator.");
+ inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression.");
+ expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET);
}
closing = parser->previous;
@@ -10217,8 +10219,8 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) {
opening = parser->previous;
if (!accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) {
- inner = parse_pattern(parser, true, "Expected a pattern expression after the ( operator.");
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ) to close the pattern expression.");
+ inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN);
}
closing = parser->previous;
@@ -10343,7 +10345,7 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) {
if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) {
// Here we have a value for the first assoc in the list, so we will parse it
// now and update the first assoc.
- yp_node_t *value = parse_pattern(parser, false, "Expected a pattern expression after the key.");
+ yp_node_t *value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY);
yp_assoc_node_t *assoc = (yp_assoc_node_t *) first_assoc;
assoc->base.location.end = value->location.end;
@@ -10373,12 +10375,12 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) {
if (match_type_p(parser, YP_TOKEN_USTAR_STAR)) {
assoc = parse_pattern_keyword_rest(parser);
} else {
- expect(parser, YP_TOKEN_LABEL, "Expected a label after the `,'.");
+ expect(parser, YP_TOKEN_LABEL, YP_ERR_PATTERN_LABEL_AFTER_COMMA);
yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous);
yp_node_t *value = NULL;
if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) {
- value = parse_pattern(parser, false, "Expected a pattern expression after the key.");
+ value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY);
} else {
const yp_location_t *value_loc = &((yp_symbol_node_t *) key)->value_loc;
yp_parser_local_add_location(parser, value_loc->start, value_loc->end);
@@ -10399,7 +10401,7 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) {
// Parse a pattern expression primitive.
static yp_node_t *
-parse_pattern_primitive(yp_parser_t *parser, const char *message) {
+parse_pattern_primitive(yp_parser_t *parser, yp_diagnostic_id_t diag_id) {
switch (parser->current.type) {
case YP_TOKEN_IDENTIFIER: {
parser_lex(parser);
@@ -10418,11 +10420,11 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
// Otherwise, we'll parse the inner pattern, then deal with it depending
// on the type it returns.
- yp_node_t *inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator.");
+ yp_node_t *inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression.");
+ expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET);
yp_token_t closing = parser->previous;
switch (YP_NODE_TYPE(inner)) {
@@ -10486,15 +10488,15 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
key = parse_pattern_keyword_rest(parser);
break;
case YP_TOKEN_STRING_BEGIN:
- key = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected a key in the hash pattern.");
+ key = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_HASH_KEY);
if (!yp_symbol_node_label_p(key)) {
- yp_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, "Expected a label as the key in the hash pattern.");
+ yp_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, YP_ERR_PATTERN_HASH_KEY_LABEL);
}
break;
default:
parser_lex(parser);
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a key in the hash pattern.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_HASH_KEY);
key = (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end);
break;
}
@@ -10503,7 +10505,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
node = parse_pattern_hash(parser, (yp_node_t *) yp_assoc_node_create(parser, key, &operator, NULL));
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected a } to close the pattern expression.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_PATTERN_TERM_BRACE);
yp_token_t closing = parser->previous;
node->base.location.start = opening.start;
@@ -10525,18 +10527,18 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
// expression as the right side of the range.
switch (parser->current.type) {
case YP_CASE_PRIMITIVE: {
- yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected an expression after the range operator.");
+ yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right);
}
default: {
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected an expression after the range operator.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end);
return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right);
}
}
}
case YP_CASE_PRIMITIVE: {
- yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_MAX, message);
+ yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_MAX, diag_id);
// Now that we have a primitive, we need to check if it's part of a range.
if (accept_any(parser, 2, YP_TOKEN_DOT_DOT, YP_TOKEN_DOT_DOT_DOT)) {
@@ -10547,7 +10549,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
// node. Otherwise, we'll create an endless range.
switch (parser->current.type) {
case YP_CASE_PRIMITIVE: {
- yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected an expression after the range operator.");
+ yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
return (yp_node_t *) yp_range_node_create(parser, node, &operator, right);
}
default:
@@ -10607,17 +10609,17 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
yp_token_t lparen = parser->current;
parser_lex(parser);
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected an expression after the pin operator.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN);
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis after the expression.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN);
return (yp_node_t *) yp_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous);
}
default: {
// If we get here, then we have a pin operator followed by something
// not understood. We'll create a missing node and return that.
- yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected a variable after the pin operator.");
+ yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN);
yp_node_t *variable = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end);
return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable);
}
@@ -10627,7 +10629,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
yp_token_t delimiter = parser->current;
parser_lex(parser);
- expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after the :: operator.");
+ expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous);
yp_constant_path_node_t *node = yp_constant_path_node_create(parser, NULL, &delimiter, child);
@@ -10641,7 +10643,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
return parse_pattern_constant_path(parser, node);
}
default:
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, message);
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id);
return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end);
}
}
@@ -10649,7 +10651,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) {
// Parse any number of primitives joined by alternation and ended optionally by
// assignment.
static yp_node_t *
-parse_pattern_primitives(yp_parser_t *parser, const char *message) {
+parse_pattern_primitives(yp_parser_t *parser, yp_diagnostic_id_t diag_id) {
yp_node_t *node = NULL;
do {
@@ -10666,9 +10668,9 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) {
case YP_TOKEN_UDOT_DOT_DOT:
case YP_CASE_PRIMITIVE: {
if (node == NULL) {
- node = parse_pattern_primitive(parser, message);
+ node = parse_pattern_primitive(parser, diag_id);
} else {
- yp_node_t *right = parse_pattern_primitive(parser, "Expected to be able to parse a pattern after `|'.");
+ yp_node_t *right = parse_pattern_primitive(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE);
node = (yp_node_t *) yp_alternation_pattern_node_create(parser, node, right, &operator);
}
@@ -10679,13 +10681,13 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) {
if (node != NULL) {
yp_node_destroy(parser, node);
}
- node = parse_pattern(parser, false, "Expected a pattern after the opening parenthesis.");
+ node = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis after the pattern.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN);
break;
}
default: {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, message);
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id);
yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end);
if (node == NULL) {
@@ -10704,7 +10706,7 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) {
while (accept(parser, YP_TOKEN_EQUAL_GREATER)) {
yp_token_t operator = parser->previous;
- expect(parser, YP_TOKEN_IDENTIFIER, "Expected an identifier after the `=>' operator.");
+ expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_PATTERN_IDENT_AFTER_HROCKET);
yp_token_t identifier = parser->previous;
yp_parser_local_add_token(parser, &identifier);
@@ -10717,7 +10719,7 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) {
// Parse a pattern matching expression.
static yp_node_t *
-parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) {
+parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id) {
yp_node_t *node = NULL;
bool leading_rest = false;
@@ -10745,7 +10747,7 @@ parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) {
}
/* fallthrough */
default:
- node = parse_pattern_primitives(parser, message);
+ node = parse_pattern_primitives(parser, diag_id);
break;
}
@@ -10777,12 +10779,12 @@ parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) {
// will continue to parse the rest of the patterns, but we will indicate
// it as an error.
if (trailing_rest) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected rest pattern.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_REST);
}
trailing_rest = true;
} else {
- node = parse_pattern_primitives(parser, "Expected a pattern after the comma.");
+ node = parse_pattern_primitives(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA);
}
yp_node_list_append(&nodes, node);
@@ -10850,7 +10852,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
if (yp_array_node_size(array) != 0) {
- expect(parser, YP_TOKEN_COMMA, "Expected a separator for the elements in an array.");
+ expect(parser, YP_TOKEN_COMMA, YP_ERR_ARRAY_SEPARATOR);
}
// If we have a right bracket immediately following a comma, this is
@@ -10862,11 +10864,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_USTAR)) {
yp_token_t operator = parser->previous;
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after '*' in the array.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION_AFTER_STAR);
element = (yp_node_t *) yp_splat_node_create(parser, &operator, expression);
} else if (match_any_type_p(parser, 2, YP_TOKEN_LABEL, YP_TOKEN_USTAR_STAR)) {
if (parsed_bare_hash) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected bare hash.");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EXPRESSION_BARE_HASH);
}
yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser);
@@ -10878,11 +10880,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parsed_bare_hash = true;
} else {
- element = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an element for the array.");
+ element = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION);
if (yp_symbol_node_label_p(element) || accept(parser, YP_TOKEN_EQUAL_GREATER)) {
if (parsed_bare_hash) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected bare hash.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPRESSION_BARE_HASH);
}
yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser);
@@ -10894,7 +10896,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
operator = not_provided(parser);
}
- yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal.");
+ yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE);
yp_node_t *assoc = (yp_node_t *) yp_assoc_node_create(parser, element, &operator, value);
yp_keyword_hash_node_elements_append(hash, assoc);
@@ -10912,7 +10914,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a closing bracket for the array.");
+ expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_ARRAY_TERM);
yp_array_node_close_set(array, &parser->previous);
yp_accepts_block_stack_pop(parser);
@@ -10927,14 +10929,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
// If this is the end of the file or we match a right parenthesis, then
// we have an empty parentheses node, and we can immediately return.
if (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_EOF)) {
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
return (yp_node_t *) yp_parentheses_node_create(parser, &opening, NULL, &parser->previous);
}
// Otherwise, we're going to parse the first statement in the list of
// statements within the parentheses.
yp_accepts_block_stack_push(parser, true);
- yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression.");
+ yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION);
while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON));
// If we hit a right parenthesis, then we're done parsing the parentheses
@@ -10992,7 +10994,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
// Ignore semicolon without statements before them
if (accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE)) continue;
- yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression.");
+ yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION);
yp_statements_node_body_append(statements, node);
// If we're recovering from a syntax error, then we need to stop parsing the
@@ -11009,7 +11011,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
context_pop(parser);
yp_accepts_block_stack_pop(parser);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
return (yp_node_t *) yp_parentheses_node_create(parser, &opening, (yp_node_t *) statements, &parser->previous);
}
@@ -11024,7 +11026,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
yp_accepts_block_stack_pop(parser);
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected a closing delimiter for a hash literal.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_HASH_TERM);
yp_hash_node_closing_loc_set(node, &parser->previous);
return (yp_node_t *) node;
@@ -11084,7 +11086,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t delimiter = parser->previous;
- expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after ::.");
+ expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous);
yp_node_t *node = (yp_node_t *)yp_constant_path_node_create(parser, NULL, &delimiter, constant);
@@ -11100,7 +11102,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_token_t operator = parser->current;
parser_lex(parser);
- yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right);
}
case YP_TOKEN_FLOAT:
@@ -11229,7 +11231,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
lex_state_set(parser, YP_LEX_STATE_END);
- expect(parser, YP_TOKEN_HEREDOC_END, "Expected a closing delimiter for heredoc.");
+ expect(parser, YP_TOKEN_HEREDOC_END, YP_ERR_HEREDOC_TERM);
if (quote == YP_HEREDOC_QUOTE_BACKTICK) {
assert(YP_NODE_TYPE_P(node, YP_INTERPOLATED_X_STRING_NODE));
@@ -11254,7 +11256,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
return (yp_node_t *) yp_string_concat_node_create(
parser,
node,
- parse_expression(parser, YP_BINDING_POWER_CALL, "Expected string on the right side of concatenation.")
+ parse_expression(parser, YP_BINDING_POWER_CALL, YP_ERR_CANNOT_PARSE_EXPRESSION)
);
} else {
return node;
@@ -11302,7 +11304,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
case YP_SYMBOL_NODE:
case YP_INTERPOLATED_SYMBOL_NODE: {
if (!YP_NODE_TYPE_P(old_name, YP_SYMBOL_NODE) && !YP_NODE_TYPE_P(old_name, YP_INTERPOLATED_SYMBOL_NODE)) {
- yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Expected a bare word or symbol argument.");
+ yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT);
}
break;
}
@@ -11311,10 +11313,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
case YP_GLOBAL_VARIABLE_READ_NODE: {
if (YP_NODE_TYPE_P(old_name, YP_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_GLOBAL_VARIABLE_READ_NODE)) {
if (YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE)) {
- yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Can't make alias for number variables.");
+ yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT);
}
} else {
- yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Expected a global variable.");
+ yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT);
}
break;
}
@@ -11336,7 +11338,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
) {
predicate = NULL;
} else {
- predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected a value after case keyword.");
+ predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CASE_EXPRESSION_AFTER_CASE);
while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON));
}
@@ -11360,14 +11362,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
do {
if (accept(parser, YP_TOKEN_USTAR)) {
yp_token_t operator = parser->previous;
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after `*' operator.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR);
yp_splat_node_t *splat_node = yp_splat_node_create(parser, &operator, expression);
yp_when_node_conditions_append(when_node, (yp_node_t *) splat_node);
if (YP_NODE_TYPE_P(expression, YP_MISSING_NODE)) break;
} else {
- yp_node_t *condition = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after when keyword.");
+ yp_node_t *condition = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CASE_EXPRESSION_AFTER_WHEN);
yp_when_node_conditions_append(when_node, condition);
if (YP_NODE_TYPE_P(condition, YP_MISSING_NODE)) break;
@@ -11377,7 +11379,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) {
accept(parser, YP_TOKEN_KEYWORD_THEN);
} else {
- expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a delimiter after the predicates of a `when' clause.");
+ expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER);
}
if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_END)) {
@@ -11401,18 +11403,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t in_keyword = parser->previous;
- yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `in' keyword.");
+ yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_IN);
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
// Since we're in the top-level of the case-in node we need to check
// for guard clauses in the form of `if` or `unless` statements.
if (accept(parser, YP_TOKEN_KEYWORD_IF_MODIFIER)) {
yp_token_t keyword = parser->previous;
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after guard keyword.");
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_IF_PREDICATE);
pattern = (yp_node_t *) yp_if_node_modifier_create(parser, pattern, &keyword, predicate);
} else if (accept(parser, YP_TOKEN_KEYWORD_UNLESS_MODIFIER)) {
yp_token_t keyword = parser->previous;
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after guard keyword.");
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_UNLESS_PREDICATE);
pattern = (yp_node_t *) yp_unless_node_modifier_create(parser, pattern, &keyword, predicate);
}
@@ -11427,7 +11429,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
then_keyword = not_provided(parser);
}
} else {
- expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a delimiter after the predicates of an `in' clause.");
+ expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER);
then_keyword = parser->previous;
}
@@ -11450,7 +11452,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
if (accept(parser, YP_TOKEN_KEYWORD_ELSE)) {
if (case_node->conditions.size < 1) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected else without no when clauses in case statement.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CASE_LONELY_ELSE);
}
yp_token_t else_keyword = parser->previous;
@@ -11465,7 +11467,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_case_node_consequent_set(case_node, else_node);
}
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected case statement to end with an end keyword.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CASE_TERM);
yp_case_node_end_keyword_loc_set(case_node, &parser->previous);
return (yp_node_t *) case_node;
}
@@ -11486,7 +11488,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_begin_node_t *begin_node = yp_begin_node_create(parser, &begin_keyword, begin_statements);
parse_rescues(parser, begin_node);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `begin` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BEGIN_TERM);
begin_node->base.location.end = parser->previous.end;
yp_begin_node_end_keyword_set(begin_node, &parser->previous);
@@ -11495,7 +11497,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
&parser->error_list,
begin_node->else_clause->base.location.start,
begin_node->else_clause->base.location.end,
- "else without rescue is useless"
+ YP_ERR_BEGIN_LONELY_ELSE
);
}
@@ -11505,11 +11507,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t keyword = parser->previous;
- expect(parser, YP_TOKEN_BRACE_LEFT, "Expected '{' after 'BEGIN'.");
+ expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_BEGIN_UPCASE_BRACE);
yp_token_t opening = parser->previous;
yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_PREEXE);
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected '}' after 'BEGIN' statements.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BEGIN_UPCASE_TERM);
return (yp_node_t *) yp_pre_execution_node_create(parser, &keyword, &opening, statements, &parser->previous);
}
case YP_TOKEN_KEYWORD_BREAK:
@@ -11542,7 +11544,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
(parser->current_context->context == YP_CONTEXT_CLASS) ||
(parser->current_context->context == YP_CONTEXT_MODULE)
) {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid return in class/module body");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_RETURN_INVALID);
}
return (yp_node_t *) yp_return_node_create(parser, &keyword, arguments.arguments);
}
@@ -11580,7 +11582,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_LESS_LESS)) {
yp_token_t operator = parser->previous;
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_NOT, "Expected to find an expression after `<<`.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_NOT, YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS);
yp_parser_scope_push(parser, true);
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
@@ -11597,7 +11599,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements);
}
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `class` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM);
yp_constant_id_list_t locals = parser->current_scope->locals;
yp_parser_scope_pop(parser);
@@ -11605,10 +11607,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
return (yp_node_t *) yp_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
}
- yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a class name after `class`.");
+ yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_CLASS_NAME);
yp_token_t name = parser->previous;
if (name.type != YP_TOKEN_CONSTANT) {
- yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected a constant name after `class`.");
+ yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_CLASS_NAME);
}
yp_token_t inheritance_operator;
@@ -11621,7 +11623,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser->command_start = true;
parser_lex(parser);
- superclass = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected to find a superclass after `<`.");
+ superclass = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CLASS_SUPERCLASS);
} else {
inheritance_operator = not_provided(parser);
superclass = NULL;
@@ -11642,10 +11644,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements);
}
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `class` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM);
if (context_def_p(parser)) {
- yp_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, "Class definition in method body");
+ yp_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, YP_ERR_CLASS_IN_METHOD);
}
yp_constant_id_list_t locals = parser->current_scope->locals;
@@ -11684,7 +11686,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
name = parse_method_definition_name(parser);
if (name.type == YP_TOKEN_MISSING) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER);
}
} else {
name = parser->previous;
@@ -11752,7 +11754,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
name = parse_method_definition_name(parser);
if (name.type == YP_TOKEN_MISSING) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER);
}
} else {
name = identifier;
@@ -11762,13 +11764,13 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
case YP_TOKEN_PARENTHESIS_LEFT: {
parser_lex(parser);
yp_token_t lparen = parser->previous;
- yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse receiver.");
+ yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_DEF_RECEIVER);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected closing ')' for receiver.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
yp_token_t rparen = parser->previous;
lex_state_set(parser, YP_LEX_STATE_FNAME);
- expect_any(parser, "Expected '.' or '::' after receiver", 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON);
+ expect_any(parser, YP_ERR_DEF_RECEIVER_TERM, 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON);
operator = parser->previous;
receiver = (yp_node_t *) yp_parentheses_node_create(parser, &lparen, expression, &rparen);
@@ -11782,7 +11784,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
name = parse_method_definition_name(parser);
if (name.type == YP_TOKEN_MISSING) {
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME);
}
break;
}
@@ -11805,7 +11807,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
lex_state_set(parser, YP_LEX_STATE_BEG);
parser->command_start = true;
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after left parenthesis.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_DEF_PARAMS_TERM_PAREN);
rparen = parser->previous;
break;
}
@@ -11836,18 +11838,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_EQUAL)) {
if (token_is_setter_name(&name)) {
- yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Setter method cannot be defined in an endless method definition");
+ yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_DEF_ENDLESS_SETTER);
}
equal = parser->previous;
context_push(parser, YP_CONTEXT_DEF);
statements = (yp_node_t *) yp_statements_node_create(parser);
- yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_DEFINED + 1, "Expected to be able to parse body of endless method definition.");
+ yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_DEFINED + 1, YP_ERR_DEF_ENDLESS);
if (accept(parser, YP_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
yp_token_t rescue_keyword = parser->previous;
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the rescue keyword.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE);
yp_rescue_modifier_node_t *rescue_node = yp_rescue_modifier_node_create(parser, statement, &rescue_keyword, value);
statement = (yp_node_t *)rescue_node;
}
@@ -11861,7 +11863,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (lparen.type == YP_TOKEN_NOT_PROVIDED) {
lex_state_set(parser, YP_LEX_STATE_BEG);
parser->command_start = true;
- expect_any(parser, "Expected a terminator after the parameters", 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
+ expect_any(parser, YP_ERR_DEF_PARAMS_TERM, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
} else {
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
}
@@ -11882,7 +11884,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_accepts_block_stack_pop(parser);
yp_do_loop_stack_pop(parser);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `def` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_DEF_TERM);
end_keyword = parser->previous;
}
@@ -11914,18 +11916,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) {
lparen = parser->previous;
- expression = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `defined?`.");
+ expression = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_DEFINED_EXPRESSION);
if (parser->recovering) {
rparen = not_provided(parser);
} else {
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'defined?' expression.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
rparen = parser->previous;
}
} else {
lparen = not_provided(parser);
rparen = not_provided(parser);
- expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `defined?`.");
+ expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_DEFINED_EXPRESSION);
}
return (yp_node_t *) yp_defined_node_create(
@@ -11940,11 +11942,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t keyword = parser->previous;
- expect(parser, YP_TOKEN_BRACE_LEFT, "Expected '{' after 'END'.");
+ expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_END_UPCASE_BRACE);
yp_token_t opening = parser->previous;
yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_POSTEXE);
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected '}' after 'END' statements.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_END_UPCASE_TERM);
return (yp_node_t *) yp_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous);
}
case YP_TOKEN_KEYWORD_FALSE:
@@ -11957,10 +11959,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_node_t *index = parse_targets(parser, NULL, YP_BINDING_POWER_INDEX);
yp_do_loop_stack_push(parser, true);
- expect(parser, YP_TOKEN_KEYWORD_IN, "Expected keyword in.");
+ expect(parser, YP_TOKEN_KEYWORD_IN, YP_ERR_FOR_IN);
yp_token_t in_keyword = parser->previous;
- yp_node_t *collection = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected collection.");
+ yp_node_t *collection = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_FOR_COLLECTION);
yp_do_loop_stack_pop(parser);
yp_token_t do_keyword;
@@ -11975,7 +11977,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (!accept(parser, YP_TOKEN_KEYWORD_END)) {
statements = parse_statements(parser, YP_CONTEXT_FOR);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close for loop.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_FOR_TERM);
}
return (yp_node_t *) yp_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous);
@@ -12024,17 +12026,17 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) {
arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
} else {
- receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`.");
+ receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_NOT_EXPRESSION);
yp_flip_flop(receiver);
if (!parser->recovering) {
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'not' expression.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
}
}
} else {
- receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `not`.");
+ receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_NOT_EXPRESSION);
yp_flip_flop(receiver);
}
@@ -12047,7 +12049,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t module_keyword = parser->previous;
- yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a module name after `module`.");
+ yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_MODULE_NAME);
yp_token_t name;
// If we can recover from a syntax error that occurred while parsing
@@ -12060,7 +12062,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
while (accept(parser, YP_TOKEN_COLON_COLON)) {
yp_token_t double_colon = parser->previous;
- expect(parser, YP_TOKEN_CONSTANT, "Expected to find a module name after `::`.");
+ expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous);
constant_path = (yp_node_t *) yp_constant_path_node_create(parser, constant_path, &double_colon, constant);
@@ -12071,7 +12073,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
// syntax error. We handle that here as well.
name = parser->previous;
if (name.type != YP_TOKEN_CONSTANT) {
- yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected to find a module name after `module`.");
+ yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_MODULE_NAME);
}
yp_parser_scope_push(parser, true);
@@ -12092,10 +12094,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_constant_id_list_t locals = parser->current_scope->locals;
yp_parser_scope_pop(parser);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `module` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_MODULE_TERM);
if (context_def_p(parser)) {
- yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, "Module definition in method body");
+ yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, YP_ERR_MODULE_IN_METHOD);
}
return (yp_node_t *) yp_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous);
@@ -12120,7 +12122,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t keyword = parser->previous;
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected predicate expression after `until`.");
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_UNTIL_PREDICATE);
yp_do_loop_stack_pop(parser);
accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
@@ -12131,7 +12133,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
statements = parse_statements(parser, YP_CONTEXT_UNTIL);
yp_accepts_block_stack_pop(parser);
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `until` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_UNTIL_TERM);
}
return (yp_node_t *) yp_until_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
@@ -12141,7 +12143,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t keyword = parser->previous;
- yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected predicate expression after `while`.");
+ yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_WHILE_PREDICATE);
yp_do_loop_stack_pop(parser);
accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
@@ -12152,7 +12154,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
statements = parse_statements(parser, YP_CONTEXT_WHILE);
yp_accepts_block_stack_pop(parser);
accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON);
- expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `while` statement.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_WHILE_TERM);
}
return (yp_node_t *) yp_while_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
@@ -12165,7 +12167,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
accept(parser, YP_TOKEN_WORDS_SEP);
if (match_type_p(parser, YP_TOKEN_STRING_END)) break;
- expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a symbol in a `%i` list.");
+ expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_I_LOWER_ELEMENT);
yp_token_t opening = not_provided(parser);
yp_token_t closing = not_provided(parser);
@@ -12174,7 +12176,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_array_node_elements_append(array, symbol);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%i` list.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_LOWER_TERM);
yp_array_node_close_set(array, &parser->previous);
return (yp_node_t *) array;
@@ -12310,7 +12312,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
break;
}
default:
- expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a symbol in a `%I` list.");
+ expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_I_UPPER_ELEMENT);
parser_lex(parser);
break;
}
@@ -12321,7 +12323,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_array_node_elements_append(array, current);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%I` list.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_UPPER_TERM);
yp_array_node_close_set(array, &parser->previous);
return (yp_node_t *) array;
@@ -12337,7 +12339,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
accept(parser, YP_TOKEN_WORDS_SEP);
if (match_type_p(parser, YP_TOKEN_STRING_END)) break;
- expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a string in a `%w` list.");
+ expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_W_LOWER_ELEMENT);
yp_token_t opening = not_provided(parser);
yp_token_t closing = not_provided(parser);
@@ -12345,7 +12347,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_array_node_elements_append(array, string);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%w` list.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_LOWER_TERM);
yp_array_node_close_set(array, &parser->previous);
return (yp_node_t *) array;
@@ -12461,7 +12463,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
break;
}
default:
- expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a string in a `%W` list.");
+ expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_W_UPPER_ELEMENT);
parser_lex(parser);
break;
}
@@ -12472,7 +12474,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_array_node_elements_append(array, current);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%W` list.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_UPPER_TERM);
yp_array_node_close_set(array, &parser->previous);
return (yp_node_t *) array;
@@ -12536,7 +12538,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
}
- expect(parser, YP_TOKEN_REGEXP_END, "Expected a closing delimiter for a regular expression.");
+ expect(parser, YP_TOKEN_REGEXP_END, YP_ERR_REGEXP_TERM);
yp_interpolated_regular_expression_node_closing_set(node, &parser->previous);
return (yp_node_t *) node;
@@ -12600,7 +12602,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an xstring.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_XSTRING_TERM);
yp_interpolated_xstring_node_closing_set(node, &parser->previous);
return (yp_node_t *) node;
}
@@ -12618,7 +12620,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_node_t *name = NULL;
if (token_begins_expression_p(parser->current.type)) {
- name = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an expression after '*'.");
+ name = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR);
}
yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &operator, name);
@@ -12628,7 +12630,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t operator = parser->previous;
- yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary !.");
+ yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_BANG);
yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!");
yp_flip_flop(receiver);
@@ -12638,7 +12640,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t operator = parser->previous;
- yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary ~.");
+ yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_TILDE);
yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "~");
return (yp_node_t *) node;
@@ -12647,7 +12649,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t operator = parser->previous;
- yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary -.");
+ yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS);
yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "-@");
return (yp_node_t *) node;
@@ -12656,7 +12658,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t operator = parser->previous;
- yp_node_t *node = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary -.");
+ yp_node_t *node = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS);
switch (YP_NODE_TYPE(node)) {
case YP_INTEGER_NODE:
@@ -12695,7 +12697,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after left parenthesis.");
+ expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN);
yp_block_parameters_node_closing_set(params, &parser->previous);
break;
@@ -12722,10 +12724,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (!accept(parser, YP_TOKEN_BRACE_RIGHT)) {
body = (yp_node_t *) parse_statements(parser, YP_CONTEXT_LAMBDA_BRACES);
- expect(parser, YP_TOKEN_BRACE_RIGHT, "Expecting '}' to close lambda block.");
+ expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_LAMBDA_TERM_BRACE);
}
} else {
- expect(parser, YP_TOKEN_KEYWORD_DO, "Expected a 'do' keyword or a '{' to open lambda block.");
+ expect(parser, YP_TOKEN_KEYWORD_DO, YP_ERR_LAMBDA_OPEN);
opening = parser->previous;
if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_END, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) {
@@ -12739,7 +12741,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
body = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) body);
}
- expect(parser, YP_TOKEN_KEYWORD_END, "Expecting 'end' keyword to close lambda block.");
+ expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_LAMBDA_TERM_END);
}
yp_constant_id_list_t locals = parser->current_scope->locals;
@@ -12751,7 +12753,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_token_t operator = parser->previous;
- yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary +.");
+ yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_PLUS);
yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "+@");
return (yp_node_t *) node;
@@ -12793,7 +12795,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
} else if (!lex_interpolation) {
// If we don't accept interpolation then we expect the
// string to start with a single string content node.
- expect(parser, YP_TOKEN_STRING_CONTENT, "Expected string content after opening delimiter.");
+ expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_EXPECT_STRING_CONTENT);
yp_token_t content = parser->previous;
// It is unfortunately possible to have multiple string
@@ -12820,12 +12822,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_node_list_append(&parts, part);
}
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a string literal.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM);
node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
} else if (accept(parser, YP_TOKEN_LABEL_END)) {
node = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL);
} else {
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a string literal.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM);
node = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_MINIMAL);
}
} else if (match_type_p(parser, YP_TOKEN_STRING_CONTENT)) {
@@ -12857,7 +12859,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_LABEL_END)) {
node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
} else {
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated string.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM);
node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
}
}
@@ -12875,7 +12877,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (accept(parser, YP_TOKEN_LABEL_END)) {
node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
} else {
- expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated string.");
+ expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM);
node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
}
}
@@ -12896,7 +12898,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
// parsed. If it cannot be concatenated with the previous
// node, then we'll need to add a syntax error.
if (!YP_NODE_TYPE_P(node, YP_STRING_NODE) && !YP_NODE_TYPE_P(node, YP_INTERPOLATED_STRING_NODE)) {
- yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Unexpected string concatenation.");
+ yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_STRING_CONCATENATION);
}
// Either way we will create a concat node to hold the
@@ -12923,8 +12925,8 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
}
static inline yp_node_t *
-parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power, const char *message) {
- yp_node_t *value = parse_starred_expression(parser, binding_power, message);
+parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) {
+ yp_node_t *value = parse_starred_expression(parser, binding_power, diag_id);
if (previous_binding_power == YP_BINDING_POWER_STATEMENT && (YP_NODE_TYPE_P(value, YP_SPLAT_NODE) || match_type_p(parser, YP_TOKEN_COMMA))) {
yp_token_t opening = not_provided(parser);
@@ -12934,7 +12936,7 @@ parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_
value = (yp_node_t *) array;
while (accept(parser, YP_TOKEN_COMMA)) {
- yp_node_t *element = parse_starred_expression(parser, binding_power, "Expected an element for the array.");
+ yp_node_t *element = parse_starred_expression(parser, binding_power, YP_ERR_ARRAY_ELEMENT);
yp_array_node_elements_append(array, element);
if (YP_NODE_TYPE_P(element, YP_MISSING_NODE)) break;
}
@@ -12963,7 +12965,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
/* fallthrough */
case YP_CASE_WRITABLE: {
parser_lex(parser);
- yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, "Expected a value after =.");
+ yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
return parse_write(parser, node, &token, value);
}
case YP_SPLAT_NODE: {
@@ -12972,7 +12974,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
switch (YP_NODE_TYPE(splat_node->expression)) {
case YP_CASE_WRITABLE:
parser_lex(parser);
- yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, "Expected a value after =.");
+ yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
return parse_write(parser, (yp_node_t *) splat_node, &token, value);
default:
break;
@@ -12985,7 +12987,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
// In this case we have an = sign, but we don't know what it's for. We
// need to treat it as an error. For now, we'll mark it as an error
// and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `='.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
return node;
}
}
@@ -12993,12 +12995,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
switch (YP_NODE_TYPE(node)) {
case YP_BACK_REFERENCE_READ_NODE:
case YP_NUMBERED_REFERENCE_READ_NODE:
- yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
+ yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY);
/* fallthrough */
case YP_GLOBAL_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_global_variable_and_write_node_create(parser, node, &token, value);
yp_node_destroy(parser, node);
@@ -13007,7 +13009,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CLASS_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_class_variable_and_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13016,13 +13018,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CONSTANT_PATH_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
return (yp_node_t *) yp_constant_path_and_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
}
case YP_CONSTANT_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_constant_and_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13031,7 +13033,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_INSTANCE_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_instance_variable_and_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13041,7 +13043,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node;
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth);
yp_node_destroy(parser, node);
@@ -13058,11 +13060,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
- yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter");
+ yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, constant_id, 0);
yp_node_destroy(parser, node);
@@ -13072,12 +13074,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
parser_lex(parser);
node = parse_target(parser, node);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
return (yp_node_t *) yp_call_and_write_node_create(parser, (yp_call_node_t *) node, &token, value);
}
case YP_MULTI_WRITE_NODE: {
parser_lex(parser);
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `&&=' on a multi-write.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_AMPAMPEQ_MULTI_ASSIGN);
return node;
}
default:
@@ -13086,7 +13088,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
// In this case we have an &&= sign, but we don't know what it's for.
// We need to treat it as an error. For now, we'll mark it as an error
// and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `&&='.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
return node;
}
}
@@ -13094,12 +13096,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
switch (YP_NODE_TYPE(node)) {
case YP_BACK_REFERENCE_READ_NODE:
case YP_NUMBERED_REFERENCE_READ_NODE:
- yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
+ yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY);
/* fallthrough */
case YP_GLOBAL_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_global_variable_or_write_node_create(parser, node, &token, value);
yp_node_destroy(parser, node);
@@ -13108,7 +13110,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CLASS_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_class_variable_or_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13117,13 +13119,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CONSTANT_PATH_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
return (yp_node_t *) yp_constant_path_or_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
}
case YP_CONSTANT_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_constant_or_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13132,7 +13134,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_INSTANCE_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_instance_variable_or_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13142,7 +13144,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node;
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth);
yp_node_destroy(parser, node);
@@ -13159,11 +13161,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
- yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter");
+ yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, constant_id, 0);
yp_node_destroy(parser, node);
@@ -13173,12 +13175,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
parser_lex(parser);
node = parse_target(parser, node);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||=");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
return (yp_node_t *) yp_call_or_write_node_create(parser, (yp_call_node_t *) node, &token, value);
}
case YP_MULTI_WRITE_NODE: {
parser_lex(parser);
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `||=' on a multi-write.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN);
return node;
}
default:
@@ -13187,7 +13189,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
// In this case we have an ||= sign, but we don't know what it's for.
// We need to treat it as an error. For now, we'll mark it as an error
// and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `||='.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
return node;
}
}
@@ -13205,12 +13207,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
switch (YP_NODE_TYPE(node)) {
case YP_BACK_REFERENCE_READ_NODE:
case YP_NUMBERED_REFERENCE_READ_NODE:
- yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable");
+ yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY);
/* fallthrough */
case YP_GLOBAL_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_global_variable_operator_write_node_create(parser, node, &token, value);
yp_node_destroy(parser, node);
@@ -13219,7 +13221,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CLASS_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_class_variable_operator_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13228,13 +13230,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CONSTANT_PATH_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_constant_path_operator_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value);
}
case YP_CONSTANT_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_constant_operator_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13243,7 +13245,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_INSTANCE_VARIABLE_READ_NODE: {
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value);
yp_node_destroy(parser, node);
@@ -13253,7 +13255,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node;
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth);
yp_node_destroy(parser, node);
@@ -13270,11 +13272,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
- yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter");
+ yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, constant_id, 0);
yp_node_destroy(parser, node);
@@ -13284,12 +13286,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
node = parse_target(parser, node);
parser_lex(parser);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value);
}
case YP_MULTI_WRITE_NODE: {
parser_lex(parser);
- yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected operator.");
+ yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_OPERATOR_MULTI_ASSIGN);
return node;
}
default:
@@ -13298,7 +13300,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
// In this case we have an operator but we don't know what it's for.
// We need to treat it as an error. For now, we'll mark it as an error
// and just skip right past it.
- yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected operator.");
+ yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return node;
}
}
@@ -13306,14 +13308,14 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_TOKEN_KEYWORD_AND: {
parser_lex(parser);
- yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_and_node_create(parser, node, &token, right);
}
case YP_TOKEN_KEYWORD_OR:
case YP_TOKEN_PIPE_PIPE: {
parser_lex(parser);
- yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_or_node_create(parser, node, &token, right);
}
case YP_TOKEN_EQUAL_TILDE: {
@@ -13324,7 +13326,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
//
// In this case, `foo` should be a method call and not a local yet.
parser_lex(parser);
- yp_node_t *argument = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
// If the receiver of this =~ is a regular expression node, then we need
// to introduce local variables for it based on its named capture groups.
@@ -13375,7 +13377,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_TOKEN_STAR_STAR: {
parser_lex(parser);
- yp_node_t *argument = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (yp_node_t *) yp_call_node_binary_create(parser, node, &token, argument);
}
case YP_TOKEN_AMPERSAND_DOT:
@@ -13402,7 +13404,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
break;
}
default: {
- yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a valid method name");
+ yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_DEF_NAME);
message = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
}
}
@@ -13427,7 +13429,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_node_t *right = NULL;
if (token_begins_expression_p(parser->current.type)) {
- right = parse_expression(parser, binding_power, "Expected a value after the operator.");
+ right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
}
return (yp_node_t *) yp_range_node_create(parser, node, &token, right);
@@ -13436,14 +13438,14 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_token_t keyword = parser->current;
parser_lex(parser);
- yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after `if'.");
+ yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_IF_PREDICATE);
return (yp_node_t *) yp_if_node_modifier_create(parser, node, &keyword, predicate);
}
case YP_TOKEN_KEYWORD_UNLESS_MODIFIER: {
yp_token_t keyword = parser->current;
parser_lex(parser);
- yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after `unless'.");
+ yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNLESS_PREDICATE);
return (yp_node_t *) yp_unless_node_modifier_create(parser, node, &keyword, predicate);
}
case YP_TOKEN_KEYWORD_UNTIL_MODIFIER: {
@@ -13451,7 +13453,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_statements_node_t *statements = yp_statements_node_create(parser);
yp_statements_node_body_append(statements, node);
- yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after 'until'");
+ yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNTIL_PREDICATE);
return (yp_node_t *) yp_until_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0);
}
case YP_TOKEN_KEYWORD_WHILE_MODIFIER: {
@@ -13459,12 +13461,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
yp_statements_node_t *statements = yp_statements_node_create(parser);
yp_statements_node_body_append(statements, node);
- yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after 'while'");
+ yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_WHILE_PREDICATE);
return (yp_node_t *) yp_while_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0);
}
case YP_TOKEN_QUESTION_MARK: {
parser_lex(parser);
- yp_node_t *true_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after '?'");
+ yp_node_t *true_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_TERNARY_EXPRESSION_TRUE);
if (parser->recovering) {
// If parsing the true expression of this ternary resulted in a syntax
@@ -13480,10 +13482,10 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
}
accept(parser, YP_TOKEN_NEWLINE);
- expect(parser, YP_TOKEN_COLON, "Expected ':' after true expression in ternary operator.");
+ expect(parser, YP_TOKEN_COLON, YP_ERR_TERNARY_COLON);
yp_token_t colon = parser->previous;
- yp_node_t *false_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after ':'");
+ yp_node_t *false_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_TERNARY_EXPRESSION_FALSE);
return (yp_node_t *) yp_if_node_ternary_create(parser, node, true_expression, &colon, false_expression);
}
@@ -13552,7 +13554,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
return (yp_node_t *) yp_call_node_shorthand_create(parser, node, &delimiter, &arguments);
}
default: {
- yp_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, "Expected identifier or constant after '::'");
+ yp_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
yp_node_t *child = (yp_node_t *) yp_missing_node_create(parser, delimiter.start, delimiter.end);
return (yp_node_t *)yp_constant_path_node_create(parser, node, &delimiter, child);
}
@@ -13561,7 +13563,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_TOKEN_KEYWORD_RESCUE_MODIFIER: {
parser_lex(parser);
accept(parser, YP_TOKEN_NEWLINE);
- yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the rescue keyword.");
+ yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE);
return (yp_node_t *) yp_rescue_modifier_node_create(parser, node, &token, value);
}
@@ -13578,7 +13580,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
parse_arguments(parser, &arguments, false, YP_TOKEN_BRACKET_RIGHT);
yp_accepts_block_stack_pop(parser);
- expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected ']' to close the bracket expression.");
+ expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_EXPECT_RBRACKET);
}
arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
@@ -13612,7 +13614,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
parser_lex(parser);
- yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `in'.");
+ yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_IN);
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
return (yp_node_t *) yp_match_predicate_node_create(parser, node, pattern, &operator);
@@ -13627,7 +13629,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
parser_lex(parser);
- yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `=>'.");
+ yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET);
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
return (yp_node_t *) yp_match_required_node_create(parser, node, pattern, &operator);
@@ -13645,7 +13647,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
// Consumers of this function should always check parser->recovering to
// determine if they need to perform additional cleanup.
static yp_node_t *
-parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message) {
+parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) {
yp_token_t recovery = parser->previous;
yp_node_t *node = parse_expression_prefix(parser, binding_power);
@@ -13653,7 +13655,7 @@ parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const ch
// parse_expression_prefix is going to be a missing node. In that case we need
// to add the error message to the parser's error list.
if (YP_NODE_TYPE_P(node, YP_MISSING_NODE)) {
- yp_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, message);
+ yp_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, diag_id);
return node;
}