From: Brendan Hansen Date: Sun, 30 Aug 2020 12:59:55 +0000 (-0500) Subject: massive renaming of internal compiler things X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=d04874ecf25e96c7b55e8cdcfb42856fcbdacba5;p=onyx.git massive renaming of internal compiler things --- diff --git a/Makefile b/Makefile index 21ec2025..597d5dd3 100644 --- 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 \ diff --git a/docs/plan b/docs/plan index 898280e8..d135c900 100644 --- 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 diff --git a/include/bh.h b/include/bh.h index e5f0be86..37d7b785 100644 --- a/include/bh.h +++ b/include/bh.h @@ -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 index 00000000..dcc2fbfa --- /dev/null +++ b/include/onyxerrors.h @@ -0,0 +1,34 @@ +#ifndef ONYXERRORS_H +#define ONYXERRORS_H + +#include "bh.h" +#include "onyxlex.h" + +#include + +#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 index 81c41865..00000000 --- a/include/onyxmsgs.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef ONYXMSGS_H -#define ONYXMSGS_H - -#include "bh.h" -#include "onyxlex.h" - -#include - -#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 diff --git a/include/onyxparser.h b/include/onyxparser.h index f4e69dc5..0da8dc2a 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -4,7 +4,7 @@ #include "bh.h" #include "onyxlex.h" -#include "onyxmsgs.h" +#include "onyxerrors.h" #include "onyxastnodes.h" typedef struct NodeToProcess { diff --git a/include/onyxsempass.h b/include/onyxsempass.h index 5a61171a..145795c5 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -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 diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 11a6c4a6..8c803d7d 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -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 ceacaca6..fb29383a 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index 45ccbbf4..58b542c7 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -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? "); diff --git a/src/onyx.c b/src/onyx.c index 32880828..75527496 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -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: diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 67f1a2c5..d1cd9261 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index c3d1b54f..1c491448 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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 index 00000000..5e9879d0 --- /dev/null +++ b/src/onyxerrors.c @@ -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 index b436e9a9..00000000 --- a/src/onyxmsgs.c +++ /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; -} diff --git a/src/onyxparser.c b/src/onyxparser.c index 177b4ad6..223ccbd0 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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; } } diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 7324468e..73e33595 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -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; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 7e4f10d5..a91641ad 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -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; } diff --git a/src/onyxutils.c b/src/onyxutils.c index 00c7bae4..481aed41 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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: diff --git a/src/onyxwasm.c b/src/onyxwasm.c index f79e6ca1..e0ddb40e 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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: // @@ -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; }