diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2024-08-21 18:51:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-21 18:51:43 +0200 |
| commit | a8bc6f08a9b4dea769b4aea40aa33e72c0b7806a (patch) | |
| tree | 5966cc03bd6af8c7a4435f8c8e9f23477e77c94d /src | |
| parent | 63cd9a031a76220dc31ef8c009b47ace9fc2b0fd (diff) | |
| parent | 07aedb0b89c5ac4fa2607f446a7f3994159e11c3 (diff) | |
Merge pull request #4116 from Kelimion/article
Add table-driven (in)definite article to some errors.
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.cpp | 22 | ||||
| -rw-r--r-- | src/error.cpp | 29 |
2 files changed, 44 insertions, 7 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f4d5cc5a4..9cdba2710 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1071,16 +1071,19 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ return; } + // Grab definite or indefinite article matching `context_name`, or "" if not found. + String article = error_article(context_name); + if (is_type_untyped(operand->type)) { Type *target_type = type; if (type == nullptr || is_type_any(type)) { if (type == nullptr && is_type_untyped_uninit(operand->type)) { - error(operand->expr, "Use of --- in %.*s", LIT(context_name)); + error(operand->expr, "Use of --- in %.*s%.*s", LIT(article), LIT(context_name)); operand->mode = Addressing_Invalid; return; } if (type == nullptr && is_type_untyped_nil(operand->type)) { - error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name)); + error(operand->expr, "Use of untyped nil in %.*s%.*s", LIT(article), LIT(context_name)); operand->mode = Addressing_Invalid; return; } @@ -1135,9 +1138,10 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ // TODO(bill): is this a good enough error message? error(operand->expr, - "Cannot assign overloaded procedure group '%s' to '%s' in %.*s", + "Cannot assign overloaded procedure group '%s' to '%s' in %.*s%.*s", expr_str, op_type_str, + LIT(article), LIT(context_name)); operand->mode = Addressing_Invalid; } @@ -1163,20 +1167,23 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ switch (operand->mode) { case Addressing_Builtin: error(operand->expr, - "Cannot assign built-in procedure '%s' in %.*s", + "Cannot assign built-in procedure '%s' to %.*s%.*s", expr_str, + LIT(article), LIT(context_name)); break; case Addressing_Type: if (is_type_polymorphic(operand->type)) { error(operand->expr, - "Cannot assign '%s' which is a polymorphic type in %.*s", + "Cannot assign '%s', a polymorphic type, to %.*s%.*s", op_type_str, + LIT(article), LIT(context_name)); } else { error(operand->expr, - "Cannot assign '%s' which is a type in %.*s", + "Cannot assign '%s', a type, to %.*s%.*s", op_type_str, + LIT(article), LIT(context_name)); } break; @@ -1203,10 +1210,11 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ ERROR_BLOCK(); error(operand->expr, - "Cannot assign value '%s' of type '%s%s' to '%s%s' in %.*s", + "Cannot assign value '%s' of type '%s%s' to '%s%s' in %.*s%.*s", expr_str, op_type_str, op_type_extra, type_str, type_extra, + LIT(article), LIT(context_name)); check_assignment_error_suggestion(c, operand, type); diff --git a/src/error.cpp b/src/error.cpp index f95123f15..1492b00c7 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -820,6 +820,35 @@ gb_internal int error_value_cmp(void const *a, void const *b) { return token_pos_cmp(x->pos, y->pos); } +gb_global String error_article_table[][2] = { + {str_lit("a "), str_lit("bit_set literal")}, + {str_lit("a "), str_lit("constant declaration")}, + {str_lit("a "), str_lit("dynamiic array literal")}, + {str_lit("a "), str_lit("map index")}, + {str_lit("a "), str_lit("map literal")}, + {str_lit("a "), str_lit("matrix literal")}, + {str_lit("a "), str_lit("polymorphic type argument")}, + {str_lit("a "), str_lit("procedure argument")}, + {str_lit("a "), str_lit("simd vector literal")}, + {str_lit("a "), str_lit("slice literal")}, + {str_lit("a "), str_lit("structure literal")}, + {str_lit("a "), str_lit("variable declaration")}, + {str_lit("an "), str_lit("'any' literal")}, + {str_lit("an "), str_lit("array literal")}, + {str_lit("an "), str_lit("enumerated array literal")}, + +}; + +// Returns definite or indefinite article matching `context_name`, or "" if not found. +gb_internal String error_article(String context_name) { + for (int i = 0; i < gb_count_of(error_article_table); i += 1) { + if (context_name == error_article_table[i][1]) { + return error_article_table[i][0]; + } + } + return str_lit(""); +} + gb_internal bool errors_already_printed = false; gb_internal void print_all_errors(void) { |