massive renaming of internal compiler things
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 30 Aug 2020 12:59:55 +0000 (07:59 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 30 Aug 2020 12:59:55 +0000 (07:59 -0500)
20 files changed:
Makefile
docs/plan
include/bh.h
include/onyxerrors.h [new file with mode: 0644]
include/onyxmsgs.h [deleted file]
include/onyxparser.h
include/onyxsempass.h
include/onyxwasm.h
onyx
progs/poly_test.onyx
src/onyx.c
src/onyxbuiltins.c
src/onyxchecker.c
src/onyxerrors.c [new file with mode: 0644]
src/onyxmsgs.c [deleted file]
src/onyxparser.c
src/onyxsempass.c
src/onyxsymres.c
src/onyxutils.c
src/onyxwasm.c

index 21ec20250db27a7141109707c3d04a316458166d..597d5dd3a966064fd7a171f416d8753914b960c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ OBJ_FILES=\
        build/onyxsempass.o \
        build/onyxsymres.o \
        build/onyxchecker.o \
-       build/onyxmsgs.o \
+       build/onyxerrors.o \
        build/onyxutils.o \
        build/onyxwasm.o \
        build/onyxdoc.o \
index 898280e826934e7e45c43f6228a2adc5f3b8b205..d135c900883fb041183414035f5f6790a3d4c3d4 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -218,6 +218,11 @@ HOW:
 
         [X] Basic documentation outputter
 
+        [X] Rewrite error reporting system
+            - don't sort errors
+            - add infos to warnings
+            - no more preformatted strings, just write them inline ffs
+
         [ ] #file and #line directives
             - string and u32 respectively that represent the current file and line number where the directive is
 
@@ -232,9 +237,6 @@ HOW:
             - struct member names
             - array length
 
-        [ ] Clean up error messages
-            - Stop using Msg_Type_Literal everywhere and be more specific
-
         [ ] 'use' enums and packages at an arbitrary scope
 
         [ ] convert to using an 'atom' like table
index e5f0be8655a4cf852d73b87fe07c65a1ef8775a5..37d7b785b214c4c99aa0b98e7ada6819d1f969c8 100644 (file)
@@ -143,6 +143,26 @@ static inline u64 log2_dumb(u64 n) {
 
 
 
+static inline const char* bh_num_suffix(u64 i) {
+    if (i == 11 || i == 12 || i == 13) return "th";
+
+    switch (i % 10) {
+        case 0: return "th";
+        case 1: return "st";
+        case 2: return "nd";
+        case 3: return "rd";
+        case 4: return "th";
+        case 5: return "th";
+        case 6: return "th";
+        case 7: return "th";
+        case 8: return "th";
+        case 9: return "th";
+
+        default: return "";
+    }
+}
+
+
 
 
 //-------------------------------------------------------------------------------------
diff --git a/include/onyxerrors.h b/include/onyxerrors.h
new file mode 100644 (file)
index 0000000..dcc2fbf
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef ONYXERRORS_H
+#define ONYXERRORS_H
+
+#include "bh.h"
+#include "onyxlex.h"
+
+#include <stdarg.h>
+
+#define ONYX_ERR_BUFFER_SIZE 256
+
+typedef struct OnyxError {
+    OnyxFilePos pos;
+    char *text;
+} OnyxError;
+
+typedef struct OnyxErrors {
+    bh_arena     msg_arena;
+    bh_allocator msg_alloc;
+
+    // NOTE: Pointer to a table mapping file paths to
+    // their file contents. Used for better error messages
+    bh_table(bh_file_contents)* file_contents;
+
+    bh_arr(OnyxError) errors;
+} OnyxErrors;
+
+extern OnyxErrors msgs;
+
+void onyx_errors_init(bh_table(bh_file_contents)* files);
+void onyx_report_error(OnyxFilePos pos, char * format, ...);
+void onyx_errors_print();
+b32  onyx_has_errors();
+
+#endif
diff --git a/include/onyxmsgs.h b/include/onyxmsgs.h
deleted file mode 100644 (file)
index 81c4186..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef ONYXMSGS_H
-#define ONYXMSGS_H
-
-#include "bh.h"
-#include "onyxlex.h"
-
-#include <stdarg.h>
-
-#define ONYX_MSG_BUFFER_SIZE 256
-
-typedef enum MsgType {
-    Msg_Type_Literal,
-    Msg_Type_Expected_Token,
-    Msg_Type_Unexpected_Token,
-    Msg_Type_Unknown_Type,
-    Msg_Type_Not_Lval,
-    Msg_Type_Assign_Const,
-    Msg_Type_Unknown_Symbol,
-    Msg_Type_Unknown_Directive,
-
-    Msg_Type_Redeclare_Symbol,
-    Msg_Type_Binop_Mismatch,
-    Msg_Type_Assignment_Mismatch,
-    Msg_Type_Global_Type_Mismatch,
-    Msg_Type_Expected_Expression,
-    Msg_Type_Call_Non_Function,
-
-    Msg_Type_Function_Return_Mismatch,
-    Msg_Type_Function_Param_Mismatch,
-
-    Msg_Type_Duplicate_Member,
-    Msg_Type_No_Field,
-    Msg_Type_Duplicate_Value,
-    Msg_Type_Field_No_Value,
-
-    Msg_Type_Multiple_Cases,
-
-    Msg_Type_Unresolved_Type,
-    Msg_Type_Unresolved_Symbol,
-
-    Msg_Type_Failed_Gen_Load,
-    Msg_Type_Failed_Gen_Store,
-    Msg_Type_File_Not_Found,
-
-    Msg_Type_Count,
-} MsgType;
-
-typedef struct Message {
-    MsgType type;
-    OnyxFilePos pos;
-    struct Message* next;
-    char text[ONYX_MSG_BUFFER_SIZE];
-} Message;
-
-typedef struct OnyxMessages {
-    bh_allocator allocator;
-
-    // NOTE: Pointer to a table mapping file paths to
-    // their file contents. Used for better error messages
-    bh_table(bh_file_contents)* file_contents;
-
-    Message* first;
-} OnyxMessages;
-
-extern OnyxMessages msgs;
-
-void onyx_message_init(bh_allocator allocator, bh_table(bh_file_contents)* files);
-void onyx_message_add(MsgType type, OnyxFilePos pos, ...);
-void onyx_message_print();
-b32  onyx_message_has_errors();
-
-#endif
index f4e69dc5d633b7af4afc183dab1c71e783a41f7c..0da8dc2a8916a10ba27f602386e2da7037312b9d 100644 (file)
@@ -4,7 +4,7 @@
 #include "bh.h"
 
 #include "onyxlex.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 #include "onyxastnodes.h"
 
 typedef struct NodeToProcess {
index 5a61171a0d0bb225389cb23d2efee94ad3dff0ae..145795c5ceac374d3cd73561e8b00820f2305564 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "onyxlex.h"
 #include "onyxastnodes.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 
 typedef struct SemState {
     // NOTE: Adding node_allocator in case we need
index 11a6c4a6516dc9fe21f364300f19a2f9d1695989..8c803d7d96f10879d5fa3f18b8d419fd646798a6 100644 (file)
@@ -4,7 +4,7 @@
 #include "bh.h"
 
 #include "onyxastnodes.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 
 typedef u8 WasmType;
 
diff --git a/onyx b/onyx
index ceacaca6cc918d42e89930c37ec176f37c11c934..fb29383a70d23a223cee9f1396eb95a4b30cbbd9 100755 (executable)
Binary files a/onyx and b/onyx differ
index 45ccbbf4654774a52fdc260082563fe97c434b49..58b542c792a0df7c5adcb7b0c21c908bc4c2579a 100644 (file)
@@ -67,12 +67,20 @@ SOA :: struct {
     b  : [..] i64;
 }
 
+soa_init :: proc (s: ^SOA) {
+    array_init(^s.a);
+    array_init(^s.b);
+}
+
+soa_deinit :: proc (s: ^SOA) {
+    array_free(^s.a);
+    array_free(^s.b);
+}
+
 main :: proc (args: [] cstring) {
     s : SOA;
-    array_init(^s.a, 10);
-    array_init(^s.b, 10);
-    defer array_free(^s.a);
-    defer array_free(^s.b);
+    soa_init(^s);
+    defer soa_deinit(^s);
 
     print_arr_details(^s.a);
     print_arr_details(^s.b);
@@ -83,7 +91,8 @@ main :: proc (args: [] cstring) {
     }
 
     print_arr(^s.a);
-    print_arr(array_to_slice(^s.a));
+    array_to_slice(^s.a) |> print_arr();
+    array_to_slice(^s.b) |> print_arr();
 
     print("After adding...\n");
     print_arr_details(^s.a);
@@ -138,7 +147,7 @@ main2 :: proc (args: [] cstring) {
 
     print_arr_details(^barr);
     print_arr(^barr);
-    print(array_average(^barr));
+    array_average(^barr) |> print();
     print("\n");
 
     print("Does the array contain 2637? ");
index 32880828f61844a11475540f83b0bdff9a7cf4e3..75527496434ccbbcb5988a8a7e2e45a192f90bf1 100644 (file)
@@ -3,7 +3,7 @@
 #include "bh.h"
 
 #include "onyxlex.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 #include "onyxparser.h"
 #include "onyxsempass.h"
 #include "onyxutils.h"
@@ -109,8 +109,8 @@ typedef enum CompilerProgress {
 typedef struct CompilerState {
     OnyxCompileOptions* options;
 
-    bh_arena                  ast_arena, msg_arena, sp_arena;
-    bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc;
+    bh_arena                  ast_arena, sp_arena;
+    bh_allocator token_alloc, ast_alloc, sp_alloc;
 
     bh_table(bh_file_contents) loaded_files;
     bh_arr(const char *) queued_files;
@@ -124,12 +124,8 @@ static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOption
 
     program_info_init(&compiler_state->prog_info, global_heap_allocator);
 
-    bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096);
-    compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena);
-
     bh_table_init(opts->allocator, compiler_state->loaded_files, 15);
-
-    onyx_message_init(compiler_state->msg_alloc, &compiler_state->loaded_files);
+    onyx_errors_init(&compiler_state->loaded_files);
 
     compiler_state->token_alloc = opts->allocator;
 
@@ -150,7 +146,6 @@ static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOption
 
 static void compiler_state_free(CompilerState* cs) {
     bh_arena_free(&cs->ast_arena);
-    bh_arena_free(&cs->msg_arena);
     bh_arena_free(&cs->sp_arena);
     bh_table_free(cs->loaded_files);
     onyx_wasm_module_free(&cs->wasm_mod);
@@ -333,7 +328,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char*
     ParseResults results = parse_source_file(compiler_state, &fc);
     merge_parse_results(compiler_state, &results);
 
-    if (onyx_message_has_errors()) {
+    if (onyx_has_errors()) {
         return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
     } else {
         return ONYX_COMPILER_PROGRESS_SUCCESS;
@@ -354,7 +349,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
     }
 
     initialize_builtins(compiler_state->ast_alloc, &compiler_state->prog_info);
-    if (onyx_message_has_errors()) {
+    if (onyx_has_errors()) {
         return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
     }
 
@@ -380,7 +375,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
     onyx_sempass_init(compiler_state->sp_alloc, compiler_state->ast_alloc);
     onyx_sempass(&compiler_state->prog_info);
 
-    if (onyx_message_has_errors()) {
+    if (onyx_has_errors()) {
         return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
     }
 
@@ -398,7 +393,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
     compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator);
     onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->prog_info);
 
-    if (onyx_message_has_errors()) {
+    if (onyx_has_errors()) {
         return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
     }
 
@@ -454,7 +449,7 @@ int main(int argc, char *argv[]) {
         case ONYX_COMPILER_PROGRESS_FAILED_PARSE:
         case ONYX_COMPILER_PROGRESS_FAILED_SEMPASS:
         case ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN:
-            onyx_message_print();
+            onyx_errors_print();
             break;
 
         case ONYX_COMPILER_PROGRESS_FAILED_OUTPUT:
index 67f1a2c54efe217207ac955f9669a06872729310..d1cd9261b82eb7f3ad9fb0ecbdaafa5fd9e67186 100644 (file)
@@ -1,6 +1,6 @@
 #include "onyxastnodes.h"
 #include "onyxtypes.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 #include "onyxutils.h"
 
 AstBasicType basic_type_void   = { Ast_Kind_Basic_Type, 0, NULL, "void"  , &basic_types[Basic_Kind_Void]  };
@@ -65,9 +65,7 @@ void initialize_builtins(bh_allocator a, ProgramInfo* prog) {
     Package* p = program_info_package_lookup_or_create(prog, "builtin", prog->global_scope, a);
     builtin_string_type = (AstType *) symbol_raw_resolve(p->scope, "string");
     if (builtin_string_type == NULL) {
-        onyx_message_add(Msg_Type_Literal,
-                (OnyxFilePos) { 0 },
-                "'string' struct not found in builtin package");
+        onyx_report_error((OnyxFilePos) { 0 }, "'string' struct not found in builtin package.");
         return;
     }
 }
\ No newline at end of file
index c3d1b54f83d36d9f4359df3ff64956d83337a169..1c49144865b0622514b0683322138b4f4e40812d 100644 (file)
@@ -46,17 +46,15 @@ b32 check_return(AstReturn* retnode) {
         if (check_expression(&retnode->expr)) return 1;
 
         if (!types_are_compatible(retnode->expr->type, semstate.expected_return_type)) {
-            onyx_message_add(Msg_Type_Function_Return_Mismatch,
-                    retnode->expr->token->pos,
+            onyx_report_error(retnode->expr->token->pos,
+                    "Expected to return a value of type '%s', returning value of type '%s'.",
                     type_get_name(retnode->expr->type),
                     type_get_name(semstate.expected_return_type));
             return 1;
         }
     } else {
         if (semstate.expected_return_type->Basic.size > 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    retnode->token->pos,
-                    "returning from non-void function without value");
+            onyx_report_error(retnode->token->pos, "returning from non-void function without value");
             return 1;
         }
     }
@@ -70,9 +68,7 @@ b32 check_if(AstIfWhile* ifnode) {
     if (check_expression(&ifnode->cond)) return 1;
 
     if (!type_is_bool(ifnode->cond->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                ifnode->cond->token->pos,
-                "expected boolean type for condition");
+        onyx_report_error(ifnode->cond->token->pos, "expected boolean type for condition");
         return 1;
     }
 
@@ -88,9 +84,7 @@ b32 check_while(AstIfWhile* whilenode) {
     if (check_expression(&whilenode->cond)) return 1;
 
     if (!type_is_bool(whilenode->cond->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                whilenode->cond->token->pos,
-                "expected boolean type for condition");
+        onyx_report_error(whilenode->cond->token->pos, "expected boolean type for condition");
         return 1;
     }
 
@@ -110,23 +104,17 @@ b32 check_for(AstFor* fornode) {
     fill_in_type((AstTyped *) fornode->var);
 
     if (!type_is_integer(fornode->start->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                fornode->start->token->pos,
-                "expected expression of integer type for start");
+        onyx_report_error(fornode->start->token->pos, "expected expression of integer type for start");
         return 1;
     }
 
     if (!type_is_integer(fornode->end->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                fornode->end->token->pos,
-                "expected expression of integer type for end");
+        onyx_report_error(fornode->end->token->pos, "expected expression of integer type for end");
         return 1;
     }
 
     if (!type_is_integer(fornode->step->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                fornode->step->token->pos,
-                "expected expression of integer type for step");
+        onyx_report_error(fornode->step->token->pos, "expected expression of integer type for step");
         return 1;
     }
 
@@ -138,16 +126,12 @@ b32 check_for(AstFor* fornode) {
     }
 
     if (!types_are_compatible(fornode->end->type, fornode->start->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                fornode->end->token->pos,
-                "type of end does not match type of start");
+        onyx_report_error(fornode->end->token->pos, "type of end does not match type of start");
         return 1;
     }
 
     if (!types_are_compatible(fornode->step->type, fornode->start->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                fornode->start->token->pos,
-                "type of step does not match type of start");
+        onyx_report_error(fornode->start->token->pos, "type of step does not match type of start");
         return 1;
     }
 
@@ -162,9 +146,7 @@ b32 check_switch(AstSwitch* switchnode) {
 
     if (check_expression(&switchnode->expr)) return 1;
     if (!type_is_integer(switchnode->expr->type) && switchnode->expr->type->kind != Type_Kind_Enum) {
-        onyx_message_add(Msg_Type_Literal,
-                switchnode->expr->token->pos,
-                "expected integer or enum type for switch expression");
+        onyx_report_error(switchnode->expr->token->pos, "expected integer or enum type for switch expression");
         return 1;
     }
 
@@ -181,9 +163,7 @@ b32 check_switch(AstSwitch* switchnode) {
         }
 
         if (sc->value->kind != Ast_Kind_NumLit) {
-            onyx_message_add(Msg_Type_Literal,
-                    sc->value->token->pos,
-                    "case statement expected compile time known integer");
+            onyx_report_error(sc->value->token->pos, "case statement expected compile time known integer");
             return 1;
         }
 
@@ -194,9 +174,7 @@ b32 check_switch(AstSwitch* switchnode) {
         switchnode->max_case = bh_max(switchnode->max_case, value);
 
         if (bh_imap_has(&switchnode->case_map, value)) {
-            onyx_message_add(Msg_Type_Multiple_Cases,
-                    sc->value->token->pos,
-                    value);
+            onyx_report_error(sc->value->token->pos, "Multiple cases for values '%d'.", value);
             return 1;
         }
 
@@ -236,9 +214,7 @@ no_match:
         continue;
     }
 
-    onyx_message_add(Msg_Type_Literal,
-            call->token->pos,
-            "unable to match overloaded function");
+    onyx_report_error(call->token->pos, "unable to match overloaded function");
 
     return NULL;
 }
@@ -247,9 +223,7 @@ b32 check_call(AstCall* call) {
     AstFunction* callee = (AstFunction *) call->callee;
 
     if (callee->kind == Ast_Kind_Symbol) {
-        onyx_message_add(Msg_Type_Unresolved_Symbol,
-                callee->token->pos,
-                callee->token->text, callee->token->length);
+        onyx_report_error(callee->token->pos, "Unresolved symbol '%b'.", callee->token->text, callee->token->length);
         return 1;
     }
 
@@ -262,17 +236,14 @@ b32 check_call(AstCall* call) {
         if (check_expression((AstTyped **) &actual_param)) return 1;
 
         if (actual_param->value->kind == Ast_Kind_Overloaded_Function) {
-            onyx_message_add(Msg_Type_Literal,
-                    actual_param->token->pos,
-                    "cannot pass overloaded functions as parameters.");
+            onyx_report_error(actual_param->token->pos, "Cannot pass overloaded functions as parameters.");
             return 1;
         }
 
         if (type_is_structlike_strict(actual_param->value->type)) {
             if (!type_structlike_is_simple(actual_param->value->type)) {
-                onyx_message_add(Msg_Type_Literal,
-                        actual_param->token->pos,
-                        "can only pass simple structs as parameters (no nested structures). passing by pointer is the only way for now.");
+                onyx_report_error(actual_param->token->pos,
+                    "Can only pass simple structs as parameters (no nested structures). passing by pointer is the only way for now.");
                 return 1;
             }
         }
@@ -299,8 +270,8 @@ b32 check_call(AstCall* call) {
     fill_in_type((AstTyped *) callee);
 
     if (callee->type->kind != Type_Kind_Function) {
-        onyx_message_add(Msg_Type_Call_Non_Function,
-                call->token->pos,
+        onyx_report_error(call->token->pos,
+                "Attempting to call something that is not a function, '%b'.",
                 callee->token->text, callee->token->length);
         return 1;
     }
@@ -400,8 +371,8 @@ b32 check_call(AstCall* call) {
     i32 arg_pos = 0;
     while (arg_pos < callee->type->Function.param_count && actual_param != NULL) {
         if (!types_are_compatible(formal_params[arg_pos], actual_param->type)) {
-            onyx_message_add(Msg_Type_Function_Param_Mismatch,
-                    actual_param->token->pos,
+            onyx_report_error(actual_param->token->pos,
+                    "The function '%b' expects a value of type '%s' for parameter '%d', got '%s'.",
                     callee->token->text, callee->token->length,
                     type_get_name(formal_params[arg_pos]),
                     arg_pos,
@@ -414,16 +385,12 @@ b32 check_call(AstCall* call) {
     }
 
     if (arg_pos < callee->type->Function.param_count) {
-        onyx_message_add(Msg_Type_Literal,
-                call->token->pos,
-                "too few arguments to function call");
+        onyx_report_error(call->token->pos, "Too few arguments to function call.");
         return 1;
     }
 
     if (actual_param != NULL) {
-        onyx_message_add(Msg_Type_Literal,
-                call->token->pos,
-                "too many arguments to function call");
+        onyx_report_error(call->token->pos, "Too many arguments to function call.");
         return 1;
     }
 
@@ -434,29 +401,27 @@ b32 check_call(AstCall* call) {
 
 b32 check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) {
     if (!assignment_is_ok) {
-        onyx_message_add(Msg_Type_Literal,
-            binop->token->pos,
-            "assignment not valid in expression");
+        onyx_report_error(binop->token->pos, "Assignment not valid in expression.");
         return 1;
     }
 
     if (!is_lval((AstNode *) binop->left)) {
-        onyx_message_add(Msg_Type_Not_Lval,
-                binop->left->token->pos,
+        onyx_report_error(binop->left->token->pos,
+                "Cannot assign to '%b'.",
                 binop->left->token->text, binop->left->token->length);
         return 1;
     }
 
     if ((binop->left->flags & Ast_Flag_Const) != 0 && binop->left->type != NULL) {
-        onyx_message_add(Msg_Type_Assign_Const,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Cannot assign to constant '%b.'.",
                 binop->left->token->text, binop->left->token->length);
         return 1;
     }
 
     if (binop->right->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->right->token->text, binop->right->token->length);
         return 1;
     }
@@ -501,8 +466,8 @@ b32 check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) {
     }
 
     if (!types_are_compatible(binop->left->type, binop->right->type)) {
-        onyx_message_add(Msg_Type_Assignment_Mismatch,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Cannot assign value of type '%s' to a '%s'.",
                 type_get_name(binop->left->type),
                 type_get_name(binop->right->type));
         return 1;
@@ -517,36 +482,32 @@ b32 check_binaryop_compare(AstBinaryOp** pbinop) {
     AstBinaryOp* binop = *pbinop;
 
     if (binop->left->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->left->token->text, binop->left->token->length);
         return 1;
     }
 
     if (binop->right->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->right->token->text, binop->right->token->length);
         return 1;
     }
 
     if (type_is_structlike_strict(binop->left->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "invalid type for left side of binary operator");
+        onyx_report_error(binop->token->pos, "Invalid type for left side of comparison operator.");
         return 1;
     }
 
     if (type_is_structlike_strict(binop->right->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "invalid type for right side of binary operator");
+        onyx_report_error(binop->token->pos, "Invalid type for right side of comparison operator.");
         return 1;
     }
 
     if (!types_are_compatible(binop->left->type, binop->right->type)) {
-        onyx_message_add(Msg_Type_Binop_Mismatch,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Cannot compare '%s' to '%s'.",
                 type_get_name(binop->left->type),
                 type_get_name(binop->right->type));
         return 1;
@@ -565,23 +526,21 @@ b32 check_binaryop_bool(AstBinaryOp** pbinop) {
     AstBinaryOp* binop = *pbinop;
 
     if (binop->left->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->left->token->text, binop->left->token->length);
         return 1;
     }
 
     if (binop->right->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->right->token->text, binop->right->token->length);
         return 1;
     }
 
     if (!type_is_bool(binop->left->type) || !type_is_bool(binop->right->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "boolean operator expects boolean types for both operands");
+        onyx_report_error(binop->token->pos, "Boolean operator expects boolean types for both operands.");
         return 1;
     }
 
@@ -611,62 +570,50 @@ b32 check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) {
         return check_binaryop_bool(pbinop);
 
     if (binop->left->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->left->token->text, binop->left->token->length);
         return 1;
     }
 
     if (binop->right->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Unable to resolve type for symbol '%b'.",
                 binop->right->token->text, binop->right->token->length);
         return 1;
     }
 
     if (!type_is_numeric(binop->left->type) && !type_is_pointer(binop->left->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "expected numeric or pointer type for left side of binary operator");
+        onyx_report_error(binop->token->pos, "Expected numeric or pointer type for left side of binary operator.");
         return 1;
     }
 
     if (!type_is_numeric(binop->right->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "expected numeric type for right side of binary operator");
+        onyx_report_error(binop->token->pos, "Expected numeric type for right side of binary operator.");
         return 1;
     }
 
     if (type_is_pointer(binop->right->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "right side of binary operator is a pointer");
+        onyx_report_error(binop->token->pos, "Right side of binary operator is a pointer.");
         return 1;
     }
 
     if (binop->left->type->kind == Type_Kind_Basic
         && binop->left->type->Basic.kind == Basic_Kind_Rawptr
         && !binop_is_compare(binop)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "cannot operate on a rawptr");
+        onyx_report_error(binop->token->pos, "Cannot operate on a 'rawptr'. Cast it to a another pointer type first.");
         return 1;
     }
 
     b32 lptr = type_is_pointer(binop->left->type);
     if (lptr && (binop->operation != Binary_Op_Add && binop->operation != Binary_Op_Minus)) {
-        onyx_message_add(Msg_Type_Literal,
-                binop->token->pos,
-                "this operator is not supported for these operands");
+        onyx_report_error(binop->token->pos, "This operator is not supported for these operands.");
         return 1;
     }
 
     if (lptr) {
         if (!type_is_integer(binop->right->type)) {
-            onyx_message_add(Msg_Type_Literal,
-                    binop->right->token->pos,
-                    "expected integer type");
+            onyx_report_error(binop->right->token->pos, "Expected integer type.");
             return 1;
         }
 
@@ -698,8 +645,8 @@ b32 check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) {
     }
 
     if (!types_are_compatible(binop->left->type, binop->right->type)) {
-        onyx_message_add(Msg_Type_Binop_Mismatch,
-                binop->token->pos,
+        onyx_report_error(binop->token->pos,
+                "Mismatched types for binary operation. left: '%s', right: '%s'.",
                 type_get_name(binop->left->type),
                 type_get_name(binop->right->type));
         return 1;
@@ -738,9 +685,11 @@ b32 check_struct_literal(AstStructLiteral* sl) {
     u32 mem_count = type_structlike_mem_count(sl->type);
 
     if (mem_count != bh_arr_length(sl->values)) {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "incorrect number of initial values for this type");
+        onyx_report_error(sl->token->pos,
+                "'%s' expects %d values, given %d.",
+                type_get_name(sl->type),
+                bh_arr_length(sl->values),
+                mem_count);
         return 1;
     }
 
@@ -757,8 +706,9 @@ b32 check_struct_literal(AstStructLiteral* sl) {
         Type* formal = smem.type;
 
         if (!types_are_compatible(formal, (*actual)->type)) {
-            onyx_message_add(Msg_Type_Assignment_Mismatch,
-                    sl->token->pos,
+            onyx_report_error(sl->token->pos,
+                    "Mismatched types for %d%s member, expected '%s, got '%s'.",
+                    i, bh_num_suffix(i),
                     type_get_name(formal),
                     type_get_name((*actual)->type));
             return 1;
@@ -778,9 +728,7 @@ b32 check_address_of(AstAddressOf* aof) {
             && aof->expr->kind != Ast_Kind_Field_Access
             && aof->expr->kind != Ast_Kind_Memres
             && aof->expr->kind != Ast_Kind_Local) {
-        onyx_message_add(Msg_Type_Literal,
-                aof->token->pos,
-                "cannot take the address of this");
+        onyx_report_error(aof->token->pos, "Cannot take the address of value.");
         return 1;
     }
 
@@ -795,16 +743,12 @@ b32 check_dereference(AstDereference* deref) {
     if (check_expression(&deref->expr)) return 1;
 
     if (!type_is_pointer(deref->expr->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                deref->token->pos,
-                "cannot dereference non-pointer");
+        onyx_report_error(deref->token->pos, "Cannot dereference non-pointer value.");
         return 1;
     }
 
     if (deref->expr->type == basic_type_rawptr.type) {
-        onyx_message_add(Msg_Type_Literal,
-                deref->token->pos,
-                "cannot dereference rawptr");
+        onyx_report_error(deref->token->pos, "Cannot dereference 'rawptr'. Cast to another pointer type first.");
         return 1;
     }
 
@@ -818,17 +762,13 @@ b32 check_array_access(AstArrayAccess* aa) {
     if (check_expression(&aa->expr)) return 1;
 
     if (!type_is_array_accessible(aa->addr->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                aa->token->pos,
-                "expected pointer or array type for left of array access");
+        onyx_report_error(aa->token->pos, "Expected pointer or array type for left of array access.");
         return 1;
     }
 
     if (aa->expr->type->kind != Type_Kind_Basic
             || (aa->expr->type->Basic.kind != Basic_Kind_I32 && aa->expr->type->Basic.kind != Basic_Kind_U32)) {
-        onyx_message_add(Msg_Type_Literal,
-                aa->token->pos,
-                "expected 32-bit integer type for index");
+        onyx_report_error(aa->token->pos, "Expected type u32 or i32 for index.");
         return 1;
     }
 
@@ -854,9 +794,7 @@ b32 check_array_access(AstArrayAccess* aa) {
         aa->type = aa->addr->type->Pointer.elem;
     }
     else {
-        onyx_message_add(Msg_Type_Literal,
-                aa->token->pos,
-                "invalid type for left of array access");
+        onyx_report_error(aa->token->pos, "Invalid type for left of array access.");
         return 1;
     }
 
@@ -871,25 +809,19 @@ b32 check_slice(AstSlice* sl) {
     if (check_expression(&sl->hi)) return 1;
 
     if (!type_is_pointer(sl->addr->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "expected pointer or array type for left of slice creation");
+        onyx_report_error(sl->token->pos, "Expected pointer or array type for left of slice creation.");
         return 1;
     }
 
     if (sl->lo->type->kind != Type_Kind_Basic
             || (sl->lo->type->Basic.kind != Basic_Kind_I32 && sl->lo->type->Basic.kind != Basic_Kind_U32)) {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "expected 32-bit integer type for lower index");
+        onyx_report_error(sl->lo->token->pos, "Expected type u32 or i32 for lower index.");
         return 1;
     }
 
     if (sl->hi->type->kind != Type_Kind_Basic
             || (sl->hi->type->Basic.kind != Basic_Kind_I32 && sl->hi->type->Basic.kind != Basic_Kind_U32)) {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "expected 32-bit integer type for upper index");
+        onyx_report_error(sl->hi->token->pos, "Expected type u32 or i32 for upper index.");
         return 1;
     }
 
@@ -899,9 +831,7 @@ b32 check_slice(AstSlice* sl) {
     else if (sl->addr->type->kind == Type_Kind_Array)
         of = sl->addr->type->Array.elem;
     else {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "invalid type for left of slice creation");
+        onyx_report_error(sl->token->pos, "Invalid type for left of slice creation.");
         return 1;
     }
 
@@ -916,17 +846,19 @@ b32 check_field_access(AstFieldAccess** pfield) {
     if (check_expression(&field->expr)) return 1;
 
     if (!type_is_structlike(field->expr->type)) {
-        onyx_message_add(Msg_Type_Literal,
-            field->token->pos,
-            "cannot access field on non structures");
+        onyx_report_error(field->token->pos,
+            "Cannot access field '%b' on '%s'. Type is not a struct.",
+            field->token->text,
+            field->token->length,
+            type_get_name(field->expr->type));
         return 1;
     }
 
     token_toggle_end(field->token);
     StructMember smem;
     if (!type_lookup_member(field->expr->type, field->token->text, &smem)) {
-        onyx_message_add(Msg_Type_No_Field,
-            field->token->pos,
+        onyx_report_error(field->token->pos,
+            "Field '%s' does not exists on '%s'.",
             field->token->text,
             type_get_name(field->expr->type));
         token_toggle_end(field->token);
@@ -956,9 +888,7 @@ b32 check_align_of(AstAlignOf* ao) {
 b32 check_expression(AstTyped** pexpr) {
     AstTyped* expr = *pexpr;
     if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) {
-        onyx_message_add(Msg_Type_Literal,
-                expr->token->pos,
-                "type used as part of an expression");
+        onyx_report_error(expr->token->pos, "Type used as part of an expression.");
         return 1;
     }
 
@@ -973,17 +903,15 @@ b32 check_expression(AstTyped** pexpr) {
         case Ast_Kind_Block: retval = check_block((AstBlock *) expr); break;
 
         case Ast_Kind_Symbol:
-            onyx_message_add(Msg_Type_Unresolved_Symbol,
-                    expr->token->pos,
+            onyx_report_error(expr->token->pos,
+                    "Unable to resolve symbol '%b'.",
                     expr->token->text, expr->token->length);
             retval = 1;
             break;
 
         case Ast_Kind_Param:
             if (expr->type == NULL) {
-                onyx_message_add(Msg_Type_Literal,
-                        expr->token->pos,
-                        "local variable with unknown type");
+                onyx_report_error(expr->token->pos, "Parameter with unknown type. You should hopefully never see this.");
                 retval = 1;
             }
             break;
@@ -1000,9 +928,7 @@ b32 check_expression(AstTyped** pexpr) {
 
         case Ast_Kind_Global:
             if (expr->type == NULL) {
-                onyx_message_add(Msg_Type_Literal,
-                        expr->token->pos,
-                        "global with unknown type");
+                onyx_report_error(expr->token->pos, "Global with unknown type.");
                 retval = 1;
             }
             break;
@@ -1062,8 +988,8 @@ b32 check_global(AstGlobal* global) {
     fill_in_type((AstTyped *) global);
 
     if (global->type == NULL) {
-        onyx_message_add(Msg_Type_Unresolved_Type,
-                global->token->pos,
+        onyx_report_error(global->token->pos,
+                "Unable to resolve type for global '%b'.",
                 global->exported_name->text,
                 global->exported_name->length);
 
@@ -1083,20 +1009,7 @@ b32 check_statement(AstNode* stmt) {
         case Ast_Kind_For:        return check_for((AstFor *) stmt);
         case Ast_Kind_Switch:     return check_switch((AstSwitch *) stmt);
         case Ast_Kind_Block:      return check_block((AstBlock *) stmt);
-        case Ast_Kind_Defer: {
-            if (!semstate.defer_allowed) {
-                onyx_message_add(Msg_Type_Literal,
-                    stmt->token->pos,
-                    "deferred statement not allowed in deferred block");
-                return 1;
-            }
-
-            semstate.defer_allowed = 0;
-            b32 state = check_statement(((AstDefer *) stmt)->stmt);
-            semstate.defer_allowed = 1;
-
-            return state;
-        }
+        case Ast_Kind_Defer:      return check_statement(((AstDefer *) stmt)->stmt);
 
         case Ast_Kind_Binary_Op:
             stmt->flags |= Ast_Flag_Expr_Ignored;
@@ -1124,8 +1037,8 @@ b32 check_block(AstBlock* block) {
         fill_in_type(value);
 
         if (value->type == NULL) {
-            onyx_message_add(Msg_Type_Unresolved_Type,
-                    value->token->pos,
+            onyx_report_error(value->token->pos,
+                    "Unable to resolve type for local '%b'.",
                     value->token->text, value->token->length);
             return 1;
         }
@@ -1146,17 +1059,13 @@ b32 check_function(AstFunction* func) {
 b32 check_overloaded_function(AstOverloadedFunction* func) {
     bh_arr_each(AstTyped *, node, func->overloads) {
         if ((*node)->kind == Ast_Kind_Overloaded_Function) {
-            onyx_message_add(Msg_Type_Literal,
-                    (*node)->token->pos,
-                    "overload option can not be another overloaded function (yet)");
+            onyx_report_error((*node)->token->pos, "Overload option can not be another overloaded function.");
 
             return 1;
         }
 
         if ((*node)->kind != Ast_Kind_Function) {
-            onyx_message_add(Msg_Type_Literal,
-                    (*node)->token->pos,
-                    "overload option not function");
+            onyx_report_error((*node)->token->pos, "Overload option not function.");
 
             return 1;
         }
@@ -1169,19 +1078,12 @@ b32 check_struct(AstStructType* s_node) {
     bh_table(i32) mem_set;
     bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
 
-    if (bh_arr_length(s_node->members) == 0) {
-        onyx_message_add(Msg_Type_Literal,
-                s_node->token->pos,
-                "empty structure");
-        return 1;
-    }
-
     bh_arr_each(AstStructMember *, member, s_node->members) {
         token_toggle_end((*member)->token);
 
         if (bh_table_has(i32, mem_set, (*member)->token->text)) {
-            onyx_message_add(Msg_Type_Duplicate_Member,
-                    (*member)->token->pos,
+            onyx_report_error((*member)->token->pos,
+                    "Duplicate struct member '%s'.",
                     (*member)->token->text);
 
             token_toggle_end((*member)->token);
@@ -1207,9 +1109,8 @@ b32 check_function_header(AstFunction* func) {
         AstLocal* local = param->local;
 
         if (expect_default_param && param->default_value == NULL) {
-            onyx_message_add(Msg_Type_Literal,
-                    local->token->pos,
-                    "all parameters must have default values after the first default valued parameter.");
+            onyx_report_error(local->token->pos,
+                    "All parameters must have default values after the first default valued parameter.");
             return 1;
         }
 
@@ -1218,17 +1119,13 @@ b32 check_function_header(AstFunction* func) {
         fill_in_type((AstTyped *) local);
 
         if (local->type == NULL) {
-            onyx_message_add(Msg_Type_Literal,
-                    local->token->pos,
-                    "function parameter types must be known");
+            onyx_report_error(local->token->pos, "Function parameter types must be known.");
             return 1;
         }
 
         if (local->type->kind != Type_Kind_Array
             && type_size_of(local->type) == 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    local->token->pos,
-                    "function parameters must have non-void types");
+            onyx_report_error(local->token->pos, "Function parameters cannot have zero-width types.");
             return 1;
         }
     }
@@ -1237,30 +1134,22 @@ b32 check_function_header(AstFunction* func) {
 
     if ((func->flags & Ast_Flag_Exported) != 0) {
         if ((func->flags & Ast_Flag_Foreign) != 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    func->token->pos,
-                    "exporting a foreign function");
+            onyx_report_error(func->token->pos, "exporting a foreign function");
             return 1;
         }
 
         if ((func->flags & Ast_Flag_Intrinsic) != 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    func->token->pos,
-                    "exporting a intrinsic function");
+            onyx_report_error(func->token->pos, "exporting a intrinsic function");
             return 1;
         }
 
         if ((func->flags & Ast_Flag_Inline) != 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    func->token->pos,
-                    "exporting a inlined function");
+            onyx_report_error(func->token->pos, "exporting a inlined function");
             return 1;
         }
 
         if (func->exported_name == NULL) {
-            onyx_message_add(Msg_Type_Literal,
-                    func->token->pos,
-                    "exporting function without a name");
+            onyx_report_error(func->token->pos, "exporting function without a name");
             return 1;
         }
     }
@@ -1276,17 +1165,15 @@ b32 check_memres(AstMemRes* memres) {
         check_expression(&memres->initial_value);
 
         if ((memres->initial_value->flags & Ast_Flag_Comptime) == 0) {
-            onyx_message_add(Msg_Type_Literal,
-                    memres->initial_value->token->pos,
-                    "top level expressions must be compile time known");
+            onyx_report_error(memres->initial_value->token->pos, "Top level expressions must be compile time known.");
             return 1;
         }
 
         Type* memres_type = memres->type;
 
         if (!types_are_compatible(memres_type, memres->initial_value->type)) {
-            onyx_message_add(Msg_Type_Binop_Mismatch,
-                    memres->token->pos,
+            onyx_report_error(memres->token->pos,
+                    "Cannot assign value of type '%s' to a '%s'.",
                     type_get_name(memres_type),
                     type_get_name(memres->initial_value->type));
             return 1;
diff --git a/src/onyxerrors.c b/src/onyxerrors.c
new file mode 100644 (file)
index 0000000..5e9879d
--- /dev/null
@@ -0,0 +1,66 @@
+
+#include "onyxerrors.h"
+#include "onyxutils.h"
+
+#define MAX_MSGS 100
+
+OnyxErrors errors;
+
+void onyx_errors_init(bh_table(bh_file_contents)* files) {
+    errors.file_contents = files;
+
+    bh_arena_init(&errors.msg_arena, global_heap_allocator, 16 * 1024);
+    errors.msg_alloc = bh_arena_allocator(&errors.msg_arena);
+
+    bh_arr_new(global_heap_allocator, errors.errors, 4);
+}
+
+void onyx_report_error(OnyxFilePos pos, char * format, ...) {
+
+    va_list vargs;
+    va_start(vargs, format);
+    char* msg = bh_bprintf_va(format, vargs);
+    va_end(vargs);
+
+    OnyxError err = {
+        .pos = pos,
+        .text = bh_strdup(errors.msg_alloc, msg),
+    };
+
+    bh_arr_push(errors.errors, err);
+}
+
+static void print_detailed_message(OnyxError* err, bh_file_contents* fc) {
+    bh_printf("(%s:%l,%l) %s\n", err->pos.filename, err->pos.line, err->pos.column, err->text);
+
+    i32 linelength = 0;
+    char* walker = err->pos.line_start;
+    while (*walker != '\n') linelength++, walker++;
+
+    i32 numlen = bh_printf(" %d | ", err->pos.line);
+    bh_printf("%b\n", err->pos.line_start, linelength);
+
+    char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength + numlen);
+    memset(pointer_str, ' ', linelength + numlen);
+    memset(pointer_str + err->pos.column + numlen - 1, '~', err->pos.length - 1);
+    pointer_str[err->pos.column + numlen - 2] = '^';
+    pointer_str[err->pos.column + numlen + err->pos.length - 1] = 0;
+
+    bh_printf("%s\n", pointer_str);
+}
+
+void onyx_errors_print() {
+    bh_arr_each(OnyxError, err, errors.errors) {
+        if (err->pos.filename) {
+            bh_file_contents* fc = &bh_table_get(bh_file_contents, *errors.file_contents, (char *) err->pos.filename);
+            print_detailed_message(err, fc);
+
+        } else {
+            bh_printf("(%l,%l) %s\n", err->pos.line, err->pos.column, err->text);
+        }
+    }
+}
+
+b32 onyx_has_errors() {
+    return bh_arr_length(errors.errors) > 0;
+}
diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c
deleted file mode 100644 (file)
index b436e9a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-
-#include "onyxmsgs.h"
-#include "onyxutils.h"
-
-#define MAX_MSGS 100
-
-OnyxMessages msgs;
-
-static const char* msg_formats[] = {
-    "%s",
-    "expected token '%s', got '%s'",
-    "unexpected token '%s'",
-    "unknown type '%s'",
-    "cannot assign to '%b'",
-    "attempt to assign to constant '%b'",
-    "unknown symbol '%s'",
-    "unknown directive '%b'",
-
-    "redeclaration of symbol '%s'",
-    "mismatched types for binary operator, '%s', '%s'",
-    "mismatched types on assignment, expected '%s', got '%s'",
-    "mismatched types for global '%b'; expected '%s', got '%s'",
-    "expected expression, got '%s'",
-    "attempt to call non-function, '%b'",
-
-    "returning '%s' from function that returns '%s'",
-    "function '%b' expected type '%s' in position '%d', got '%s'",
-
-    "duplicate declaration of struct member '%s'",
-    "field '%s' does not exist on '%s'",
-    "duplicate value for struct member '%b'",
-    "no value provided for field '%b'",
-
-    "multiple cases for '%l'",
-
-    "unable to resolve type for symbol '%b'",
-    "unable to resolve symbol '%b'",
-
-    "failed to generate load instruction for type '%s'",
-    "failed to generate store instruction for type '%s'",
-
-    "file not found '%s'",
-};
-
-void onyx_message_init(bh_allocator allocator, bh_table(bh_file_contents)* files) {
-    msgs.allocator = allocator;
-    msgs.first = NULL;
-    msgs.file_contents = files;
-}
-
-void onyx_message_add(MsgType type, OnyxFilePos pos, ...) {
-    Message* msg = bh_alloc_item(msgs.allocator, Message);
-    msg->type = type;
-    msg->pos = pos;
-
-    va_list arg_list;
-    va_start(arg_list, pos);
-    bh_snprintf_va(msg->text, ONYX_MSG_BUFFER_SIZE, msg_formats[type], arg_list);
-    va_end(arg_list);
-
-    Message** walker = &msgs.first;
-    while (*walker && strcmp((*walker)->pos.filename, pos.filename) < 0) walker = &(*walker)->next;
-    while (*walker && (*walker)->pos.line < pos.line) walker = &(*walker)->next;
-    while (*walker && (*walker)->pos.line == pos.line && (*walker)->pos.column < pos.column) walker = &(*walker)->next;
-
-    msg->next = *walker;
-    *walker = msg;
-}
-
-static void print_detailed_message(Message* msg, bh_file_contents* fc) {
-    bh_printf("(%s:%l,%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text);
-
-    i32 linelength = 0;
-    char* walker = msg->pos.line_start;
-    while (*walker != '\n') linelength++, walker++;
-
-    i32 numlen = bh_printf(" %d | ", msg->pos.line);
-    bh_printf("%b\n", msg->pos.line_start, linelength);
-
-    char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength + numlen);
-    memset(pointer_str, ' ', linelength + numlen);
-    memset(pointer_str + msg->pos.column + numlen - 1, '~', msg->pos.length - 1);
-    pointer_str[msg->pos.column + numlen - 2] = '^';
-    pointer_str[msg->pos.column + numlen + msg->pos.length - 1] = 0;
-
-    bh_printf("%s\n", pointer_str);
-}
-
-void onyx_message_print() {
-    Message* msg = msgs.first;
-    i32 msg_count = MAX_MSGS;
-
-    while (msg && msg_count-- > 0) {
-        if (msg->pos.filename) {
-            bh_file_contents* fc = &bh_table_get(bh_file_contents, *msgs.file_contents, (char *) msg->pos.filename);
-
-            print_detailed_message(msg, fc);
-        } else {
-            bh_printf("(%l,%l) %s\n", msg->pos.line, msg->pos.column, msg->text);
-        }
-        msg = msg->next;
-    }
-}
-
-b32 onyx_message_has_errors() {
-    return msgs.first != NULL;
-}
index 177b4ad686bb7b4f1eec7ec20394b8a63a7b7e79..223ccbd0c93b1f24a13ae2913d5957f587ab602d 100644 (file)
@@ -1,5 +1,5 @@
 #include "onyxlex.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 #include "onyxparser.h"
 #include "onyxutils.h"
 
@@ -85,9 +85,7 @@ static OnyxToken* expect_token(OnyxParser* parser, TokenType token_type) {
     consume_token(parser);
 
     if (token->type != token_type) {
-        onyx_message_add(Msg_Type_Expected_Token,
-                         token->pos,
-                         token_name(token_type), token_name(token->type));
+        onyx_report_error(token->pos, "expected token '%s', got '%s'.", token_name(token_type), token_name(token->type));
         parser->hit_unexpected_token = 1;
         parser->curr = &parser->tokenizer->tokens[bh_arr_length(parser->tokenizer->tokens) - 1];
         return NULL;
@@ -452,9 +450,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                             break;
                         }
                         default: {
-                            onyx_message_add(Msg_Type_Literal,
-                                    char_lit->token->pos,
-                                    "invalid escaped character");
+                            onyx_report_error(char_lit->token->pos, "invalid escaped character");
                             break;
                         }
                     }
@@ -464,16 +460,12 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 break;
             }
 
-            onyx_message_add(Msg_Type_Literal,
-                    parser->curr->pos,
-                    "invalid directive in expression.");
+            onyx_report_error(parser->curr->pos, "invalid directive in expression.");
             return NULL;
         }
 
         default:
-            onyx_message_add(Msg_Type_Unexpected_Token,
-                    parser->curr->pos,
-                    token_name(parser->curr->type));
+            onyx_report_error(parser->curr->pos, "unexpected token '%s'.", token_name(parser->curr->type));
             return NULL;
     }
 
@@ -947,14 +939,7 @@ static b32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret)
         consume_token(parser);
 
         AstTyped* expr = parse_expression(parser);
-        if (expr == NULL) {
-            token_toggle_end(parser->curr);
-            onyx_message_add(Msg_Type_Expected_Expression,
-                    assignment->token->pos,
-                    parser->curr->text);
-            token_toggle_end(parser->curr);
-            return 1;
-        }
+        if (expr == NULL) return 1;
         assignment->right = expr;
 
         AstNode* left_symbol = make_node(AstNode, Ast_Kind_Symbol);
@@ -1108,15 +1093,7 @@ static AstNode* parse_statement(OnyxParser* parser) {
             break;
     }
 
-    if (needs_semicolon) {
-        if (parser->curr->type != ';') {
-            onyx_message_add(Msg_Type_Expected_Token,
-                parser->curr->pos,
-                token_name(';'),
-                token_name(parser->curr->type));
-        }
-        consume_token(parser);
-    }
+    if (needs_semicolon) expect_token(parser, ';');
 
     return retval;
 }
@@ -1249,11 +1226,9 @@ static AstType* parse_type(OnyxParser* parser, bh_arr(AstPolyParam)* poly_vars)
         }
 
         else if (parser->curr->type == '$') {
-            if (poly_vars == NULL) {
-                onyx_message_add(Msg_Type_Literal,
-                        parser->curr->pos,
-                        "polymorphic variable not valid here.");
-            }
+            if (poly_vars == NULL)
+                onyx_report_error(parser->curr->pos, "polymorphic variable not valid here.");
+
             bh_arr(AstPolyParam) pv = *poly_vars;
             consume_token(parser);
 
@@ -1299,12 +1274,7 @@ static AstType* parse_type(OnyxParser* parser, bh_arr(AstPolyParam)* poly_vars)
         }
 
         else {
-            token_toggle_end(parser->curr);
-            onyx_message_add(Msg_Type_Unexpected_Token,
-                    parser->curr->pos,
-                    parser->curr->text);
-            token_toggle_end(parser->curr);
-
+            onyx_report_error(parser->curr->pos, "unexpected token '%b'.", parser->curr->text, parser->curr->length);
             consume_token(parser);
             break;
         }
@@ -1346,9 +1316,7 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             OnyxToken* directive_token = expect_token(parser, '#');
             OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
 
-            onyx_message_add(Msg_Type_Unknown_Directive,
-                    directive_token->pos,
-                    symbol_token->text, symbol_token->length);
+            onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
         }
     }
 
@@ -1535,9 +1503,7 @@ static AstFunction* parse_function_definition(OnyxParser* parser) {
             OnyxToken* directive_token = expect_token(parser, '#');
             OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
 
-            onyx_message_add(Msg_Type_Unknown_Directive,
-                    directive_token->pos,
-                    symbol_token->text, symbol_token->length);
+            onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
         }
     }
 
@@ -1592,9 +1558,7 @@ static AstTyped* parse_global_declaration(OnyxParser* parser) {
             OnyxToken* directive_token = expect_token(parser, '#');
             OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
 
-            onyx_message_add(Msg_Type_Unknown_Directive,
-                    directive_token->pos,
-                    symbol_token->text, symbol_token->length);
+            onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
         }
     }
 
@@ -1618,9 +1582,7 @@ static AstEnumType* parse_enum_declaration(OnyxParser* parser) {
             OnyxToken* directive_token = expect_token(parser, '#');
             OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
 
-            onyx_message_add(Msg_Type_Unknown_Directive,
-                    directive_token->pos,
-                    symbol_token->text, symbol_token->length);
+            onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
         }
     }
 
@@ -1849,8 +1811,7 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) {
                     return (AstNode *) include;
                 }
                 else {
-                    onyx_message_add(Msg_Type_Unknown_Directive,
-                            dir_token->pos, dir_token->text, dir_token->length);
+                    onyx_report_error(dir_token->pos, "unknown directive '#%b'.", dir_token->text, dir_token->length);
                     return NULL;
                 }
             }
index 7324468e7251eb61aed3b0f6f36154f974dd88b3..73e335950504970300b00ef0ac727b37a9f7d654 100644 (file)
@@ -26,7 +26,7 @@ void onyx_sempass(ProgramInfo* program) {
     semstate.program = program;
 
     onyx_resolve_symbols(program);
-    if (onyx_message_has_errors()) return;
+    if (onyx_has_errors()) return;
 
     onyx_type_check(program);
 
@@ -38,5 +38,5 @@ void onyx_sempass(ProgramInfo* program) {
         bh_arr_clear(semstate.other_entities);
     }
     
-    if (onyx_message_has_errors()) return;
+    if (onyx_has_errors()) return;
 }
index 7e4f10d52ee0b5d192c77eb9a46c8c4c0bb39e08..a91641adb8f4452661a559b72f9db01a662d463c 100644 (file)
@@ -56,11 +56,8 @@ static AstType* symres_type(AstType* type) {
         AstFieldAccess* field = (AstFieldAccess *) type;
         symres_field_access(&field);
 
-        if (!node_is_type((AstNode *) field)) {
-            onyx_message_add(Msg_Type_Literal,
-                    type->token->pos,
-                    "field access did not result in a type");
-        }
+        if (!node_is_type((AstNode *) field))
+            onyx_report_error(type->token->pos, "field access did not result in a type");
 
         return (AstType *) field;
     }
@@ -130,9 +127,6 @@ static AstType* symres_type(AstType* type) {
         return type;
     }
 
-    onyx_message_add(Msg_Type_Literal,
-            (OnyxFilePos) { 0 },
-            onyx_ast_node_kind_string(type->kind));
     return type;
 }
 
@@ -194,9 +188,7 @@ static void symres_ufc(AstBinaryOp** ufc) {
     symres_expression(&(*ufc)->left);
 
     if (call_node->kind != Ast_Kind_Call) {
-        onyx_message_add(Msg_Type_Literal,
-                (*ufc)->token->pos,
-                "universal function call expected call on right side");
+        onyx_report_error((*ufc)->token->pos, "universal function call expected call on right side");
         return;
     }
 
@@ -236,9 +228,7 @@ static void symres_struct_literal(AstStructLiteral* sl) {
     sl->type = type_build_from_ast(semstate.allocator, sl->type_node);
 
     if (!type_is_structlike_strict(sl->type)) {
-        onyx_message_add(Msg_Type_Literal,
-                sl->token->pos,
-                "type is not a constructable using a struct literal");
+        onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal.");
         return;
     }
 
@@ -250,18 +240,15 @@ static void symres_struct_literal(AstStructLiteral* sl) {
         bh_arr_each(AstStructMember *, smem, sl->named_values) {
             token_toggle_end((*smem)->token);
             if (!type_lookup_member(sl->type, (*smem)->token->text, &s)) {
-                onyx_message_add(Msg_Type_No_Field,
-                        (*smem)->token->pos,
-                        (*smem)->token->text, type_get_name(sl->type));
+                onyx_report_error((*smem)->token->pos,
+                    "The field '%s' does not exist on type '%s'.", (*smem)->token->text, type_get_name(sl->type));
                 token_toggle_end((*smem)->token);
                 return;
             }
             token_toggle_end((*smem)->token);
 
             if (sl->values[s.idx] != NULL) {
-                onyx_message_add(Msg_Type_Duplicate_Value,
-                        (*smem)->token->pos,
-                        (*smem)->token->text, (*smem)->token->length);
+                onyx_report_error((*smem)->token->pos, "Multiple values given for '%b'.", (*smem)->token->text, (*smem)->token->length);
                 return;
             }
 
@@ -275,8 +262,7 @@ static void symres_struct_literal(AstStructLiteral* sl) {
 
                 if (sl->values[idx] == NULL) {
                     if (st->members[idx]->initial_value == NULL) {
-                        onyx_message_add(Msg_Type_Field_No_Value,
-                                sl->token->pos,
+                        onyx_report_error(sl->token->pos, "No value was given for the field '%b'.",
                                 st->members[idx]->token->text,
                                 st->members[idx]->token->length);
                         return;
@@ -490,8 +476,8 @@ void symres_function(AstFunction* func) {
 
             if (param->default_value != NULL) {
                 if (!types_are_compatible(param->local->type, param->default_value->type)) {
-                    onyx_message_add(Msg_Type_Assignment_Mismatch,
-                            param->local->token->pos,
+                    onyx_report_error(param->local->token->pos,
+                            "Expected default value of type '%s', was of type '%s'.",
                             type_get_name(param->local->type),
                             type_get_name(param->default_value->type));
                     return;
@@ -529,9 +515,7 @@ void symres_function(AstFunction* func) {
                 }
 
             } else {
-                onyx_message_add(Msg_Type_Literal,
-                        param->local->token->pos,
-                        "can only 'use' structures or pointers to structures.");
+                onyx_report_error(param->local->token->pos, "can only 'use' structures or pointers to structures.");
             }
         }
     }
@@ -564,9 +548,7 @@ static void symres_use_package(AstUsePackage* package) {
     token_toggle_end(package->package->token);
 
     if (p == NULL) {
-        onyx_message_add(Msg_Type_Literal,
-            package->token->pos,
-            "package not found in included source files");
+        onyx_report_error(package->token->pos, "package not found in included source files");
         return;
     }
 
@@ -585,9 +567,7 @@ static void symres_use_package(AstUsePackage* package) {
 
             AstNode* thing = symbol_resolve(p->scope, (*alias)->token);
             if (thing == NULL) {
-                onyx_message_add(Msg_Type_Literal,
-                    (*alias)->token->pos,
-                    "not found in package");
+                onyx_report_error((*alias)->token->pos, "not found in package");
                 return;
             }
 
@@ -619,9 +599,7 @@ static void symres_enum(AstEnumType* enum_node) {
             } else if ((*value)->value->type_node == (AstType *) &basic_type_i64) {
                 next_assign_value = (*value)->value->value.l;
             } else {
-                onyx_message_add(Msg_Type_Literal,
-                    (*value)->token->pos,
-                    "expected numeric integer literal for enum initialization");
+                onyx_report_error((*value)->token->pos, "expected numeric integer literal for enum initialization");
                 return;
             }
 
index 00c7bae42c564882379336369db5454571745a1e..481aed417404109027ad994f967c8462ac041dd0 100644 (file)
@@ -3,7 +3,7 @@
 #include "onyxutils.h"
 #include "onyxlex.h"
 #include "onyxastnodes.h"
-#include "onyxmsgs.h"
+#include "onyxerrors.h"
 #include "onyxparser.h"
 #include "onyxastnodes.h"
 #include "onyxsempass.h"
@@ -156,7 +156,7 @@ b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol) {
 
 b32 symbol_raw_introduce(Scope* scope, char* name, OnyxFilePos pos, AstNode* symbol) {
     if (bh_table_has(AstNode *, scope->symbols, name)) {
-        onyx_message_add(Msg_Type_Redeclare_Symbol, pos, name);
+        onyx_report_error(pos, "Redeclaration of symbol '%s'.", name);
         return 0;
     }
 
@@ -194,7 +194,7 @@ AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) {
     AstNode* res = symbol_raw_resolve(start_scope, tkn->text);
 
     if (res == NULL) {
-        onyx_message_add(Msg_Type_Unknown_Symbol, tkn->pos, tkn->text);
+        onyx_report_error(tkn->pos, "Unable to resolve symbol '%s'", tkn->text);
         token_toggle_end(tkn);
         return &empty_node;
     }
@@ -389,9 +389,7 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, AstCall* call) {
     bh_arr_each(AstPolyParam, param, pp->poly_params) {
         AstArgument* arg = call->arguments;
         if (param->idx >= call->arg_count) {
-            onyx_message_add(Msg_Type_Literal,
-                    call->token->pos,
-                    "not enough arguments to polymorphic procedure.");
+            onyx_report_error(call->token->pos, "Not enough arguments to polymorphic procedure.");
             return NULL;
         }
 
@@ -401,9 +399,7 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, AstCall* call) {
         Type* resolved_type = solve_poly_type(param->poly_sym, param->type_expr, arg_type);
 
         if (resolved_type == NULL) {
-            onyx_message_add(Msg_Type_Literal,
-                    call->token->pos,
-                    "unable to match polymorphic procedure type.");
+            onyx_report_error(call->token->pos, "Unable to match polymorphic procedure type.");
             return NULL;
         }
 
@@ -431,16 +427,14 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, AstCall* call) {
     bh_table_put(AstFunction *, pp->concrete_funcs, key_buf, func);
 
     symres_function(func);
-    if (onyx_message_has_errors()) goto has_error;
+    if (onyx_has_errors()) goto has_error;
     if (check_function_header(func)) goto has_error;
     if (check_function(func)) goto has_error;
-    if (onyx_message_has_errors()) goto has_error;
+    if (onyx_has_errors()) goto has_error;
     goto no_errors;
 
 has_error:
-    onyx_message_add(Msg_Type_Literal,
-            call->token->pos,
-            "error in polymorphic procedure generated from this call site.");
+    onyx_report_error(call->token->pos, "Error in polymorphic procedure generated from this call site.");
     return NULL;
 
 no_errors:
index f79e6ca11a34f5dc7ca04a687ce420e6132a7fb9..e0ddb40e10014c372d9d03300bbe5c9e0a4d9116 100644 (file)
@@ -353,46 +353,46 @@ static u64 local_lookup_idx(LocalAllocator* la, u64 value) {
 #define WI(instr) bh_arr_push(code, ((WasmInstruction){ instr, 0x00 }))
 #define WID(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, data }))
 #define WIL(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, { .l = data } }))
-#define COMPILE_FUNC(kind, ...) static void compile_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, __VA_ARGS__)
-
-COMPILE_FUNC(function_body,                 AstFunction* fd);
-COMPILE_FUNC(block,                         AstBlock* block, b32 generate_block_headers);
-COMPILE_FUNC(statement,                     AstNode* stmt);
-COMPILE_FUNC(assignment,                    AstBinaryOp* assign);
-COMPILE_FUNC(store_instruction,             Type* type, u32 offset);
-COMPILE_FUNC(load_instruction,              Type* type, u32 offset);
-COMPILE_FUNC(if,                            AstIfWhile* if_node);
-COMPILE_FUNC(while,                         AstIfWhile* while_node);
-COMPILE_FUNC(for,                           AstFor* for_node);
-COMPILE_FUNC(switch,                        AstSwitch* switch_node);
-COMPILE_FUNC(defer,                         AstDefer* defer);
-COMPILE_FUNC(deferred_stmts,                AstNode* node);
-COMPILE_FUNC(binop,                         AstBinaryOp* binop);
-COMPILE_FUNC(unaryop,                       AstUnaryOp* unop);
-COMPILE_FUNC(call,                          AstCall* call);
-COMPILE_FUNC(intrinsic_call,                AstIntrinsicCall* call);
-COMPILE_FUNC(array_access_location,         AstArrayAccess* aa, u64* offset_return);
-COMPILE_FUNC(field_access_location,         AstFieldAccess* field, u64* offset_return);
-COMPILE_FUNC(local_location,                AstLocal* local, u64* offset_return);
-COMPILE_FUNC(memory_reservation_location,   AstMemRes* memres);
-COMPILE_FUNC(location,                      AstTyped* expr);
-COMPILE_FUNC(struct_load,                   Type* type, u64 offset);
-COMPILE_FUNC(struct_lval,                   AstTyped* lval);
-COMPILE_FUNC(struct_store,                  Type* type, u64 offset);
-COMPILE_FUNC(struct_literal,                AstStructLiteral* sl);
-COMPILE_FUNC(expression,                    AstTyped* expr);
-COMPILE_FUNC(cast,                          AstUnaryOp* cast);
-COMPILE_FUNC(return,                        AstReturn* ret);
-COMPILE_FUNC(stack_enter,                   u64 stacksize);
-COMPILE_FUNC(stack_leave,                   u32 unused);
-
-COMPILE_FUNC(function_body, AstFunction* fd) {
+#define EMIT_FUNC(kind, ...) static void emit_ ## kind (OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, __VA_ARGS__)
+
+EMIT_FUNC(function_body,                 AstFunction* fd);
+EMIT_FUNC(block,                         AstBlock* block, b32 generate_block_headers);
+EMIT_FUNC(statement,                     AstNode* stmt);
+EMIT_FUNC(assignment,                    AstBinaryOp* assign);
+EMIT_FUNC(store_instruction,             Type* type, u32 offset);
+EMIT_FUNC(load_instruction,              Type* type, u32 offset);
+EMIT_FUNC(if,                            AstIfWhile* if_node);
+EMIT_FUNC(while,                         AstIfWhile* while_node);
+EMIT_FUNC(for,                           AstFor* for_node);
+EMIT_FUNC(switch,                        AstSwitch* switch_node);
+EMIT_FUNC(defer,                         AstDefer* defer);
+EMIT_FUNC(deferred_stmts,                AstNode* node);
+EMIT_FUNC(binop,                         AstBinaryOp* binop);
+EMIT_FUNC(unaryop,                       AstUnaryOp* unop);
+EMIT_FUNC(call,                          AstCall* call);
+EMIT_FUNC(intrinsic_call,                AstIntrinsicCall* call);
+EMIT_FUNC(array_access_location,         AstArrayAccess* aa, u64* offset_return);
+EMIT_FUNC(field_access_location,         AstFieldAccess* field, u64* offset_return);
+EMIT_FUNC(local_location,                AstLocal* local, u64* offset_return);
+EMIT_FUNC(memory_reservation_location,   AstMemRes* memres);
+EMIT_FUNC(location,                      AstTyped* expr);
+EMIT_FUNC(struct_load,                   Type* type, u64 offset);
+EMIT_FUNC(struct_lval,                   AstTyped* lval);
+EMIT_FUNC(struct_store,                  Type* type, u64 offset);
+EMIT_FUNC(struct_literal,                AstStructLiteral* sl);
+EMIT_FUNC(expression,                    AstTyped* expr);
+EMIT_FUNC(cast,                          AstUnaryOp* cast);
+EMIT_FUNC(return,                        AstReturn* ret);
+EMIT_FUNC(stack_enter,                   u64 stacksize);
+EMIT_FUNC(stack_leave,                   u32 unused);
+
+EMIT_FUNC(function_body, AstFunction* fd) {
     if (fd->body == NULL) return;
 
-    compile_block(mod, pcode, fd->body, 0);
+    emit_block(mod, pcode, fd->body, 0);
 }
 
-COMPILE_FUNC(block, AstBlock* block, b32 generate_block_headers) {
+EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (generate_block_headers) {
@@ -404,10 +404,10 @@ COMPILE_FUNC(block, AstBlock* block, b32 generate_block_headers) {
         bh_imap_put(&mod->local_map, (u64) *local, local_allocate(mod->local_alloc, *local));
 
     forll (AstNode, stmt, block->body, next) {
-        compile_statement(mod, &code, stmt);
+        emit_statement(mod, &code, stmt);
     }
 
-    compile_deferred_stmts(mod, &code, (AstNode *) block);
+    emit_deferred_stmts(mod, &code, (AstNode *) block);
 
     bh_arr_each(AstLocal *, local, block->locals)
         local_free(mod->local_alloc, *local);
@@ -420,7 +420,7 @@ COMPILE_FUNC(block, AstBlock* block, b32 generate_block_headers) {
     *pcode = code;
 }
 
-COMPILE_FUNC(structured_jump, i32 jump_count, JumpType jump) {
+EMIT_FUNC(structured_jump, i32 jump_count, JumpType jump) {
     bh_arr(WasmInstruction) code = *pcode;
 
     static const u8 wants[Jump_Type_Count] = { 1, 2, 3 };
@@ -452,30 +452,30 @@ COMPILE_FUNC(structured_jump, i32 jump_count, JumpType jump) {
     *pcode = code;
 }
 
-COMPILE_FUNC(statement, AstNode* stmt) {
+EMIT_FUNC(statement, AstNode* stmt) {
     bh_arr(WasmInstruction) code = *pcode;
 
     switch (stmt->kind) {
-        case Ast_Kind_Return:     compile_return(mod, &code, (AstReturn *) stmt); break;
-        case Ast_Kind_If:         compile_if(mod, &code, (AstIfWhile *) stmt); break;
-        case Ast_Kind_While:      compile_while(mod, &code, (AstIfWhile *) stmt); break;
-        case Ast_Kind_For:        compile_for(mod, &code, (AstFor *) stmt); break;
-        case Ast_Kind_Switch:     compile_switch(mod, &code, (AstSwitch *) stmt); break;
-        case Ast_Kind_Jump:       compile_structured_jump(mod, &code, ((AstJump *) stmt)->count, ((AstJump *) stmt)->jump); break;
-        case Ast_Kind_Block:      compile_block(mod, &code, (AstBlock *) stmt, 1); break;
-        case Ast_Kind_Defer:      compile_defer(mod, &code, (AstDefer *) stmt); break;
-        default:                  compile_expression(mod, &code, (AstTyped *) stmt); break;
+        case Ast_Kind_Return:     emit_return(mod, &code, (AstReturn *) stmt); break;
+        case Ast_Kind_If:         emit_if(mod, &code, (AstIfWhile *) stmt); break;
+        case Ast_Kind_While:      emit_while(mod, &code, (AstIfWhile *) stmt); break;
+        case Ast_Kind_For:        emit_for(mod, &code, (AstFor *) stmt); break;
+        case Ast_Kind_Switch:     emit_switch(mod, &code, (AstSwitch *) stmt); break;
+        case Ast_Kind_Jump:       emit_structured_jump(mod, &code, ((AstJump *) stmt)->count, ((AstJump *) stmt)->jump); break;
+        case Ast_Kind_Block:      emit_block(mod, &code, (AstBlock *) stmt, 1); break;
+        case Ast_Kind_Defer:      emit_defer(mod, &code, (AstDefer *) stmt); break;
+        default:                  emit_expression(mod, &code, (AstTyped *) stmt); break;
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(assignment, AstBinaryOp* assign) {
+EMIT_FUNC(assignment, AstBinaryOp* assign) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (type_is_structlike_strict(assign->right->type)) {
-        compile_expression(mod, &code, assign->right);
-        compile_struct_lval(mod, &code, assign->left);
+        emit_expression(mod, &code, assign->right);
+        emit_struct_lval(mod, &code, assign->left);
 
         *pcode = code;
         return;
@@ -486,53 +486,53 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) {
     if (lval->kind == Ast_Kind_Local) {
         if (bh_imap_get(&mod->local_map, (u64) lval) & LOCAL_IS_WASM) {
             u64 localidx = bh_imap_get(&mod->local_map, (u64) lval);
-            compile_expression(mod, &code, assign->right);
+            emit_expression(mod, &code, assign->right);
             WIL(WI_LOCAL_SET, localidx);
 
         } else {
             u64 offset = 0;
-            compile_local_location(mod, &code, (AstLocal *) lval, &offset);
-            compile_expression(mod, &code, assign->right);
-            compile_store_instruction(mod, &code, lval->type, offset);
+            emit_local_location(mod, &code, (AstLocal *) lval, &offset);
+            emit_expression(mod, &code, assign->right);
+            emit_store_instruction(mod, &code, lval->type, offset);
         }
 
     } else if (lval->kind == Ast_Kind_Global) {
         i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) lval);
 
-        compile_expression(mod, &code, assign->right);
+        emit_expression(mod, &code, assign->right);
         WID(WI_GLOBAL_SET, globalidx);
 
     } else if (lval->kind == Ast_Kind_Dereference) {
         AstDereference* deref = (AstDereference *) lval;
-        compile_expression(mod, &code, deref->expr);
-        compile_expression(mod, &code, assign->right);
+        emit_expression(mod, &code, deref->expr);
+        emit_expression(mod, &code, assign->right);
 
-        compile_store_instruction(mod, &code, deref->type, 0);
+        emit_store_instruction(mod, &code, deref->type, 0);
 
     } else if (lval->kind == Ast_Kind_Array_Access) {
         AstArrayAccess* aa = (AstArrayAccess *) lval;
 
         u64 offset = 0;
-        compile_array_access_location(mod, &code, aa, &offset);
-        compile_expression(mod, &code, assign->right);
+        emit_array_access_location(mod, &code, aa, &offset);
+        emit_expression(mod, &code, assign->right);
 
-        compile_store_instruction(mod, &code, aa->type, offset);
+        emit_store_instruction(mod, &code, aa->type, offset);
 
     } else if (lval->kind == Ast_Kind_Field_Access) {
         AstFieldAccess* field = (AstFieldAccess *) lval;
 
         u64 offset = 0;
-        compile_field_access_location(mod, &code, field, &offset);
-        compile_expression(mod, &code, assign->right);
+        emit_field_access_location(mod, &code, field, &offset);
+        emit_expression(mod, &code, assign->right);
 
-        compile_store_instruction(mod, &code, field->type, offset);
+        emit_store_instruction(mod, &code, field->type, offset);
 
     } else if (lval->kind == Ast_Kind_Memres) {
         AstMemRes* memres = (AstMemRes *) lval;
 
-        compile_memory_reservation_location(mod, &code, memres);
-        compile_expression(mod, &code, assign->right);
-        compile_store_instruction(mod, &code, memres->type, 0);
+        emit_memory_reservation_location(mod, &code, memres);
+        emit_expression(mod, &code, assign->right);
+        emit_store_instruction(mod, &code, memres->type, 0);
 
     } else {
         assert(("Invalid lval", 0));
@@ -541,11 +541,11 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) {
     *pcode = code;
 }
 
-COMPILE_FUNC(store_instruction, Type* type, u32 offset) {
+EMIT_FUNC(store_instruction, Type* type, u32 offset) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (type_is_structlike_strict(type)) {
-        compile_struct_store(mod, pcode, type, offset);
+        emit_struct_store(mod, pcode, type, offset);
         return;
     }
 
@@ -576,19 +576,19 @@ COMPILE_FUNC(store_instruction, Type* type, u32 offset) {
         if      (store_size == 4)   WID(WI_F32_STORE, ((WasmInstructionData) { alignment, offset }));
         else if (store_size == 8)   WID(WI_F64_STORE, ((WasmInstructionData) { alignment, offset }));
     } else {
-        onyx_message_add(Msg_Type_Failed_Gen_Store,
-            (OnyxFilePos) { 0 },
+        onyx_report_error((OnyxFilePos) { 0 },
+            "Failed to generate store instruction for type '%s'.",
             type_get_name(type));
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(load_instruction, Type* type, u32 offset) {
+EMIT_FUNC(load_instruction, Type* type, u32 offset) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (type_is_structlike_strict(type)) {
-        compile_struct_load(mod, pcode, type, offset);
+        emit_struct_load(mod, pcode, type, offset);
         return;
     }
 
@@ -639,36 +639,36 @@ COMPILE_FUNC(load_instruction, Type* type, u32 offset) {
     WID(instr, ((WasmInstructionData) { alignment, offset }));
 
     if (instr == WI_NOP) {
-        onyx_message_add(Msg_Type_Failed_Gen_Load,
-                (OnyxFilePos) { 0 },
-                type_get_name(type));
+        onyx_report_error((OnyxFilePos) { 0 },
+            "Failed to generate load instruction for type '%s'.",
+            type_get_name(type));
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(if, AstIfWhile* if_node) {
+EMIT_FUNC(if, AstIfWhile* if_node) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (if_node->assignment != NULL) {
         bh_imap_put(&mod->local_map, (u64) if_node->local, local_allocate(mod->local_alloc, if_node->local));
 
-        compile_assignment(mod, &code, if_node->assignment);
+        emit_assignment(mod, &code, if_node->assignment);
     }
 
-    compile_expression(mod, &code, if_node->cond);
+    emit_expression(mod, &code, if_node->cond);
     WID(WI_IF_START, 0x40);
 
     bh_arr_push(mod->structured_jump_target, 0);
-    if (if_node->true_stmt) compile_block(mod, &code, if_node->true_stmt, 0);
+    if (if_node->true_stmt) emit_block(mod, &code, if_node->true_stmt, 0);
 
     if (if_node->false_stmt) {
         WI(WI_ELSE);
 
         if (if_node->false_stmt->kind == Ast_Kind_If) {
-            compile_if(mod, &code, (AstIfWhile *) if_node->false_stmt);
+            emit_if(mod, &code, (AstIfWhile *) if_node->false_stmt);
         } else {
-            compile_block(mod, &code, if_node->false_stmt, 0);
+            emit_block(mod, &code, if_node->false_stmt, 0);
         }
     }
 
@@ -683,27 +683,27 @@ COMPILE_FUNC(if, AstIfWhile* if_node) {
     *pcode = code;
 }
 
-COMPILE_FUNC(while, AstIfWhile* while_node) {
+EMIT_FUNC(while, AstIfWhile* while_node) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (while_node->assignment != NULL) {
         bh_imap_put(&mod->local_map, (u64) while_node->local, local_allocate(mod->local_alloc, while_node->local));
 
-        compile_assignment(mod, &code, while_node->assignment);
+        emit_assignment(mod, &code, while_node->assignment);
     }
 
     if (while_node->false_stmt == NULL) {
         WID(WI_BLOCK_START, 0x40);
         WID(WI_LOOP_START, 0x40);
 
-        compile_expression(mod, &code, while_node->cond);
+        emit_expression(mod, &code, while_node->cond);
         WI(WI_I32_EQZ);
         WID(WI_COND_JUMP, 0x01);
 
         bh_arr_push(mod->structured_jump_target, 1);
         bh_arr_push(mod->structured_jump_target, 2);
 
-        compile_block(mod, &code, while_node->true_stmt, 0);
+        emit_block(mod, &code, while_node->true_stmt, 0);
 
         bh_arr_pop(mod->structured_jump_target);
         bh_arr_pop(mod->structured_jump_target);
@@ -715,20 +715,20 @@ COMPILE_FUNC(while, AstIfWhile* while_node) {
         WI(WI_BLOCK_END);
 
     } else {
-        compile_expression(mod, &code, while_node->cond);
+        emit_expression(mod, &code, while_node->cond);
 
         bh_arr_push(mod->structured_jump_target, 1);
         bh_arr_push(mod->structured_jump_target, 2);
         WID(WI_IF_START, 0x40);
 
         WID(WI_LOOP_START, 0x40);
-        compile_block(mod, &code, while_node->true_stmt, 0);
-        compile_expression(mod, &code, while_node->cond);
+        emit_block(mod, &code, while_node->true_stmt, 0);
+        emit_expression(mod, &code, while_node->cond);
         WID(WI_COND_JUMP, 0x00);
         WI(WI_LOOP_END);
 
         WI(WI_ELSE);
-        compile_block(mod, &code, while_node->false_stmt, 0);
+        emit_block(mod, &code, while_node->false_stmt, 0);
         WID(WI_IF_END, 0x40);
 
         bh_arr_pop(mod->structured_jump_target);
@@ -741,7 +741,7 @@ COMPILE_FUNC(while, AstIfWhile* while_node) {
     *pcode = code;
 }
 
-COMPILE_FUNC(for, AstFor* for_node) {
+EMIT_FUNC(for, AstFor* for_node) {
     bh_arr(WasmInstruction) code = *pcode;
 
     AstLocal* var = for_node->var;
@@ -757,12 +757,12 @@ COMPILE_FUNC(for, AstFor* for_node) {
     WasmInstructionType ge_instr  = var_type == WASM_TYPE_INT32 ? WI_I32_GE_S : WI_I64_GE_S;
 
     if (it_is_local) {
-        compile_expression(mod, &code, for_node->start);
+        emit_expression(mod, &code, for_node->start);
         WIL(WI_LOCAL_SET, tmp);
     } else {
-        compile_local_location(mod, &code, var, &offset);
-        compile_expression(mod, &code, for_node->start);
-        compile_store_instruction(mod, &code, var->type, offset);
+        emit_local_location(mod, &code, var, &offset);
+        emit_expression(mod, &code, for_node->start);
+        emit_store_instruction(mod, &code, var->type, offset);
     }
 
     WID(WI_BLOCK_START, 0x40);
@@ -775,29 +775,29 @@ COMPILE_FUNC(for, AstFor* for_node) {
         WIL(WI_LOCAL_GET, tmp);
     } else {
         offset = 0;
-        compile_local_location(mod, &code, var, &offset);
-        compile_load_instruction(mod, &code, var->type, offset);
+        emit_local_location(mod, &code, var, &offset);
+        emit_load_instruction(mod, &code, var->type, offset);
     }
-    compile_expression(mod, &code, for_node->end);
+    emit_expression(mod, &code, for_node->end);
     WI(ge_instr);
     WID(WI_COND_JUMP, 0x01);
 
-    compile_block(mod, &code, for_node->stmt, 0);
+    emit_block(mod, &code, for_node->stmt, 0);
 
     if (it_is_local) {
         WIL(WI_LOCAL_GET, tmp);
-        compile_expression(mod, &code, for_node->step);
+        emit_expression(mod, &code, for_node->step);
         WI(add_instr);
         WIL(WI_LOCAL_SET, tmp);
     } else {
         offset = 0;
-        compile_local_location(mod, &code, var, &offset);
+        emit_local_location(mod, &code, var, &offset);
         offset = 0;
-        compile_local_location(mod, &code, var, &offset);
-        compile_load_instruction(mod, &code, var->type, offset);
-        compile_expression(mod, &code, for_node->step);
+        emit_local_location(mod, &code, var, &offset);
+        emit_load_instruction(mod, &code, var->type, offset);
+        emit_expression(mod, &code, for_node->step);
         WI(add_instr);
-        compile_store_instruction(mod, &code, var->type, offset);
+        emit_store_instruction(mod, &code, var->type, offset);
     }
 
     bh_arr_pop(mod->structured_jump_target);
@@ -814,7 +814,7 @@ COMPILE_FUNC(for, AstFor* for_node) {
     *pcode = code;
 }
 
-COMPILE_FUNC(switch, AstSwitch* switch_node) {
+EMIT_FUNC(switch, AstSwitch* switch_node) {
     bh_arr(WasmInstruction) code = *pcode;
 
     bh_imap block_map;
@@ -823,7 +823,7 @@ COMPILE_FUNC(switch, AstSwitch* switch_node) {
     if (switch_node->assignment != NULL) {
         bh_imap_put(&mod->local_map, (u64) switch_node->local, local_allocate(mod->local_alloc, switch_node->local));
 
-        compile_assignment(mod, &code, switch_node->assignment);
+        emit_assignment(mod, &code, switch_node->assignment);
     }
 
     WID(WI_BLOCK_START, 0x40);
@@ -851,7 +851,7 @@ COMPILE_FUNC(switch, AstSwitch* switch_node) {
     }
 
     WID(WI_BLOCK_START, 0x40);
-    compile_expression(mod, &code, switch_node->expr);
+    emit_expression(mod, &code, switch_node->expr);
     if (switch_node->min_case != 0) {
         WID(WI_I32_CONST, switch_node->min_case);
         WI(WI_I32_SUB);
@@ -864,7 +864,7 @@ COMPILE_FUNC(switch, AstSwitch* switch_node) {
 
         u64 bn = bh_imap_get(&block_map, (u64) sc->block);
 
-        compile_block(mod, &code, sc->block, 0);
+        emit_block(mod, &code, sc->block, 0);
 
         if (bh_arr_last(code).type != WI_JUMP)
             WID(WI_JUMP, block_num - bn);
@@ -876,7 +876,7 @@ COMPILE_FUNC(switch, AstSwitch* switch_node) {
     }
 
     if (switch_node->default_case != NULL) {
-        compile_block(mod, &code, switch_node->default_case, 0);
+        emit_block(mod, &code, switch_node->default_case, 0);
     }
 
     WI(WI_BLOCK_END);
@@ -889,14 +889,14 @@ COMPILE_FUNC(switch, AstSwitch* switch_node) {
     *pcode = code;
 }
 
-COMPILE_FUNC(defer, AstDefer* defer) {
+EMIT_FUNC(defer, AstDefer* defer) {
     bh_arr_push(mod->deferred_stmts, ((DeferredStmt) {
         .depth = bh_arr_length(mod->structured_jump_target),
         .stmt = defer->stmt,
     }));
 }
 
-COMPILE_FUNC(deferred_stmts, AstNode* node) {
+EMIT_FUNC(deferred_stmts, AstNode* node) {
     if (bh_arr_length(mod->deferred_stmts) == 0) return;
 
     bh_arr(WasmInstruction) code = *pcode;
@@ -904,7 +904,7 @@ COMPILE_FUNC(deferred_stmts, AstNode* node) {
     u64 depth = bh_arr_length(mod->structured_jump_target);
 
     while (bh_arr_last(mod->deferred_stmts).depth == depth) {
-        compile_statement(mod, &code, bh_arr_last(mod->deferred_stmts).stmt);
+        emit_statement(mod, &code, bh_arr_last(mod->deferred_stmts).stmt);
         bh_arr_pop(mod->deferred_stmts);
     }
 
@@ -939,11 +939,11 @@ static const WasmInstructionType binop_map[][4] = {
     /* BOR  */ { WI_I32_OR,    WI_I64_OR,    WI_NOP,     WI_NOP },
 };
 
-COMPILE_FUNC(binop, AstBinaryOp* binop) {
+EMIT_FUNC(binop, AstBinaryOp* binop) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (binop_is_assignment(binop)) {
-        compile_assignment(mod, &code, binop);
+        emit_assignment(mod, &code, binop);
         *pcode = code;
         return;
     }
@@ -984,15 +984,15 @@ COMPILE_FUNC(binop, AstBinaryOp* binop) {
         }
     }
 
-    compile_expression(mod, &code, binop->left);
-    compile_expression(mod, &code, binop->right);
+    emit_expression(mod, &code, binop->left);
+    emit_expression(mod, &code, binop->right);
 
     WI(binop_instr);
 
     *pcode = code;
 }
 
-COMPILE_FUNC(unaryop, AstUnaryOp* unop) {
+EMIT_FUNC(unaryop, AstUnaryOp* unop) {
     bh_arr(WasmInstruction) code = *pcode;
 
     switch (unop->operation) {
@@ -1003,18 +1003,18 @@ COMPILE_FUNC(unaryop, AstUnaryOp* unop) {
                     || type->kind == Basic_Kind_I16
                     || type->kind == Basic_Kind_I8) {
                 WID(WI_I32_CONST, 0x00);
-                compile_expression(mod, &code, unop->expr);
+                emit_expression(mod, &code, unop->expr);
                 WI(WI_I32_SUB);
 
             }
             else if (type->kind == Basic_Kind_I64) {
                 WID(WI_I64_CONST, 0x00);
-                compile_expression(mod, &code, unop->expr);
+                emit_expression(mod, &code, unop->expr);
                 WI(WI_I64_SUB);
 
             }
             else {
-                compile_expression(mod, &code, unop->expr);
+                emit_expression(mod, &code, unop->expr);
 
                 if (type->kind == Basic_Kind_F32)
                     WI(WI_F32_NEG);
@@ -1027,24 +1027,24 @@ COMPILE_FUNC(unaryop, AstUnaryOp* unop) {
         }
 
         case Unary_Op_Not:
-            compile_expression(mod, &code, unop->expr);
+            emit_expression(mod, &code, unop->expr);
 
             WI(WI_I32_EQZ);
             break;
 
-        case Unary_Op_Cast: compile_cast(mod, &code, unop); break;
+        case Unary_Op_Cast: emit_cast(mod, &code, unop); break;
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(call, AstCall* call) {
+EMIT_FUNC(call, AstCall* call) {
     bh_arr(WasmInstruction) code = *pcode;
 
     for (AstArgument *arg = call->arguments;
             arg != NULL;
             arg = (AstArgument *) arg->next) {
-        compile_expression(mod, &code, arg->value);
+        emit_expression(mod, &code, arg->value);
     }
 
     CallingConvention cc = type_function_get_cc(call->callee->type);
@@ -1069,7 +1069,7 @@ COMPILE_FUNC(call, AstCall* call) {
         bh_arr_push(code, ((WasmInstruction){ WI_CALL, func_idx }));
 
     } else {
-        compile_expression(mod, &code, call->callee);
+        emit_expression(mod, &code, call->callee);
 
         i32 type_idx = generate_type_idx(mod, call->callee->type);
         WID(WI_CALL_INDIRECT, ((WasmInstructionData) { type_idx, 0x00 }));
@@ -1082,13 +1082,13 @@ COMPILE_FUNC(call, AstCall* call) {
         WID(WI_GLOBAL_SET, stack_top_idx);
 
         WID(WI_GLOBAL_GET, stack_top_idx);
-        compile_load_instruction(mod, &code, return_type, 0);
+        emit_load_instruction(mod, &code, return_type, 0);
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(intrinsic_call, AstIntrinsicCall* call) {
+EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
     bh_arr(WasmInstruction) code = *pcode;
 
     i32 place_arguments_normally = 1;
@@ -1101,7 +1101,7 @@ COMPILE_FUNC(intrinsic_call, AstIntrinsicCall* call) {
         for (AstArgument *arg = call->arguments;
                 arg != NULL;
                 arg = (AstArgument *) arg->next) {
-            compile_expression(mod, &code, arg->value);
+            emit_expression(mod, &code, arg->value);
         }
     }
 
@@ -1159,10 +1159,10 @@ COMPILE_FUNC(intrinsic_call, AstIntrinsicCall* call) {
     *pcode = code;
 }
 
-COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) {
+EMIT_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    compile_expression(mod, &code, aa->expr);
+    emit_expression(mod, &code, aa->expr);
     if (aa->elem_size != 1) {
         WID(WI_I32_CONST, aa->elem_size);
         WI(WI_I32_MUL);
@@ -1171,18 +1171,18 @@ COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) {
     u64 offset = 0;
     if (aa->addr->kind == Ast_Kind_Array_Access
         && aa->addr->type->kind == Type_Kind_Array) {
-        compile_array_access_location(mod, &code, (AstArrayAccess *) aa->addr, &offset);
+        emit_array_access_location(mod, &code, (AstArrayAccess *) aa->addr, &offset);
     } else if (aa->addr->kind == Ast_Kind_Field_Access
         && aa->addr->type->kind == Type_Kind_Array) {
-        compile_field_access_location(mod, &code, (AstFieldAccess *) aa->addr, &offset);
+        emit_field_access_location(mod, &code, (AstFieldAccess *) aa->addr, &offset);
     } else if ((aa->addr->kind == Ast_Kind_Local || aa->addr->kind == Ast_Kind_Param)
         && aa->addr->type->kind == Type_Kind_Array) {
-        compile_local_location(mod, &code, (AstLocal *) aa->addr, &offset);
+        emit_local_location(mod, &code, (AstLocal *) aa->addr, &offset);
     } else if (aa->addr->kind == Ast_Kind_Memres
         && aa->addr->type->kind != Type_Kind_Array) {
-        compile_memory_reservation_location(mod, &code, (AstMemRes *) aa->addr);
+        emit_memory_reservation_location(mod, &code, (AstMemRes *) aa->addr);
     } else {
-        compile_expression(mod, &code, aa->addr);
+        emit_expression(mod, &code, aa->addr);
     }
     WI(WI_I32_ADD);
 
@@ -1191,7 +1191,7 @@ COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) {
     *pcode = code;
 }
 
-COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) {
+EMIT_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) {
     bh_arr(WasmInstruction) code = *pcode;
 
     u64 offset = field->offset;
@@ -1205,18 +1205,18 @@ COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) {
     if (source_expr->kind == Ast_Kind_Array_Access
         && source_expr->type->kind != Type_Kind_Pointer) {
         u64 o2 = 0;
-        compile_array_access_location(mod, &code, (AstArrayAccess *) source_expr, &o2);
+        emit_array_access_location(mod, &code, (AstArrayAccess *) source_expr, &o2);
         offset += o2;
     } else if ((source_expr->kind == Ast_Kind_Local || source_expr->kind == Ast_Kind_Param)
         && source_expr->type->kind != Type_Kind_Pointer) {
         u64 o2 = 0;
-        compile_local_location(mod, &code, (AstLocal *) source_expr, &o2);
+        emit_local_location(mod, &code, (AstLocal *) source_expr, &o2);
         offset += o2;
     } else if (source_expr->kind == Ast_Kind_Memres
         && source_expr->type->kind != Type_Kind_Pointer) {
-        compile_memory_reservation_location(mod, &code, (AstMemRes *) source_expr);
+        emit_memory_reservation_location(mod, &code, (AstMemRes *) source_expr);
     } else {
-        compile_expression(mod, &code, source_expr);
+        emit_expression(mod, &code, source_expr);
     }
 
     *offset_return = offset;
@@ -1224,7 +1224,7 @@ COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) {
     *pcode = code;
 }
 
-COMPILE_FUNC(memory_reservation_location, AstMemRes* memres) {
+EMIT_FUNC(memory_reservation_location, AstMemRes* memres) {
     bh_arr(WasmInstruction) code = *pcode;
 
     WID(WI_I32_CONST, memres->addr);
@@ -1232,7 +1232,7 @@ COMPILE_FUNC(memory_reservation_location, AstMemRes* memres) {
     *pcode = code;
 }
 
-COMPILE_FUNC(local_location, AstLocal* local, u64* offset_return) {
+EMIT_FUNC(local_location, AstLocal* local, u64* offset_return) {
     bh_arr(WasmInstruction) code = *pcode;
 
     u64 local_offset = (u64) bh_imap_get(&mod->local_map, (u64) local);
@@ -1253,7 +1253,7 @@ COMPILE_FUNC(local_location, AstLocal* local, u64* offset_return) {
     *pcode = code;
 }
 
-COMPILE_FUNC(struct_load, Type* type, u64 offset) {
+EMIT_FUNC(struct_load, Type* type, u64 offset) {
     // NOTE: Expects the stack to look like:
     //      <location>
 
@@ -1266,7 +1266,7 @@ COMPILE_FUNC(struct_load, Type* type, u64 offset) {
 
     if (mem_count == 1) {
         type_lookup_member_by_idx(type, 0, &smem);
-        compile_load_instruction(mod, &code, smem.type, offset);
+        emit_load_instruction(mod, &code, smem.type, offset);
         *pcode = code;
         return;
     }
@@ -1277,7 +1277,7 @@ COMPILE_FUNC(struct_load, Type* type, u64 offset) {
     fori (i, 0, mem_count) {
         type_lookup_member_by_idx(type, i, &smem);
         if (i != 0) WIL(WI_LOCAL_GET, tmp_idx);
-        compile_load_instruction(mod, &code, smem.type, offset + smem.offset);
+        emit_load_instruction(mod, &code, smem.type, offset + smem.offset);
     }
 
     local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
@@ -1285,7 +1285,7 @@ COMPILE_FUNC(struct_load, Type* type, u64 offset) {
     *pcode = code;
 }
 
-COMPILE_FUNC(struct_lval, AstTyped* lval) {
+EMIT_FUNC(struct_lval, AstTyped* lval) {
     // NOTE: Expects the stack to look like:
     //      mem_1
     //      mem_2
@@ -1299,21 +1299,21 @@ COMPILE_FUNC(struct_lval, AstTyped* lval) {
     u64 offset = 0;
 
     switch (lval->kind) {
-        case Ast_Kind_Local:        compile_local_location(mod, &code, (AstLocal *) lval, &offset); break;
-        case Ast_Kind_Dereference:  compile_expression(mod, &code, ((AstDereference *) lval)->expr); break;
-        case Ast_Kind_Array_Access: compile_array_access_location(mod, &code, (AstArrayAccess *) lval, &offset); break;
-        case Ast_Kind_Field_Access: compile_field_access_location(mod, &code, (AstFieldAccess *) lval, &offset); break;
-        case Ast_Kind_Memres:       compile_memory_reservation_location(mod, &code, (AstMemRes *) lval); break;
+        case Ast_Kind_Local:        emit_local_location(mod, &code, (AstLocal *) lval, &offset); break;
+        case Ast_Kind_Dereference:  emit_expression(mod, &code, ((AstDereference *) lval)->expr); break;
+        case Ast_Kind_Array_Access: emit_array_access_location(mod, &code, (AstArrayAccess *) lval, &offset); break;
+        case Ast_Kind_Field_Access: emit_field_access_location(mod, &code, (AstFieldAccess *) lval, &offset); break;
+        case Ast_Kind_Memres:       emit_memory_reservation_location(mod, &code, (AstMemRes *) lval); break;
 
         default: assert(0);
     }
 
-    compile_struct_store(mod, &code, lval->type, offset);
+    emit_struct_store(mod, &code, lval->type, offset);
 
     *pcode = code;
 }
 
-COMPILE_FUNC(struct_store, Type* type, u64 offset) {
+EMIT_FUNC(struct_store, Type* type, u64 offset) {
     // NOTE: Expects the stack to look like:
     //      mem_1
     //      mem_2
@@ -1341,7 +1341,7 @@ COMPILE_FUNC(struct_store, Type* type, u64 offset) {
                 WIL(WI_LOCAL_GET, loc_idx);
             }
 
-            compile_struct_store(mod, &code, smem.type, offset + smem.offset);
+            emit_struct_store(mod, &code, smem.type, offset + smem.offset);
 
         } else {
             WasmType wt = onyx_type_to_wasm_type(smem.type);
@@ -1351,7 +1351,7 @@ COMPILE_FUNC(struct_store, Type* type, u64 offset) {
             WIL(WI_LOCAL_GET, loc_idx);
             WIL(WI_LOCAL_GET, tmp_idx);
 
-            compile_store_instruction(mod, &code, smem.type, offset + smem.offset);
+            emit_store_instruction(mod, &code, smem.type, offset + smem.offset);
 
             local_raw_free(mod->local_alloc, wt);
         }
@@ -1362,24 +1362,24 @@ COMPILE_FUNC(struct_store, Type* type, u64 offset) {
     *pcode = code;
 }
 
-COMPILE_FUNC(struct_literal, AstStructLiteral* sl) {
+EMIT_FUNC(struct_literal, AstStructLiteral* sl) {
     bh_arr(WasmInstruction) code = *pcode;
 
     bh_arr_each(AstTyped *, val, sl->values) {
-        compile_expression(mod, &code, *val);
+        emit_expression(mod, &code, *val);
     }
 
     *pcode = code;
 }
 
-COMPILE_FUNC(location, AstTyped* expr) {
+EMIT_FUNC(location, AstTyped* expr) {
     bh_arr(WasmInstruction) code = *pcode;
 
     switch (expr->kind) {
         case Ast_Kind_Param:
         case Ast_Kind_Local: {
             u64 offset = 0;
-            compile_local_location(mod, &code, (AstLocal *) expr, &offset);
+            emit_local_location(mod, &code, (AstLocal *) expr, &offset);
             if (offset != 0) {
                 WID(WI_I32_CONST, offset);
                 WI(WI_I32_ADD);
@@ -1388,14 +1388,14 @@ COMPILE_FUNC(location, AstTyped* expr) {
         }
 
         case Ast_Kind_Dereference: {
-            compile_expression(mod, &code, ((AstDereference *) expr)->expr);
+            emit_expression(mod, &code, ((AstDereference *) expr)->expr);
             break;
         }
 
         case Ast_Kind_Array_Access: {
             AstArrayAccess* aa = (AstArrayAccess *) expr;
             u64 offset = 0;
-            compile_array_access_location(mod, &code, aa, &offset);
+            emit_array_access_location(mod, &code, aa, &offset);
             if (offset != 0) {
                 WID(WI_I32_CONST, offset);
                 WI(WI_I32_ADD);
@@ -1414,7 +1414,7 @@ COMPILE_FUNC(location, AstTyped* expr) {
             }
 
             u64 offset = 0;
-            compile_field_access_location(mod, &code, field, &offset);
+            emit_field_access_location(mod, &code, field, &offset);
             if (offset != 0) {
                 WID(WI_I32_CONST, offset);
                 WI(WI_I32_ADD);
@@ -1429,10 +1429,7 @@ COMPILE_FUNC(location, AstTyped* expr) {
         }
 
         default: {
-            DEBUG_HERE;
-            onyx_message_add(Msg_Type_Literal,
-                    (OnyxFilePos) { 0 },
-                    "location unknown");
+            onyx_report_error(expr->token->pos, "Unable to generate locate for '%s'.", onyx_ast_node_kind_string(expr->kind));
             break;
         }
     }
@@ -1440,7 +1437,7 @@ COMPILE_FUNC(location, AstTyped* expr) {
     *pcode = code;
 }
 
-COMPILE_FUNC(expression, AstTyped* expr) {
+EMIT_FUNC(expression, AstTyped* expr) {
     bh_arr(WasmInstruction) code = *pcode;
 
     switch (expr->kind) {
@@ -1473,10 +1470,10 @@ COMPILE_FUNC(expression, AstTyped* expr) {
 
             } else {
                 u64 offset = 0;
-                compile_local_location(mod, &code, (AstLocal *) expr, &offset);
+                emit_local_location(mod, &code, (AstLocal *) expr, &offset);
 
                 if (expr->type->kind != Type_Kind_Array) {
-                    compile_load_instruction(mod, &code, expr->type, offset);
+                    emit_load_instruction(mod, &code, expr->type, offset);
                 } else if (offset != 0) {
                     WID(WI_I32_CONST, offset);
                     WI(WI_I32_ADD);
@@ -1523,7 +1520,7 @@ COMPILE_FUNC(expression, AstTyped* expr) {
         }
 
         case Ast_Kind_Struct_Literal: {
-            compile_struct_literal(mod, &code, (AstStructLiteral *) expr);
+            emit_struct_literal(mod, &code, (AstStructLiteral *) expr);
             break;
         }
 
@@ -1533,30 +1530,30 @@ COMPILE_FUNC(expression, AstTyped* expr) {
             break;
         }
 
-        case Ast_Kind_Block:          compile_block(mod, &code, (AstBlock *) expr, 1); break;
-        case Ast_Kind_Call:           compile_call(mod, &code, (AstCall *) expr); break;
-        case Ast_Kind_Intrinsic_Call: compile_intrinsic_call(mod, &code, (AstIntrinsicCall *) expr); break;
-        case Ast_Kind_Binary_Op:      compile_binop(mod, &code, (AstBinaryOp *) expr); break;
-        case Ast_Kind_Unary_Op:       compile_unaryop(mod, &code, (AstUnaryOp *) expr); break;
+        case Ast_Kind_Block:          emit_block(mod, &code, (AstBlock *) expr, 1); break;
+        case Ast_Kind_Call:           emit_call(mod, &code, (AstCall *) expr); break;
+        case Ast_Kind_Intrinsic_Call: emit_intrinsic_call(mod, &code, (AstIntrinsicCall *) expr); break;
+        case Ast_Kind_Binary_Op:      emit_binop(mod, &code, (AstBinaryOp *) expr); break;
+        case Ast_Kind_Unary_Op:       emit_unaryop(mod, &code, (AstUnaryOp *) expr); break;
 
         case Ast_Kind_Address_Of: {
             AstAddressOf* aof = (AstAddressOf *) expr;
-            compile_location(mod, &code, aof->expr);
+            emit_location(mod, &code, aof->expr);
             break;
         }
 
         case Ast_Kind_Dereference: {
             AstDereference* deref = (AstDereference *) expr;
-            compile_expression(mod, &code, deref->expr);
-            compile_load_instruction(mod, &code, deref->type, 0);
+            emit_expression(mod, &code, deref->expr);
+            emit_load_instruction(mod, &code, deref->type, 0);
             break;
         }
 
         case Ast_Kind_Array_Access: {
             AstArrayAccess* aa = (AstArrayAccess *) expr;
             u64 offset = 0;
-            compile_array_access_location(mod, &code, aa, &offset);
-            compile_load_instruction(mod, &code, aa->type, offset);
+            emit_array_access_location(mod, &code, aa, &offset);
+            emit_load_instruction(mod, &code, aa->type, offset);
             break;
         }
 
@@ -1587,8 +1584,8 @@ COMPILE_FUNC(expression, AstTyped* expr) {
             }
 
             u64 offset = 0;
-            compile_field_access_location(mod, &code, field, &offset);
-            compile_load_instruction(mod, &code, field->type, offset);
+            emit_field_access_location(mod, &code, field, &offset);
+            emit_load_instruction(mod, &code, field->type, offset);
             break;
         }
 
@@ -1597,15 +1594,15 @@ COMPILE_FUNC(expression, AstTyped* expr) {
 
             u64 tmp_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
 
-            compile_expression(mod, &code, sl->lo);
+            emit_expression(mod, &code, sl->lo);
             WIL(WI_LOCAL_TEE, tmp_local);
             if (sl->elem_size != 1) {
                 WID(WI_I32_CONST, sl->elem_size);
                 WI(WI_I32_MUL);
             }
-            compile_expression(mod, &code, sl->addr);
+            emit_expression(mod, &code, sl->addr);
             WI(WI_I32_ADD);
-            compile_expression(mod, &code, sl->hi);
+            emit_expression(mod, &code, sl->hi);
             WIL(WI_LOCAL_GET, tmp_local);
             WI(WI_I32_SUB);
 
@@ -1635,9 +1632,7 @@ COMPILE_FUNC(expression, AstTyped* expr) {
                 WID(WI_I64_CONST, ev->value->value.l);
             }
             else {
-                onyx_message_add(Msg_Type_Literal,
-                    ev->token->pos,
-                    "invalid backing type for enum");
+                onyx_report_error(ev->token->pos, "Invalid backing type for enum.");
             }
             break;
         }
@@ -1645,7 +1640,7 @@ COMPILE_FUNC(expression, AstTyped* expr) {
         case Ast_Kind_Memres: {
             AstMemRes* memres = (AstMemRes *) expr;
             WID(WI_I32_CONST, memres->addr);
-            compile_load_instruction(mod, &code, memres->type, 0);
+            emit_load_instruction(mod, &code, memres->type, 0);
             break;
         }
 
@@ -1688,45 +1683,37 @@ static const WasmInstructionType cast_map[][11] = {
     /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_UNREACHABLE,     WI_UNREACHABLE,    WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_NOP },
 };
 
-COMPILE_FUNC(cast, AstUnaryOp* cast) {
+EMIT_FUNC(cast, AstUnaryOp* cast) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    compile_expression(mod, &code, cast->expr);
+    emit_expression(mod, &code, cast->expr);
 
     Type* from = cast->expr->type;
     Type* to = cast->type;
 
     if (from->kind == Type_Kind_Struct || to->kind == Type_Kind_Struct) {
-        onyx_message_add(Msg_Type_Literal,
-                cast->token->pos,
-                "cannot cast to or from a struct");
+        onyx_report_error(cast->token->pos, "Cannot cast to or from a struct.");
         WI(WI_DROP);
         *pcode = code;
         return;
     }
 
     if (from->kind == Type_Kind_Slice || to->kind == Type_Kind_Slice) {
-        onyx_message_add(Msg_Type_Literal,
-                cast->token->pos,
-                "cannot cast to or from a slice");
+        onyx_report_error(cast->token->pos, "Cannot cast to or from a slice.");
         WI(WI_DROP);
         *pcode = code;
         return;
     }
 
     if (from->kind == Type_Kind_DynArray || to->kind == Type_Kind_DynArray) {
-        onyx_message_add(Msg_Type_Literal,
-                cast->token->pos,
-                "cannot cast to or from a dynamic array");
+        onyx_report_error(cast->token->pos, "Cannot cast to or from a dynamic array.");
         WI(WI_DROP);
         *pcode = code;
         return;
     }
 
     if (to->kind == Type_Kind_Function) {
-        onyx_message_add(Msg_Type_Literal,
-                cast->token->pos,
-                "cannot cast to a function");
+        onyx_report_error(cast->token->pos, "Cannot cast to a function.");
         WI(WI_DROP);
         *pcode = code;
         return;
@@ -1736,9 +1723,7 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
     if (to->kind == Type_Kind_Enum) to = to->Enum.backing;
 
     if (from->kind == Type_Kind_Basic && from->Basic.kind == Basic_Kind_Void) {
-        onyx_message_add(Msg_Type_Literal,
-                cast->token->pos,
-                "cannot cast from void");
+        onyx_report_error(cast->token->pos, "Cannot cast from void.");
         WI(WI_DROP);
         *pcode = code;
         return;
@@ -1781,9 +1766,7 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
         WasmInstructionType cast_op = cast_map[fromidx][toidx];
         if (cast_op == WI_UNREACHABLE) {
             bh_printf("%d %d\n", fromidx, toidx);
-            onyx_message_add(Msg_Type_Literal,
-                    cast->token->pos,
-                    "bad cast");
+            onyx_report_error(cast->token->pos, "Bad cast.");
         }
         else if (cast_op != WI_NOP) {
             WI(cast_op);
@@ -1793,53 +1776,53 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
     *pcode = code;
 }
 
-COMPILE_FUNC(return, AstReturn* ret) {
+EMIT_FUNC(return, AstReturn* ret) {
     bh_arr(WasmInstruction) code = *pcode;
 
     if (ret->expr) {
         if (mod->curr_cc == CC_Return_Stack) {
             if (type_is_structlike_strict(ret->expr->type)) {
-                compile_expression(mod, &code, ret->expr);
+                emit_expression(mod, &code, ret->expr);
 
                 WIL(WI_LOCAL_GET, mod->stack_base_idx);
                 WID(WI_I32_CONST, type_size_of(ret->expr->type));
                 WI(WI_I32_SUB);
 
-                compile_store_instruction(mod, &code, ret->expr->type, 0);
+                emit_store_instruction(mod, &code, ret->expr->type, 0);
 
             } else {
                 WIL(WI_LOCAL_GET, mod->stack_base_idx);
                 WID(WI_I32_CONST, type_size_of(ret->expr->type));
                 WI(WI_I32_SUB);
 
-                compile_expression(mod, &code, ret->expr);
-                compile_store_instruction(mod, &code, ret->expr->type, 0);
+                emit_expression(mod, &code, ret->expr);
+                emit_store_instruction(mod, &code, ret->expr->type, 0);
             }
 
         } else {
-            compile_expression(mod, &code, ret->expr);
+            emit_expression(mod, &code, ret->expr);
         }
     }
 
-    compile_deferred_stmts(mod, &code, (AstNode *) ret);
+    emit_deferred_stmts(mod, &code, (AstNode *) ret);
 
     if (bh_arr_length(mod->deferred_stmts) != 0) {
         i32 i = bh_arr_length(mod->deferred_stmts) - 1;
         while (i >= 0) {
-            compile_statement(mod, &code, mod->deferred_stmts[i].stmt);
+            emit_statement(mod, &code, mod->deferred_stmts[i].stmt);
             i--;
         }
     }
 
     if (mod->has_stack_locals)
-        compile_stack_leave(mod, &code, 0);
+        emit_stack_leave(mod, &code, 0);
 
     WI(WI_RETURN);
 
     *pcode = code;
 }
 
-COMPILE_FUNC(stack_enter, u64 stacksize) {
+EMIT_FUNC(stack_enter, u64 stacksize) {
     bh_arr(WasmInstruction) code = *pcode;
 
     bh_align(stacksize, 16);
@@ -1856,7 +1839,7 @@ COMPILE_FUNC(stack_enter, u64 stacksize) {
     *pcode = code;
 }
 
-COMPILE_FUNC(stack_leave, u32 unused) {
+EMIT_FUNC(stack_leave, u32 unused) {
     bh_arr(WasmInstruction) code = *pcode;
 
     u64 stack_top_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_top);
@@ -1939,7 +1922,7 @@ static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func) {
     }
 }
 
-static inline b32 should_compile_function(AstFunction* fd) {
+static inline b32 should_EMIT_FUNCtion(AstFunction* fd) {
     // NOTE: Don't output intrinsic functions
     if (fd->flags & Ast_Flag_Intrinsic) return 0;
 
@@ -1959,8 +1942,8 @@ static inline b32 should_compile_function(AstFunction* fd) {
 }
 
 
-static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
-    if (!should_compile_function(fd)) return;
+static void EMIT_FUNCtion(OnyxWasmModule* mod, AstFunction* fd) {
+    if (!should_EMIT_FUNCtion(fd)) return;
 
     i32 type_idx = generate_type_idx(mod, fd->type);
 
@@ -2039,11 +2022,11 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
         }
 
         // Generate code
-        compile_function_body(mod, &wasm_func.code, fd);
+        emit_function_body(mod, &wasm_func.code, fd);
 
         if (mod->has_stack_locals) {
-            compile_stack_enter(mod, &wasm_func.code, mod->local_alloc->max_stack);
-            compile_stack_leave(mod, &wasm_func.code, 0);
+            emit_stack_enter(mod, &wasm_func.code, mod->local_alloc->max_stack);
+            emit_stack_leave(mod, &wasm_func.code, 0);
         }
     }
 
@@ -2055,7 +2038,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
     bh_imap_clear(&mod->local_map);
 }
 
-static void compile_global(OnyxWasmModule* module, AstGlobal* global) {
+static void emit_global(OnyxWasmModule* module, AstGlobal* global) {
     WasmType global_type = onyx_type_to_wasm_type(global->type);
 
     if (global->flags & Ast_Flag_Foreign) {
@@ -2109,7 +2092,7 @@ static void compile_global(OnyxWasmModule* module, AstGlobal* global) {
 
 }
 
-static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) {
+static void emit_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) {
 
     // NOTE: Allocating more than necessary, but there are no cases
     // in a string literal that create more bytes than already
@@ -2174,7 +2157,7 @@ static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) {
     bh_arr_push(mod->data, datum);
 }
 
-static void compile_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) {
+static void emit_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) {
     switch (node->kind) {
     case Ast_Kind_NumLit: {
         switch (node->type->Basic.kind) {
@@ -2207,13 +2190,13 @@ static void compile_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) {
 
         //fallthrough
     }
-    default: onyx_message_add(Msg_Type_Literal,
-            node->token->pos,
-            "invalid data");
+    default: onyx_report_error(node->token->pos,
+            "Cannot generate constant data for '%s'.",
+            onyx_ast_node_kind_string(node->kind));
     }
 }
 
-static void compile_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) {
+static void emit_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) {
     Type* effective_type = memres->type;
 
     u64 alignment = type_alignment_of(effective_type);
@@ -2226,7 +2209,7 @@ static void compile_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) {
 
     if (memres->initial_value != NULL) {
         u8* data = bh_alloc(global_heap_allocator, size);
-        compile_raw_data(mod, data, memres->initial_value);
+        emit_raw_data(mod, data, memres->initial_value);
 
         WasmDatum datum = {
             .offset = offset,
@@ -2241,7 +2224,7 @@ static void compile_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) {
     mod->next_datum_offset = offset + size;
 }
 
-static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {
+static void emit_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {
     token_toggle_end(fc->filename);
 
     if (bh_table_has(u32, mod->loaded_file_offsets, fc->filename->text)) {
@@ -2255,8 +2238,8 @@ static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {
     bh_table_put(u32, mod->loaded_file_offsets, fc->filename->text, offset);
 
     if (!bh_file_exists(fc->filename->text)) {
-        onyx_message_add(Msg_Type_File_Not_Found,
-                fc->filename->pos,
+        onyx_report_error(fc->filename->pos,
+                "Unable to open file for reading, '%s'.",
                 fc->filename->text);
 
         token_toggle_end(fc->filename);
@@ -2369,7 +2352,7 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) {
 
         switch (entity->type) {
             case Entity_Type_Function_Header: {
-                if (!should_compile_function(entity->function)) break;
+                if (!should_EMIT_FUNCtion(entity->function)) break;
 
                 u64 func_idx;
                 if ((entity->function->flags & Ast_Flag_Foreign) != 0)
@@ -2393,22 +2376,22 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) {
             }
 
             case Entity_Type_String_Literal: {
-                compile_string_literal(module, (AstStrLit *) entity->strlit);
+                emit_string_literal(module, (AstStrLit *) entity->strlit);
                 break;
             }
 
             case Entity_Type_File_Contents: {
-                compile_file_contents(module, (AstFileContents *) entity->file_contents);
+                emit_file_contents(module, (AstFileContents *) entity->file_contents);
                 break;
             }
 
             case Entity_Type_Memory_Reservation: {
-                compile_memory_reservation(module, (AstMemRes *) entity->mem_res);
+                emit_memory_reservation(module, (AstMemRes *) entity->mem_res);
                 break;
             }
 
-            case Entity_Type_Function: compile_function(module, entity->function); break;
-            case Entity_Type_Global:   compile_global(module,   entity->global); break;
+            case Entity_Type_Function: EMIT_FUNCtion(module, entity->function); break;
+            case Entity_Type_Global:   emit_global(module,   entity->global); break;
 
             default: break;
         }