From e9478dcf3fd300bfcde2acf975c46526da2abce7 Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Sat, 24 Oct 2026 02:36:32 +0200 Subject: [PATCH] refactor: store diagnostic messages in a static enum map --- source/diagnostics/diagnostics.hon | 64 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/source/diagnostics/diagnostics.hon b/source/diagnostics/diagnostics.hon index 8e8b94a..02d0a1b 100644 --- a/source/diagnostics/diagnostics.hon +++ b/source/diagnostics/diagnostics.hon @@ -1,5 +1,6 @@ import "@std/mem" import "@std/arraylist" +import "@std/enummap" Span :: struct { start u32 @@ -76,34 +77,39 @@ count proc(store @Store) usize { return store.list.items.len } +# a missing entry leaves an undefined payload, which static initialization rejects. +@hide:file +messages :: $enummap.init(Code, []u8, { + invalid_character = "invalid character", + float_must_end_with_digit = "float literal must end with a digit", + unterminated_string = "unterminated string literal", + unexpected_token = "unexpected token", + duplicate_name = "duplicate name or forbidden shadowing", + unknown_name = "unknown name", + expected_type = "annotation must name a type", + type_not_value = "type name cannot be used as a value", + invalid_void_type = "void cannot be stored or used as a parameter type", + type_mismatch = "incompatible value type", + invalid_operand = "operator requires compatible operand types", + integer_division = "division requires float operands", + not_callable = "value is not callable", + argument_count_mismatch = "argument count does not match the function signature", + cannot_infer_type = "cannot infer a type without a type anchor", + missing_return = "nonvoid function can finish without returning a value", + return_type_mismatch = "return does not match the function result type", + condition_not_bool = "condition must have type bool", + invalid_assignment_target = "assignment requires a mutable local binding", + missing_entry = "program requires a main function", + invalid_entry = "main must be a function with no parameters", + literal_out_of_range = "numeric literal is outside its runtime type's range", + invalid_escape = "invalid string escape", + read_before_initialization = "local value was read before initialization", + write_before_initialization = "local value was assigned before initialization", + initialization_cycle = "global initialization cycle", + integer_overflow = "integer arithmetic overflow", +}) + +#! returns a borrowed static message; all Code entries are required at compile time. message proc(code Code) []u8 { - return match code { - .invalid_character: "invalid character" - .float_must_end_with_digit: "float literal must end with a digit" - .unterminated_string: "unterminated string literal" - .unexpected_token: "unexpected token" - .duplicate_name: "duplicate name or forbidden shadowing" - .unknown_name: "unknown name" - .expected_type: "annotation must name a type" - .type_not_value: "type name cannot be used as a value" - .invalid_void_type: "void cannot be stored or used as a parameter type" - .type_mismatch: "incompatible value type" - .invalid_operand: "operator requires compatible operand types" - .integer_division: "division requires float operands" - .not_callable: "value is not callable" - .argument_count_mismatch: "argument count does not match the function signature" - .cannot_infer_type: "cannot infer a type without a type anchor" - .missing_return: "nonvoid function can finish without returning a value" - .return_type_mismatch: "return does not match the function result type" - .condition_not_bool: "condition must have type bool" - .invalid_assignment_target: "assignment requires a mutable local binding" - .missing_entry: "program requires a main function" - .invalid_entry: "main must be a function with no parameters" - .literal_out_of_range: "numeric literal is outside its runtime type's range" - .invalid_escape: "invalid string escape" - .read_before_initialization: "local value was read before initialization" - .write_before_initialization: "local value was assigned before initialization" - .initialization_cycle: "global initialization cycle" - .integer_overflow: "integer arithmetic overflow" - } + return enummap.get(Code, []u8, &messages, code)? }