From 36b9586b3a370ee1e909f3f600d7cfd875b806e7 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 8 Sep 2021 08:16:46 -0500 Subject: [PATCH] renamed the compiler source files. --- bin/onyx | Bin 431048 -> 430992 bytes build.bat | 4 +- build.sh | 2 +- docs/bugs | 4 + include/{onyxastnodes.h => astnodes.h} | 4 +- include/{onyxdoc.h => doc.h} | 2 +- include/{onyxerrors.h => errors.h} | 2 +- include/{onyxlex.h => lex.h} | 0 include/{onyxparser.h => parser.h} | 6 +- include/{onyxtypes.h => types.h} | 0 include/{onyxutils.h => utils.h} | 2 +- include/{onyxwasm.h => wasm.h} | 4 +- src/{onyxastnodes.c => astnodes.c} | 6 +- src/{onyxbuiltins.c => builtins.c} | 8 +- src/{onyxchecker.c => checker.c} | 4 +- src/{onyxclone.c => clone.c} | 6 +- src/{onyxdoc.c => doc.c} | 6 +- src/{onyxentities.c => entities.c} | 4 +- src/{onyxerrors.c => errors.c} | 4 +- src/{onyxlex.c => lex.c} | 6 +- src/onyx.c | 12 +- src/{onyxparser.c => parser.c} | 11 +- src/{onyxutils.c => polymorph.c} | 893 +----------------- src/{onyxsymres.c => symres.c} | 8 +- src/{onyxtypes.c => types.c} | 8 +- src/utils.c | 871 +++++++++++++++++ src/{onyxwasm.c => wasm.c} | 10 +- ...nyxwasm_intrinsics.c => wasm_intrinsics.c} | 0 src/{onyxwasm_output.c => wasm_output.c} | 0 ...nyxwasm_type_table.c => wasm_type_table.c} | 0 30 files changed, 951 insertions(+), 936 deletions(-) rename include/{onyxastnodes.h => astnodes.h} (99%) rename include/{onyxdoc.h => doc.h} (96%) rename include/{onyxerrors.h => errors.h} (97%) rename include/{onyxlex.h => lex.h} (100%) rename include/{onyxparser.h => parser.h} (93%) rename include/{onyxtypes.h => types.h} (100%) rename include/{onyxutils.h => utils.h} (98%) rename include/{onyxwasm.h => wasm.h} (99%) rename src/{onyxastnodes.c => astnodes.c} (99%) rename src/{onyxbuiltins.c => builtins.c} (99%) rename src/{onyxchecker.c => checker.c} (99%) rename src/{onyxclone.c => clone.c} (99%) rename src/{onyxdoc.c => doc.c} (99%) rename src/{onyxentities.c => entities.c} (99%) rename src/{onyxerrors.c => errors.c} (98%) rename src/{onyxlex.c => lex.c} (99%) rename src/{onyxparser.c => parser.c} (99%) rename src/{onyxutils.c => polymorph.c} (53%) rename src/{onyxsymres.c => symres.c} (99%) rename src/{onyxtypes.c => types.c} (99%) create mode 100644 src/utils.c rename src/{onyxwasm.c => wasm.c} (99%) rename src/{onyxwasm_intrinsics.c => wasm_intrinsics.c} (100%) rename src/{onyxwasm_output.c => wasm_output.c} (100%) rename src/{onyxwasm_type_table.c => wasm_type_table.c} (100%) diff --git a/bin/onyx b/bin/onyx index 8a4f175d476239d8bd10574cb4c3c6bb654a2f53..4a8dd7340b3b9d9847955ea73d45fc462557900a 100755 GIT binary patch delta 47905 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 MoNo`+*Lp+$7h&yjz5oCK delta 48114 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 NUL 2> NUL cl.exe %FLAGS% /I include /std:c17 /Tc %SOURCE_FILES% /link /DEBUG /OUT:onyx.exe /incremental:no /opt:ref /subsystem:console -del *.obj > NUL 2> NUL \ No newline at end of file +del *.obj > NUL 2> NUL diff --git a/build.sh b/build.sh index 1558a98c..41bde8ac 100755 --- a/build.sh +++ b/build.sh @@ -7,7 +7,7 @@ sudo cp -r ./core/ "$CORE_DIR" [ "$1" = "libs_only" ] && exit 0 -C_FILES="onyx onyxastnodes onyxbuiltins onyxchecker onyxclone onyxdoc onyxentities onyxerrors onyxlex onyxparser onyxsymres onyxtypes onyxutils onyxwasm" +C_FILES="onyx astnodes builtins checker clone doc entities errors lex parser symres types utils wasm" CC='gcc' WARNINGS='-Wimplicit -Wmisleading-indentation -Wparentheses -Wsequence-point -Wreturn-type -Wshift-negative-value -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-function -Wunused-label -Wmaybe-uninitialized -Wsign-compare -Wstrict-overflow -Wduplicated-branches -Wduplicated-cond -Wtrigraphs -Waddress -Wlogical-op' diff --git a/docs/bugs b/docs/bugs index 209cc77a..0cca7527 100644 --- a/docs/bugs +++ b/docs/bugs @@ -8,6 +8,10 @@ List of known bugs: println(x); // Doesn't work } +[ ] Memory reservation type checking doesn't work how I think it should. This errors for example: + + x: i64 = 1; + [X] Initialization statements on control statements should be better. For example, this should be possible: diff --git a/include/onyxastnodes.h b/include/astnodes.h similarity index 99% rename from include/onyxastnodes.h rename to include/astnodes.h index a4f5f556..e15aef54 100644 --- a/include/onyxastnodes.h +++ b/include/astnodes.h @@ -1,8 +1,8 @@ #ifndef ONYXASTNODES_H #define ONYXASTNODES_H -#include "onyxlex.h" -#include "onyxtypes.h" +#include "lex.h" +#include "types.h" #define AST_NODES \ NODE(Node) \ diff --git a/include/onyxdoc.h b/include/doc.h similarity index 96% rename from include/onyxdoc.h rename to include/doc.h index 0e6e505c..75d4bfc5 100644 --- a/include/onyxdoc.h +++ b/include/doc.h @@ -2,7 +2,7 @@ #define ONYXDOC_H #include "bh.h" -#include "onyxastnodes.h" +#include "astnodes.h" typedef enum DocFormat { Doc_Format_Human, diff --git a/include/onyxerrors.h b/include/errors.h similarity index 97% rename from include/onyxerrors.h rename to include/errors.h index 993f4f70..41aebdde 100644 --- a/include/onyxerrors.h +++ b/include/errors.h @@ -2,7 +2,7 @@ #define ONYXERRORS_H #include "bh.h" -#include "onyxlex.h" +#include "lex.h" #include diff --git a/include/onyxlex.h b/include/lex.h similarity index 100% rename from include/onyxlex.h rename to include/lex.h diff --git a/include/onyxparser.h b/include/parser.h similarity index 93% rename from include/onyxparser.h rename to include/parser.h index 712ac282..bfad9417 100644 --- a/include/onyxparser.h +++ b/include/parser.h @@ -3,9 +3,9 @@ #include "bh.h" -#include "onyxlex.h" -#include "onyxerrors.h" -#include "onyxastnodes.h" +#include "lex.h" +#include "errors.h" +#include "astnodes.h" typedef struct PolymorphicContext { AstType* root_node; diff --git a/include/onyxtypes.h b/include/types.h similarity index 100% rename from include/onyxtypes.h rename to include/types.h diff --git a/include/onyxutils.h b/include/utils.h similarity index 98% rename from include/onyxutils.h rename to include/utils.h index 96957887..48c58f5f 100644 --- a/include/onyxutils.h +++ b/include/utils.h @@ -1,6 +1,6 @@ #include "bh.h" -#include "onyxastnodes.h" +#include "astnodes.h" extern bh_scratch global_scratch; extern bh_allocator global_scratch_allocator; diff --git a/include/onyxwasm.h b/include/wasm.h similarity index 99% rename from include/onyxwasm.h rename to include/wasm.h index b423403d..7d0ddc30 100644 --- a/include/onyxwasm.h +++ b/include/wasm.h @@ -3,8 +3,8 @@ #include "bh.h" -#include "onyxastnodes.h" -#include "onyxerrors.h" +#include "astnodes.h" +#include "errors.h" typedef u8 WasmType; diff --git a/src/onyxastnodes.c b/src/astnodes.c similarity index 99% rename from src/onyxastnodes.c rename to src/astnodes.c index 666a2038..7cdbc445 100644 --- a/src/onyxastnodes.c +++ b/src/astnodes.c @@ -1,6 +1,6 @@ -#include "onyxastnodes.h" -#include "onyxparser.h" -#include "onyxutils.h" +#include "astnodes.h" +#include "parser.h" +#include "utils.h" static const char* ast_node_names[] = { "ERROR", diff --git a/src/onyxbuiltins.c b/src/builtins.c similarity index 99% rename from src/onyxbuiltins.c rename to src/builtins.c index 8731a619..7be8a782 100644 --- a/src/onyxbuiltins.c +++ b/src/builtins.c @@ -1,7 +1,7 @@ -#include "onyxastnodes.h" -#include "onyxtypes.h" -#include "onyxerrors.h" -#include "onyxutils.h" +#include "astnodes.h" +#include "types.h" +#include "errors.h" +#include "utils.h" AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, NULL, 0, NULL, NULL, &basic_types[Basic_Kind_Void] }; AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, NULL, 0, NULL, NULL, &basic_types[Basic_Kind_Bool] }; diff --git a/src/onyxchecker.c b/src/checker.c similarity index 99% rename from src/onyxchecker.c rename to src/checker.c index e2edab7a..0e595ae1 100644 --- a/src/onyxchecker.c +++ b/src/checker.c @@ -1,6 +1,6 @@ #define BH_DEBUG -#include "onyxparser.h" -#include "onyxutils.h" +#include "parser.h" +#include "utils.h" // All of the `check` functions return a boolean that signals if an issue // was reached while processing the node. These error booleans propagate diff --git a/src/onyxclone.c b/src/clone.c similarity index 99% rename from src/onyxclone.c rename to src/clone.c index 8940a035..ac4a8932 100644 --- a/src/onyxclone.c +++ b/src/clone.c @@ -1,6 +1,6 @@ -#include "onyxastnodes.h" -#include "onyxparser.h" -#include "onyxutils.h" +#include "astnodes.h" +#include "parser.h" +#include "utils.h" static inline b32 should_clone(AstNode* node) { if (node->flags & Ast_Flag_No_Clone) return 0; diff --git a/src/onyxdoc.c b/src/doc.c similarity index 99% rename from src/onyxdoc.c rename to src/doc.c index ab1bc9dc..b6e06c32 100644 --- a/src/onyxdoc.c +++ b/src/doc.c @@ -1,6 +1,6 @@ -#include "onyxdoc.h" -#include "onyxutils.h" -#include "onyxtypes.h" +#include "doc.h" +#include "utils.h" +#include "types.h" static i32 cmp_doc_entry(const void * a, const void * b) { DocEntry* d1 = (DocEntry *) a; diff --git a/src/onyxentities.c b/src/entities.c similarity index 99% rename from src/onyxentities.c rename to src/entities.c index 7a938621..ed209a28 100644 --- a/src/onyxentities.c +++ b/src/entities.c @@ -1,6 +1,6 @@ #include "bh.h" -#include "onyxastnodes.h" -#include "onyxutils.h" +#include "astnodes.h" +#include "utils.h" static inline i32 entity_phase(Entity* e1) { if (e1->state <= Entity_State_Parse) return 1; diff --git a/src/onyxerrors.c b/src/errors.c similarity index 98% rename from src/onyxerrors.c rename to src/errors.c index d6ad29cd..0a074521 100644 --- a/src/onyxerrors.c +++ b/src/errors.c @@ -1,5 +1,5 @@ -#include "onyxerrors.h" -#include "onyxutils.h" +#include "errors.h" +#include "utils.h" OnyxErrors errors; diff --git a/src/onyxlex.c b/src/lex.c similarity index 99% rename from src/onyxlex.c rename to src/lex.c index eefcdd16..a1f1ac3f 100644 --- a/src/onyxlex.c +++ b/src/lex.c @@ -1,7 +1,7 @@ #include "bh.h" -#include "onyxlex.h" -#include "onyxutils.h" -#include "onyxerrors.h" +#include "lex.h" +#include "utils.h" +#include "errors.h" u64 lexer_lines_processed = 0; u64 lexer_tokens_processed = 0; diff --git a/src/onyx.c b/src/onyx.c index 0352896c..6f1557d2 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -2,12 +2,12 @@ #define BH_DEFINE #include "bh.h" -#include "onyxlex.h" -#include "onyxerrors.h" -#include "onyxparser.h" -#include "onyxutils.h" -#include "onyxwasm.h" -#include "onyxdoc.h" +#include "lex.h" +#include "errors.h" +#include "parser.h" +#include "utils.h" +#include "wasm.h" +#include "doc.h" #define VERSION "v0.1.0-beta" diff --git a/src/onyxparser.c b/src/parser.c similarity index 99% rename from src/onyxparser.c rename to src/parser.c index 1c60685f..ced1fdc2 100644 --- a/src/onyxparser.c +++ b/src/parser.c @@ -3,13 +3,10 @@ // such as procedure definitions, string literals, struct definitions // and declarations to be introduced into scopes. -// Things that need to be cleaned up in the parser: -// - control block local variables should be more extensible and reuse more code - -#include "onyxlex.h" -#include "onyxerrors.h" -#include "onyxparser.h" -#include "onyxutils.h" +#include "lex.h" +#include "errors.h" +#include "parser.h" +#include "utils.h" #define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind) // :LinearTokenDependent diff --git a/src/onyxutils.c b/src/polymorph.c similarity index 53% rename from src/onyxutils.c rename to src/polymorph.c index e53256ce..c05734bb 100644 --- a/src/onyxutils.c +++ b/src/polymorph.c @@ -1,254 +1,17 @@ -#define BH_DEBUG - -#include "onyxutils.h" -#include "onyxlex.h" -#include "onyxastnodes.h" -#include "onyxerrors.h" -#include "onyxparser.h" -#include "onyxastnodes.h" - -bh_scratch global_scratch; -bh_allocator global_scratch_allocator; - -bh_managed_heap global_heap; -bh_allocator global_heap_allocator; - -// -// Program info and packages -// -Package* package_lookup(char* package_name) { - if (bh_table_has(Package *, context.packages, package_name)) { - return bh_table_get(Package *, context.packages, package_name); - } else { - return NULL; - } -} - -Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_allocator alloc) { - if (bh_table_has(Package *, context.packages, package_name)) { - return bh_table_get(Package *, context.packages, package_name); - - } else { - Package* package = bh_alloc_item(alloc, Package); - - char* pac_name = bh_alloc_array(alloc, char, strlen(package_name) + 1); - memcpy(pac_name, package_name, strlen(package_name) + 1); - pac_name[strlen(package_name)] = '\0'; - - package->name = pac_name; - package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 }); - package->private_scope = scope_create(alloc, package->scope, (OnyxFilePos) { 0 }); - package->use_package_entities = NULL; - - bh_table_put(Package *, context.packages, pac_name, package); - - return package; - } -} - -void package_track_use_package(Package* package, Entity* entity) { - if (package->use_package_entities == NULL) { - bh_arr_new(global_heap_allocator, package->use_package_entities, 4); - } - - bh_arr_push(package->use_package_entities, entity); -} - -void package_reinsert_use_packages(Package* package) { - if (!package->use_package_entities) return; - - bh_arr_each(Entity *, use_package, package->use_package_entities) { - (*use_package)->state = Entity_State_Resolve_Symbols; - (*use_package)->macro_attempts = 0; - entity_heap_insert_existing(&context.entities, *use_package); - } - - bh_arr_set_length(package->use_package_entities, 0); -} - - -// -// Scoping -// -static u64 next_scope_id = 1; - -Scope* scope_create(bh_allocator a, Scope* parent, OnyxFilePos created_at) { - Scope* scope = bh_alloc_item(a, Scope); - scope->id = next_scope_id++; - scope->parent = parent; - scope->created_at = created_at; - - scope->symbols = NULL; - bh_table_init(global_heap_allocator, scope->symbols, 64); - - return scope; -} - -void scope_include(Scope* target, Scope* source, OnyxFilePos pos) { - bh_table_each_start(AstNode *, source->symbols); - symbol_raw_introduce(target, (char *) key, pos, value); - bh_table_each_end; -} - -b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol) { - token_toggle_end(tkn); - - b32 ret = symbol_raw_introduce(scope, tkn->text, tkn->pos, symbol); - - token_toggle_end(tkn); - return ret; -} - -b32 symbol_raw_introduce(Scope* scope, char* name, OnyxFilePos pos, AstNode* symbol) { - if (strcmp(name, "_")) { - if (bh_table_has(AstNode *, scope->symbols, name)) { - if (bh_table_get(AstNode *, scope->symbols, name) != symbol) { - onyx_report_error(pos, "Redeclaration of symbol '%s'.", name); - return 0; - } - return 1; - } - } - - bh_table_put(AstNode *, scope->symbols, name, symbol); - return 1; -} - -void symbol_builtin_introduce(Scope* scope, char* sym, AstNode *node) { - bh_table_put(AstNode *, scope->symbols, sym, node); -} - -void symbol_subpackage_introduce(Scope* scope, char* sym, AstPackage* package) { - if (bh_table_has(AstNode *, scope->symbols, sym)) { - AstNode* maybe_package = bh_table_get(AstNode *, scope->symbols, sym); - - // CLEANUP: Make this assertion an actual error message. - assert(maybe_package->kind == Ast_Kind_Package); - } else { - bh_table_put(AstNode *, scope->symbols, sym, (AstNode *) package); - } -} - -AstNode* symbol_raw_resolve(Scope* start_scope, char* sym) { - AstNode* res = NULL; - Scope* scope = start_scope; - - while (res == NULL && scope != NULL) { - if (bh_table_has(AstNode *, scope->symbols, sym)) { - res = bh_table_get(AstNode *, scope->symbols, sym); - } else { - scope = scope->parent; - } - } - - return res; -} - -AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) { - token_toggle_end(tkn); - AstNode* res = symbol_raw_resolve(start_scope, tkn->text); - token_toggle_end(tkn); - - return res; -} - -AstNode* try_symbol_raw_resolve_from_node(AstNode* node, char* symbol) { - b32 used_pointer = 0; - - while (1) { - if (!node) return NULL; - - switch (node->kind) { - case Ast_Kind_Type_Raw_Alias: node = (AstNode *) ((AstTypeRawAlias *) node)->to->ast_type; break; - case Ast_Kind_Type_Alias: node = (AstNode *) ((AstTypeAlias *) node)->to; break; - case Ast_Kind_Alias: node = (AstNode *) ((AstAlias *) node)->alias; break; - case Ast_Kind_Pointer_Type: { - if (used_pointer) goto all_types_peeled_off; - used_pointer = 1; - - node = (AstNode *) ((AstPointerType *) node)->elem; - break; - } - - default: goto all_types_peeled_off; - } - } - -all_types_peeled_off: - if (!node) return NULL; - - switch (node->kind) { - case Ast_Kind_Package: { - AstPackage* package = (AstPackage *) node; - - // CLEANUP - if (package->package == NULL) { - package->package = package_lookup(package->package_name); - } - - if (package->package == NULL) { - return NULL; - } - - return symbol_raw_resolve(package->package->scope, symbol); - } - - case Ast_Kind_Enum_Type: { - AstEnumType* etype = (AstEnumType *) node; - return symbol_raw_resolve(etype->scope, symbol); - } - - case Ast_Kind_Struct_Type: { - AstStructType* stype = (AstStructType *) node; - AstNode* result = symbol_raw_resolve(stype->scope, symbol); - - if (result == NULL && stype->stcache != NULL) { - Type* struct_type = stype->stcache; - assert(struct_type->kind == Type_Kind_Struct); - - bh_arr_each(AstPolySolution, sln, struct_type->Struct.poly_sln) { - if (token_text_equals(sln->poly_sym->token, symbol)) { - if (sln->kind == PSK_Type) { - result = (AstNode *) sln->type->ast_type; - } else { - result = (AstNode *) sln->value; - } - } - } - } - - return result; - } - - case Ast_Kind_Poly_Struct_Type: { - AstStructType* stype = ((AstPolyStructType *) node)->base_struct; - return symbol_raw_resolve(stype->scope, symbol); - } - } - - return NULL; -} - -AstNode* try_symbol_resolve_from_node(AstNode* node, OnyxToken* token) { - token_toggle_end(token); - AstNode* result = try_symbol_raw_resolve_from_node(node, token->text); - token_toggle_end(token); - - return result; -} - -void scope_clear(Scope* scope) { - bh_table_clear(scope->symbols); -} - // // Polymorphic Procedures // -// HACK HACK HACK nocheckin +// This flag is used by some of the procedures that try working with polymorphic things, +// but need to wait until more information is known. Instead of passing a out parameter +// into each of these procedures, a single global variable is used instead. If the type +// checker ever gets multi-threaded, this would have to become a threadlocal variable. static b32 flag_to_yield = 0; +// The name is pretty self-descriptive, but this is a node that is returned from things +// like polymorphic_proc_lookup when it is determined that everything works so far, but +// the caller must yield in order to finish checking this polymorphic procedure. AstTyped node_that_signals_a_yield = { Ast_Kind_Function, 0 }; static void ensure_polyproc_cache_is_created(AstPolyProc* pp) { @@ -281,14 +44,13 @@ static void insert_poly_slns_into_scope(Scope* scope, bh_arr(AstPolySolution) sl // NOTE: This might return a volatile string. Do not store it without copying it. static char* build_poly_solution_key(AstPolySolution* sln) { - static char buffer[128]; - if (sln->kind == PSK_Type) { return (char *) type_get_unique_name(sln->type); - } - else if (sln->kind == PSK_Value) { - fori (i, 0, 128) buffer[i] = 0; + } else if (sln->kind == PSK_Value) { + static char buffer[256]; + + fori (i, 0, 256) buffer[i] = 0; if (sln->value->kind == Ast_Kind_NumLit) { strncat(buffer, "NUMLIT:", 127); @@ -965,6 +727,13 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM .scope = solidified_func.poly_scope, }; + // HACK: Everything with entity_bring_to_state is a big hack... + // The idea is that instead of making the caller yield for a simple procedure header, + // do a single pass of trying to solve for the parameter types and return types. + // The big missing piece of the entity pumping system is that once an entity is + // entered into the system, it cannot be removed and it is assumed it is going to + // be used in the final binary. This is obviously not always the case, but that + // is how the system currently works. b32 successful = entity_bring_to_state(&func_header_entity, Entity_State_Code_Gen); if (onyx_has_errors()) { onyx_errors_print(); @@ -980,350 +749,6 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM return solidified_func.func; } -// -// Overloaded Procedures -// - -// -// @Cleanup: Everything having to do with overload resolving! -// Things that need to be available: -// * A copy of the arguments list that can be mutated -// - The named_values do not need to be copied, because they are not modified when fill_in_arguments happens. -// - Only values needs to have a copy available -// - This copy needs to be reset after checking every option -// -// Steps needed to check if an overload option is "the one": -// 1. Figure out what the overload is -// a. If polymorphic, generate the header for the procedure only -// 2. Place the arguments in the copy, according to the overload option -// 3. Ensure the option has a type filled out -// 4. For each argument -// a. Ensure it has a place to go (not too many arguments) -// b. Ensure it has a type -// c. Ensure the types match (currently there could be a problem if an option is attempted and doesn't work all the way that polymorphic procedures as arguments could still be solidified) -// -// Additional features that this needs to account for: -// * Resolving an overload from a list of parameter types -// * Resolving an overload from a TypeFunction (so an overloaded procedure can be passed as a parameter) -// - -void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload) { - bh_arr(OverloadOption) overloads = *poverloads; - - i32 index = -1; - fori (i, 0, bh_arr_length(overloads)) { - if (overloads[i].precedence > precedence) { - index = i; - break; - } - } - - if (index < 0) { - bh_arr_push(overloads, ((OverloadOption) { - .precedence = precedence, - .option = overload, - })); - - } else { - bh_arr_insertn(overloads, index, 1); - overloads[index].precedence = precedence; - overloads[index].option = overload; - } - - *poverloads = overloads; -} - -// NOTE: The job of this function is to take a set of overloads, and traverse it to add all possible -// overloads that are reachable. This is slightly more difficult than it may seem. In this language, -// overloaded procedures have a strict ordering to their overloads, which determines how the correct -// match will be found. This was not very complicated until overloaded procedures could be used as -// overload options. This means that you could create an "infinite loop" of overloads like so: -// -// o1 :: { o2 :: { -// (...) { ... }, (...) { ... }, -// o2 o1 -// } } -// -// Obviously, this is not really an infinite loop. It just means that all options are available if -// o1 or o2 are called. The difference between o1 and o2 is the order that the overloads will be -// searched. To build the the list of overloads, a hashmap is used to prevent the problem from being -// O(n^2), even though n would (probably) be small. bh_imap has the useful property that it maintains -// an "entries" array that, so long as nothing is ever removed from it, will maintain the order in -// which entries were put into the map. This is useful because a simple recursive algorithm can -// collect all the overloads into the map, and also use the map to provide a base case. -void build_all_overload_options(bh_arr(OverloadOption) overloads, bh_imap* all_overloads) { - bh_arr_each(OverloadOption, overload, overloads) { - if (bh_imap_has(all_overloads, (u64) overload->option)) continue; - - bh_imap_put(all_overloads, (u64) overload->option, 1); - - if (overload->option->kind == Ast_Kind_Overloaded_Function) { - AstOverloadedFunction* sub_overload = (AstOverloadedFunction *) overload->option; - build_all_overload_options(sub_overload->overloads, all_overloads); - } - } -} - -AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args, b32* should_yield) { - Arguments args; - arguments_clone(&args, param_args); - arguments_ensure_length(&args, bh_arr_length(args.values) + bh_arr_length(args.named_values)); - - // CLEANUP SPEED: This currently rebuilds the complete set of overloads every time one is looked up. - // This should be cached in the AstOverloadedFunction or somewhere like that. - bh_imap all_overloads; - bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2); - build_all_overload_options(overloads, &all_overloads); - - AstTyped *matched_overload = NULL; - - bh_arr_each(bh__imap_entry, entry, all_overloads.entries) { - AstTyped* node = (AstTyped *) entry->key; - arguments_copy(&args, param_args); - - AstFunction* overload = NULL; - switch (node->kind) { - case Ast_Kind_Function: overload = (AstFunction *) node; break; - case Ast_Kind_Macro: overload = macro_resolve_header((AstMacro *) node, param_args, NULL); break; - case Ast_Kind_Polymorphic_Proc: overload = polymorphic_proc_build_only_header((AstPolyProc *) node, PPLM_By_Arguments, param_args); break; - } - - // NOTE: Overload is not something that is known to be overloadable. - if (overload == NULL) continue; - if (overload->kind != Ast_Kind_Function) continue; - if (overload->type == NULL) { - // If it was not possible to create the type for this procedure, tell the - // caller that this should yield and try again later. - if (should_yield) *should_yield = 1; - - // return and not continue because if the overload that didn't have a type will - // work in the future, then it has to take precedence over the other options available. - return NULL; - } - assert(overload->type->kind == Type_Kind_Function); - - // NOTE: If the arguments cannot be placed successfully in the parameters list - if (!fill_in_arguments(&args, (AstNode *) overload, NULL)) continue; - - TypeFunction* ol_type = &overload->type->Function; - if (bh_arr_length(args.values) < (i32) ol_type->needed_param_count) continue; - - b32 all_arguments_work = 1; - fori (i, 0, bh_arr_length(args.values)) { - if (i >= ol_type->param_count) { - all_arguments_work = 0; - break; - } - - Type* type_to_match = ol_type->params[i]; - AstTyped** value = &args.values[i]; - - if (type_to_match->kind == Type_Kind_VarArgs) type_to_match = type_to_match->VarArgs.ptr_to_data->Pointer.elem; - if ((*value)->kind == Ast_Kind_Argument) { - // :ArgumentResolvingIsComplicated - if (((AstArgument *) (*value))->is_baked) continue; - value = &((AstArgument *) *value)->value; - } - - if (!type_check_or_auto_cast(value, type_to_match)) { - all_arguments_work = 0; - break; - } - } - - if (all_arguments_work) { - matched_overload = node; - break; - } - } - - bh_imap_free(&all_overloads); - bh_arr_free(args.values); - return matched_overload; -} - -AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type* type) { - if (type->kind != Type_Kind_Function) return NULL; - - bh_imap all_overloads; - bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2); - build_all_overload_options(overloads, &all_overloads); - - AstTyped *matched_overload = NULL; - - bh_arr_each(bh__imap_entry, entry, all_overloads.entries) { - AstTyped* node = (AstTyped *) entry->key; - if (node->kind == Ast_Kind_Overloaded_Function) continue; - - if (type_check_or_auto_cast(&node, type)) { - matched_overload = node; - break; - } - } - - bh_imap_free(&all_overloads); - return matched_overload; -} - -void report_unable_to_match_overload(AstCall* call) { - char* arg_str = bh_alloc(global_scratch_allocator, 1024); - arg_str[0] = '\0'; - - bh_arr_each(AstTyped *, arg, call->args.values) { - strncat(arg_str, node_get_type_name(*arg), 1023); - - if (arg != &bh_arr_last(call->args.values)) - strncat(arg_str, ", ", 1023); - } - - if (bh_arr_length(call->args.named_values) > 0) { - if (bh_arr_length(call->args.values) > 0) { - strncat(arg_str, ", ", 1023); - } - - bh_arr_each(AstNamedValue *, named_value, call->args.named_values) { - token_toggle_end((*named_value)->token); - strncat(arg_str, (*named_value)->token->text, 1023); - token_toggle_end((*named_value)->token); - - strncat(arg_str, "=", 1023); - strncat(arg_str, node_get_type_name((*named_value)->value), 1023); // CHECK: this might say 'unknown'. - - if (named_value != &bh_arr_last(call->args.named_values)) - strncat(arg_str, ", ", 1023); - } - } - - onyx_report_error(call->token->pos, "Unable to match overloaded function with provided argument types: (%s)", arg_str); - - bh_free(global_scratch_allocator, arg_str); -} - - -// -// Macros -// -// -// TODO: Write this documentation -void expand_macro(AstCall** pcall, AstFunction* template) { - AstCall* call = *pcall; - AstMacro* macro = (AstMacro *) call->callee; - assert(macro->kind == Ast_Kind_Macro); - - assert(template->kind == Ast_Kind_Function); - assert(template->type != NULL); - assert(template->type->kind == Type_Kind_Function); - - AstBlock* expansion = (AstBlock *) ast_clone(context.ast_alloc, template->body); - expansion->rules = Block_Rule_Macro; - expansion->scope = NULL; - expansion->next = call->next; - - AstNode* subst = (AstNode *) expansion; - - if (template->type->Function.return_type != &basic_types[Basic_Kind_Void]) { - AstDoBlock* doblock = (AstDoBlock *) onyx_ast_node_new(context.ast_alloc, sizeof(AstDoBlock), Ast_Kind_Do_Block); - doblock->token = expansion->token; - doblock->block = expansion; - doblock->type = template->type->Function.return_type; - doblock->next = expansion->next; - expansion->next = NULL; - - subst = (AstNode *) doblock; - } - - Scope* argument_scope = scope_create(context.ast_alloc, NULL, call->token->pos); - if (expansion->binding_scope != NULL) - scope_include(argument_scope, expansion->binding_scope, call->token->pos); - expansion->binding_scope = argument_scope; - - // HACK HACK HACK This is probably very wrong. I don't know what guarentees that - // the paramters and arguments are going to be in the same order exactly. - fori (i, 0, bh_arr_length(call->args.values)) { - symbol_introduce(argument_scope, - template->params[i].local->token, - (AstNode *) ((AstArgument *) call->args.values[i])->value); - } - - if (template->flags & Ast_Flag_From_Polymorphism) { - // SLOW DUMB HACKY WAY TO DO THIS!!!!! FIX IT!!!!! - - AstPolyProc* pp = (AstPolyProc *) macro->body; - bh_table_each_start(AstSolidifiedFunction, pp->concrete_funcs); - - if (value.func == template) { - scope_include(argument_scope, value.poly_scope, call->token->pos); - break; - } - - bh_table_each_end; - } - - *(AstNode **) pcall = subst; - return; -} - -AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite) { - switch (macro->body->kind) { - case Ast_Kind_Function: return (AstFunction *) macro->body; - - case Ast_Kind_Polymorphic_Proc: { - AstPolyProc* pp = (AstPolyProc *) macro->body; - ensure_polyproc_cache_is_created(pp); - - char* err_msg=NULL; - bh_arr(AstPolySolution) slns = find_polymorphic_slns(pp, PPLM_By_Arguments, args, &err_msg); - - if (slns == NULL) { - if (flag_to_yield) { - flag_to_yield = 0; - return (AstFunction *) &node_that_signals_a_yield; - } - - if (callsite) onyx_report_error(callsite->pos, err_msg); - - return NULL; - } - - // CLEANUP Copy'n'pasted from polymorphic_proc_build_only_header - AstSolidifiedFunction solidified_func; - - char* unique_key = build_poly_slns_unique_key(slns); - if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) { - solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key); - - } else { - // NOTE: This function is only going to have the header of it correctly created. - // Nothing should happen to this function's body or else the original will be corrupted. - // - brendanfh 2021/01/10 - solidified_func = generate_solidified_function(pp, slns, callsite, 1); - } - - if (solidified_func.header_complete) return solidified_func.func; - - Entity func_header_entity = { - .state = Entity_State_Resolve_Symbols, - .type = Entity_Type_Function_Header, - .function = solidified_func.func, - .package = NULL, - .scope = solidified_func.poly_scope, - }; - - b32 successful = entity_bring_to_state(&func_header_entity, Entity_State_Code_Gen); - if (onyx_has_errors()) return NULL; - - solidified_func.header_complete = successful; - - bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func); - if (!successful) return (AstFunction *) &node_that_signals_a_yield; - - return solidified_func.func; - } - - default: assert(("Bad macro body type.", 0)); - } -} - // // Polymorphic Structures // @@ -1469,285 +894,3 @@ AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstP add_entities_for_node(NULL, (AstNode *) concrete_struct, sln_scope, NULL); return NULL; } - -b32 entity_bring_to_state(Entity* ent, EntityState state) { - EntityState last_state = ent->state; - - while (ent->state != state) { - switch (ent->state) { - case Entity_State_Resolve_Symbols: symres_entity(ent); break; - case Entity_State_Check_Types: check_entity(ent); break; - case Entity_State_Code_Gen: emit_entity(ent); break; - - default: return 0; - } - - if (ent->state == last_state) return 0; - last_state = ent->state; - - if (onyx_has_errors()) return 0; - } - - return 1; -} - - -// -// Arguments resolving -// -static i32 lookup_idx_by_name(AstNode* provider, char* name) { - switch (provider->kind) { - case Ast_Kind_Struct_Literal: { - AstStructLiteral* sl = (AstStructLiteral *) provider; - assert(sl->type); - - StructMember s; - if (!type_lookup_member(sl->type, name, &s)) return -1; - if (s.included_through_use) return -1; - - return s.idx; - } - - case Ast_Kind_Function: { - AstFunction* func = (AstFunction *) provider; - - i32 param_idx = -1; - i32 idx = 0; - bh_arr_each(AstParam, param, func->params) { - if (token_text_equals(param->local->token, name)) { - param_idx = idx; - break; - } - - idx++; - } - - return param_idx; - } - - default: return -1; - } -} - -static AstNode* lookup_default_value_by_idx(AstNode* provider, i32 idx) { - switch (provider->kind) { - case Ast_Kind_Struct_Literal: { - AstStructLiteral* sl = (AstStructLiteral *) provider; - assert(sl->type); - - if (sl->type->kind == Type_Kind_Struct) { - bh_arr(StructMember *) memarr = sl->type->Struct.memarr; - if (idx >= bh_arr_length(memarr)) return NULL; - - return (AstNode *) *memarr[idx]->initial_value; - } - - return NULL; - } - - case Ast_Kind_Function: { - AstFunction* func = (AstFunction *) provider; - - AstTyped* default_value = func->params[idx].default_value; - if (default_value == NULL) return NULL; - - AstArgument* arg = make_argument(context.ast_alloc, default_value); - return (AstNode *) arg; - } - - default: return NULL; - } -} - -static i32 maximum_argument_count(AstNode* provider) { - switch (provider->kind) { - case Ast_Kind_Struct_Literal: { - AstStructLiteral* sl = (AstStructLiteral *) provider; - assert(sl->type); - - return type_structlike_mem_count(sl->type); - } - } - - // NOTE: This returns int_max for anything other than struct literals because the - // bounds checking on the arguments will be done elsewhere. - return 0x7fffffff; -} - -// NOTE: The values array can be partially filled out, and is the resulting array. -// Returns if all the values were filled in. -b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) { - - { // Delete baked arguments - // :ArgumentResolvingIsComplicated - i32 max = bh_arr_length(args->values); - fori (i, 0, max) { - AstTyped* value = args->values[i]; - if (value == NULL) continue; - - if (value->kind == Ast_Kind_Argument) { - if (((AstArgument *) value)->is_baked) { - i--; - max--; - bh_arr_deleten(args->values, i, 1); - } - } - } - } - - if (args->named_values != NULL) { - bh_arr_each(AstNamedValue *, p_named_value, args->named_values) { - AstNamedValue* named_value = *p_named_value; - - if (named_value->value->kind == Ast_Kind_Argument) { - if (((AstArgument *) named_value->value)->is_baked) { - // :ArgumentResolvingIsComplicated - bh_arr_set_length(args->values, bh_arr_length(args->values) - 1); - continue; - } - } - - token_toggle_end(named_value->token); - i32 idx = lookup_idx_by_name(provider, named_value->token->text); - if (idx == -1) { - if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "'%s' is not a valid named parameter here.", named_value->token->text); - token_toggle_end(named_value->token); - return 0; - } - - // assert(idx < bh_arr_length(args->values)); - if (idx >= bh_arr_length(args->values)) { - token_toggle_end(named_value->token); - return 0; - } - - if (args->values[idx] != NULL && args->values[idx] != named_value->value) { - if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "Multiple values given for parameter named '%s'.", named_value->token->text); - token_toggle_end(named_value->token); - return 0; - } - - args->values[idx] = named_value->value; - token_toggle_end(named_value->token); - } - } - - b32 success = 1; - fori (idx, 0, bh_arr_length(args->values)) { - if (args->values[idx] == NULL) args->values[idx] = (AstTyped *) lookup_default_value_by_idx(provider, idx); - if (args->values[idx] == NULL) { - *err_msg = bh_aprintf(global_scratch_allocator, "No value given for %d%s argument.", idx + 1, bh_num_suffix(idx + 1)); - success = 0; - } - } - - i32 maximum_arguments = maximum_argument_count(provider); - if (bh_arr_length(args->values) > maximum_arguments) { - *err_msg = bh_aprintf(global_scratch_allocator, "Too many values provided. Expected at most %d.", maximum_arguments); - success = 0; - } - - return success; -} - -// -// String parsing helpers -// -u32 char_to_base16_value(char x) { - if (x >= '0' && x <= '9') return (u32) (x - '0'); - if (x >= 'A' && x <= 'F') return (u32) (x - 'A' + 10); - if (x >= 'a' && x <= 'f') return (u32) (x - 'a' + 10); - return 0xffffffff; -} - -i32 string_process_escape_seqs(char* dest, char* src, i32 len) { - i32 total_len = 0; - for (i32 i = 0; i < len; i++) { - if (src[i] == '\\') { - i++; - switch (src[i]) { - case '0': *dest++ = '\0'; total_len++; break; - case 'a': *dest++ = '\a'; total_len++; break; - case 'b': *dest++ = '\b'; total_len++; break; - case 'f': *dest++ = '\f'; total_len++; break; - case 'n': *dest++ = '\n'; total_len++; break; - case 't': *dest++ = '\t'; total_len++; break; - case 'r': *dest++ = '\r'; total_len++; break; - case 'v': *dest++ = '\v'; total_len++; break; - case 'e': *dest++ = '\e'; total_len++; break; - case '"': *dest++ = '"'; total_len++; break; - case '\\': *dest++ = '\\'; total_len++; break; - case 'x': { - u8 ch1 = src[i + 1]; - u8 ch2 = src[i + 2]; - *dest++ = (i8) (char_to_base16_value(ch1) << 4 | char_to_base16_value(ch2)); - total_len++; - i += 2; - break; - } - default: *dest++ = '\\'; - *dest++ = src[i]; - total_len += 2; - } - } else { - *dest++ = src[i]; - total_len += 1; - } - } - - // NOTE: Gotta null terminate - *dest = 0; - - return total_len; -} - -char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders) { - assert(relative_to != NULL); - - static char path[256]; - fori (i, 0, 256) path[i] = 0; - - static char fn[128]; - fori (i, 0, 128) fn[i] = 0; - - if (!bh_str_ends_with(filename, ".onyx") && add_onyx_suffix) { - bh_snprintf(fn, 128, "%s.onyx", filename); - } else { - bh_snprintf(fn, 128, "%s", filename); - } - -#if defined(_BH_LINUX) - #define DIR_SEPARATOR '/' -#elif defined(_BH_WINDOWS) - #define DIR_SEPARATOR '\\' -#endif - - fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR; - - if (bh_str_starts_with(filename, "./")) { - if (relative_to[strlen(relative_to) - 1] != DIR_SEPARATOR) - bh_snprintf(path, 256, "%s%c%s", relative_to, DIR_SEPARATOR, fn + 2); - else - bh_snprintf(path, 256, "%s%s", relative_to, fn + 2); - - if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); - - return fn; - } - - if (search_included_folders) { - bh_arr_each(const char *, folder, context.options->included_folders) { - if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR) - bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn); - else - bh_snprintf(path, 256, "%s%s", *folder, fn); - - if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); - } - } - - return fn; - -#undef DIR_SEPARATOR -} - diff --git a/src/onyxsymres.c b/src/symres.c similarity index 99% rename from src/onyxsymres.c rename to src/symres.c index b048e6c8..4e1bcef7 100644 --- a/src/onyxsymres.c +++ b/src/symres.c @@ -1,8 +1,8 @@ #define BH_DEBUG -#include "onyxparser.h" -#include "onyxutils.h" -#include "onyxastnodes.h" -#include "onyxerrors.h" +#include "parser.h" +#include "utils.h" +#include "astnodes.h" +#include "errors.h" // Variables used during the symbol resolution phase. static Scope* curr_scope = NULL; diff --git a/src/onyxtypes.c b/src/types.c similarity index 99% rename from src/onyxtypes.c rename to src/types.c index ed4f955e..84ccbd01 100644 --- a/src/onyxtypes.c +++ b/src/types.c @@ -1,8 +1,8 @@ #define BH_DEBUG -#include "onyxtypes.h" -#include "onyxastnodes.h" -#include "onyxutils.h" -#include "onyxerrors.h" +#include "types.h" +#include "astnodes.h" +#include "utils.h" +#include "errors.h" // NOTE: These have to be in the same order as Basic Type basic_types[] = { diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 00000000..b98a9e21 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,871 @@ +#define BH_DEBUG + +#include "utils.h" +#include "lex.h" +#include "astnodes.h" +#include "errors.h" +#include "parser.h" +#include "astnodes.h" + +bh_scratch global_scratch; +bh_allocator global_scratch_allocator; + +bh_managed_heap global_heap; +bh_allocator global_heap_allocator; + +// +// Program info and packages +// +Package* package_lookup(char* package_name) { + if (bh_table_has(Package *, context.packages, package_name)) { + return bh_table_get(Package *, context.packages, package_name); + } else { + return NULL; + } +} + +Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_allocator alloc) { + if (bh_table_has(Package *, context.packages, package_name)) { + return bh_table_get(Package *, context.packages, package_name); + + } else { + Package* package = bh_alloc_item(alloc, Package); + + char* pac_name = bh_alloc_array(alloc, char, strlen(package_name) + 1); + memcpy(pac_name, package_name, strlen(package_name) + 1); + pac_name[strlen(package_name)] = '\0'; + + package->name = pac_name; + package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 }); + package->private_scope = scope_create(alloc, package->scope, (OnyxFilePos) { 0 }); + package->use_package_entities = NULL; + + bh_table_put(Package *, context.packages, pac_name, package); + + return package; + } +} + +void package_track_use_package(Package* package, Entity* entity) { + if (package->use_package_entities == NULL) { + bh_arr_new(global_heap_allocator, package->use_package_entities, 4); + } + + bh_arr_push(package->use_package_entities, entity); +} + +void package_reinsert_use_packages(Package* package) { + if (!package->use_package_entities) return; + + bh_arr_each(Entity *, use_package, package->use_package_entities) { + (*use_package)->state = Entity_State_Resolve_Symbols; + (*use_package)->macro_attempts = 0; + entity_heap_insert_existing(&context.entities, *use_package); + } + + bh_arr_set_length(package->use_package_entities, 0); +} + + +// +// Scoping +// +static u64 next_scope_id = 1; + +Scope* scope_create(bh_allocator a, Scope* parent, OnyxFilePos created_at) { + Scope* scope = bh_alloc_item(a, Scope); + scope->id = next_scope_id++; + scope->parent = parent; + scope->created_at = created_at; + + scope->symbols = NULL; + bh_table_init(global_heap_allocator, scope->symbols, 64); + + return scope; +} + +void scope_include(Scope* target, Scope* source, OnyxFilePos pos) { + bh_table_each_start(AstNode *, source->symbols); + symbol_raw_introduce(target, (char *) key, pos, value); + bh_table_each_end; +} + +b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol) { + token_toggle_end(tkn); + + b32 ret = symbol_raw_introduce(scope, tkn->text, tkn->pos, symbol); + + token_toggle_end(tkn); + return ret; +} + +b32 symbol_raw_introduce(Scope* scope, char* name, OnyxFilePos pos, AstNode* symbol) { + if (strcmp(name, "_")) { + if (bh_table_has(AstNode *, scope->symbols, name)) { + if (bh_table_get(AstNode *, scope->symbols, name) != symbol) { + onyx_report_error(pos, "Redeclaration of symbol '%s'.", name); + return 0; + } + return 1; + } + } + + bh_table_put(AstNode *, scope->symbols, name, symbol); + return 1; +} + +void symbol_builtin_introduce(Scope* scope, char* sym, AstNode *node) { + bh_table_put(AstNode *, scope->symbols, sym, node); +} + +void symbol_subpackage_introduce(Scope* scope, char* sym, AstPackage* package) { + if (bh_table_has(AstNode *, scope->symbols, sym)) { + AstNode* maybe_package = bh_table_get(AstNode *, scope->symbols, sym); + + // CLEANUP: Make this assertion an actual error message. + assert(maybe_package->kind == Ast_Kind_Package); + } else { + bh_table_put(AstNode *, scope->symbols, sym, (AstNode *) package); + } +} + +AstNode* symbol_raw_resolve(Scope* start_scope, char* sym) { + AstNode* res = NULL; + Scope* scope = start_scope; + + while (res == NULL && scope != NULL) { + if (bh_table_has(AstNode *, scope->symbols, sym)) { + res = bh_table_get(AstNode *, scope->symbols, sym); + } else { + scope = scope->parent; + } + } + + return res; +} + +AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) { + token_toggle_end(tkn); + AstNode* res = symbol_raw_resolve(start_scope, tkn->text); + token_toggle_end(tkn); + + return res; +} + +AstNode* try_symbol_raw_resolve_from_node(AstNode* node, char* symbol) { + b32 used_pointer = 0; + + while (1) { + if (!node) return NULL; + + switch (node->kind) { + case Ast_Kind_Type_Raw_Alias: node = (AstNode *) ((AstTypeRawAlias *) node)->to->ast_type; break; + case Ast_Kind_Type_Alias: node = (AstNode *) ((AstTypeAlias *) node)->to; break; + case Ast_Kind_Alias: node = (AstNode *) ((AstAlias *) node)->alias; break; + case Ast_Kind_Pointer_Type: { + if (used_pointer) goto all_types_peeled_off; + used_pointer = 1; + + node = (AstNode *) ((AstPointerType *) node)->elem; + break; + } + + default: goto all_types_peeled_off; + } + } + +all_types_peeled_off: + if (!node) return NULL; + + switch (node->kind) { + case Ast_Kind_Package: { + AstPackage* package = (AstPackage *) node; + + // CLEANUP + if (package->package == NULL) { + package->package = package_lookup(package->package_name); + } + + if (package->package == NULL) { + return NULL; + } + + return symbol_raw_resolve(package->package->scope, symbol); + } + + case Ast_Kind_Enum_Type: { + AstEnumType* etype = (AstEnumType *) node; + return symbol_raw_resolve(etype->scope, symbol); + } + + case Ast_Kind_Struct_Type: { + AstStructType* stype = (AstStructType *) node; + AstNode* result = symbol_raw_resolve(stype->scope, symbol); + + if (result == NULL && stype->stcache != NULL) { + Type* struct_type = stype->stcache; + assert(struct_type->kind == Type_Kind_Struct); + + bh_arr_each(AstPolySolution, sln, struct_type->Struct.poly_sln) { + if (token_text_equals(sln->poly_sym->token, symbol)) { + if (sln->kind == PSK_Type) { + result = (AstNode *) sln->type->ast_type; + } else { + result = (AstNode *) sln->value; + } + } + } + } + + return result; + } + + case Ast_Kind_Poly_Struct_Type: { + AstStructType* stype = ((AstPolyStructType *) node)->base_struct; + return symbol_raw_resolve(stype->scope, symbol); + } + } + + return NULL; +} + +AstNode* try_symbol_resolve_from_node(AstNode* node, OnyxToken* token) { + token_toggle_end(token); + AstNode* result = try_symbol_raw_resolve_from_node(node, token->text); + token_toggle_end(token); + + return result; +} + +void scope_clear(Scope* scope) { + bh_table_clear(scope->symbols); +} + +// Polymorphic procedures are in their own file to clean up this file. +#include "polymorph.c" + +// +// Overloaded Procedures +// + +// +// @Cleanup: Everything having to do with overload resolving! +// Things that need to be available: +// * A copy of the arguments list that can be mutated +// - The named_values do not need to be copied, because they are not modified when fill_in_arguments happens. +// - Only values needs to have a copy available +// - This copy needs to be reset after checking every option +// +// Steps needed to check if an overload option is "the one": +// 1. Figure out what the overload is +// a. If polymorphic, generate the header for the procedure only +// 2. Place the arguments in the copy, according to the overload option +// 3. Ensure the option has a type filled out +// 4. For each argument +// a. Ensure it has a place to go (not too many arguments) +// b. Ensure it has a type +// c. Ensure the types match (currently there could be a problem if an option is attempted and doesn't work all the way that polymorphic procedures as arguments could still be solidified) +// +// Additional features that this needs to account for: +// * Resolving an overload from a list of parameter types +// * Resolving an overload from a TypeFunction (so an overloaded procedure can be passed as a parameter) +// + +void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload) { + bh_arr(OverloadOption) overloads = *poverloads; + + i32 index = -1; + fori (i, 0, bh_arr_length(overloads)) { + if (overloads[i].precedence > precedence) { + index = i; + break; + } + } + + if (index < 0) { + bh_arr_push(overloads, ((OverloadOption) { + .precedence = precedence, + .option = overload, + })); + + } else { + bh_arr_insertn(overloads, index, 1); + overloads[index].precedence = precedence; + overloads[index].option = overload; + } + + *poverloads = overloads; +} + +// NOTE: The job of this function is to take a set of overloads, and traverse it to add all possible +// overloads that are reachable. This is slightly more difficult than it may seem. In this language, +// overloaded procedures have a strict ordering to their overloads, which determines how the correct +// match will be found. This was not very complicated until overloaded procedures could be used as +// overload options. This means that you could create an "infinite loop" of overloads like so: +// +// o1 :: { o2 :: { +// (...) { ... }, (...) { ... }, +// o2 o1 +// } } +// +// Obviously, this is not really an infinite loop. It just means that all options are available if +// o1 or o2 are called. The difference between o1 and o2 is the order that the overloads will be +// searched. To build the the list of overloads, a hashmap is used to prevent the problem from being +// O(n^2), even though n would (probably) be small. bh_imap has the useful property that it maintains +// an "entries" array that, so long as nothing is ever removed from it, will maintain the order in +// which entries were put into the map. This is useful because a simple recursive algorithm can +// collect all the overloads into the map, and also use the map to provide a base case. +void build_all_overload_options(bh_arr(OverloadOption) overloads, bh_imap* all_overloads) { + bh_arr_each(OverloadOption, overload, overloads) { + if (bh_imap_has(all_overloads, (u64) overload->option)) continue; + + bh_imap_put(all_overloads, (u64) overload->option, 1); + + if (overload->option->kind == Ast_Kind_Overloaded_Function) { + AstOverloadedFunction* sub_overload = (AstOverloadedFunction *) overload->option; + build_all_overload_options(sub_overload->overloads, all_overloads); + } + } +} + +AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args, b32* should_yield) { + Arguments args; + arguments_clone(&args, param_args); + arguments_ensure_length(&args, bh_arr_length(args.values) + bh_arr_length(args.named_values)); + + // CLEANUP SPEED: This currently rebuilds the complete set of overloads every time one is looked up. + // This should be cached in the AstOverloadedFunction or somewhere like that. + bh_imap all_overloads; + bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2); + build_all_overload_options(overloads, &all_overloads); + + AstTyped *matched_overload = NULL; + + bh_arr_each(bh__imap_entry, entry, all_overloads.entries) { + AstTyped* node = (AstTyped *) entry->key; + arguments_copy(&args, param_args); + + AstFunction* overload = NULL; + switch (node->kind) { + case Ast_Kind_Function: overload = (AstFunction *) node; break; + case Ast_Kind_Macro: overload = macro_resolve_header((AstMacro *) node, param_args, NULL); break; + case Ast_Kind_Polymorphic_Proc: overload = polymorphic_proc_build_only_header((AstPolyProc *) node, PPLM_By_Arguments, param_args); break; + } + + // NOTE: Overload is not something that is known to be overloadable. + if (overload == NULL) continue; + if (overload->kind != Ast_Kind_Function) continue; + if (overload->type == NULL) { + // If it was not possible to create the type for this procedure, tell the + // caller that this should yield and try again later. + if (should_yield) *should_yield = 1; + + // return and not continue because if the overload that didn't have a type will + // work in the future, then it has to take precedence over the other options available. + return NULL; + } + assert(overload->type->kind == Type_Kind_Function); + + // NOTE: If the arguments cannot be placed successfully in the parameters list + if (!fill_in_arguments(&args, (AstNode *) overload, NULL)) continue; + + TypeFunction* ol_type = &overload->type->Function; + if (bh_arr_length(args.values) < (i32) ol_type->needed_param_count) continue; + + b32 all_arguments_work = 1; + fori (i, 0, bh_arr_length(args.values)) { + if (i >= ol_type->param_count) { + all_arguments_work = 0; + break; + } + + Type* type_to_match = ol_type->params[i]; + AstTyped** value = &args.values[i]; + + if (type_to_match->kind == Type_Kind_VarArgs) type_to_match = type_to_match->VarArgs.ptr_to_data->Pointer.elem; + if ((*value)->kind == Ast_Kind_Argument) { + // :ArgumentResolvingIsComplicated + if (((AstArgument *) (*value))->is_baked) continue; + value = &((AstArgument *) *value)->value; + } + + if (!type_check_or_auto_cast(value, type_to_match)) { + all_arguments_work = 0; + break; + } + } + + if (all_arguments_work) { + matched_overload = node; + break; + } + } + + bh_imap_free(&all_overloads); + bh_arr_free(args.values); + return matched_overload; +} + +AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type* type) { + if (type->kind != Type_Kind_Function) return NULL; + + bh_imap all_overloads; + bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2); + build_all_overload_options(overloads, &all_overloads); + + AstTyped *matched_overload = NULL; + + bh_arr_each(bh__imap_entry, entry, all_overloads.entries) { + AstTyped* node = (AstTyped *) entry->key; + if (node->kind == Ast_Kind_Overloaded_Function) continue; + + if (type_check_or_auto_cast(&node, type)) { + matched_overload = node; + break; + } + } + + bh_imap_free(&all_overloads); + return matched_overload; +} + +void report_unable_to_match_overload(AstCall* call) { + char* arg_str = bh_alloc(global_scratch_allocator, 1024); + arg_str[0] = '\0'; + + bh_arr_each(AstTyped *, arg, call->args.values) { + strncat(arg_str, node_get_type_name(*arg), 1023); + + if (arg != &bh_arr_last(call->args.values)) + strncat(arg_str, ", ", 1023); + } + + if (bh_arr_length(call->args.named_values) > 0) { + if (bh_arr_length(call->args.values) > 0) { + strncat(arg_str, ", ", 1023); + } + + bh_arr_each(AstNamedValue *, named_value, call->args.named_values) { + token_toggle_end((*named_value)->token); + strncat(arg_str, (*named_value)->token->text, 1023); + token_toggle_end((*named_value)->token); + + strncat(arg_str, "=", 1023); + strncat(arg_str, node_get_type_name((*named_value)->value), 1023); // CHECK: this might say 'unknown'. + + if (named_value != &bh_arr_last(call->args.named_values)) + strncat(arg_str, ", ", 1023); + } + } + + onyx_report_error(call->token->pos, "Unable to match overloaded function with provided argument types: (%s)", arg_str); + + bh_free(global_scratch_allocator, arg_str); +} + + +// +// Macros +// +// +// TODO: Write this documentation +void expand_macro(AstCall** pcall, AstFunction* template) { + AstCall* call = *pcall; + AstMacro* macro = (AstMacro *) call->callee; + assert(macro->kind == Ast_Kind_Macro); + + assert(template->kind == Ast_Kind_Function); + assert(template->type != NULL); + assert(template->type->kind == Type_Kind_Function); + + AstBlock* expansion = (AstBlock *) ast_clone(context.ast_alloc, template->body); + expansion->rules = Block_Rule_Macro; + expansion->scope = NULL; + expansion->next = call->next; + + AstNode* subst = (AstNode *) expansion; + + if (template->type->Function.return_type != &basic_types[Basic_Kind_Void]) { + AstDoBlock* doblock = (AstDoBlock *) onyx_ast_node_new(context.ast_alloc, sizeof(AstDoBlock), Ast_Kind_Do_Block); + doblock->token = expansion->token; + doblock->block = expansion; + doblock->type = template->type->Function.return_type; + doblock->next = expansion->next; + expansion->next = NULL; + + subst = (AstNode *) doblock; + } + + Scope* argument_scope = scope_create(context.ast_alloc, NULL, call->token->pos); + if (expansion->binding_scope != NULL) + scope_include(argument_scope, expansion->binding_scope, call->token->pos); + expansion->binding_scope = argument_scope; + + // HACK HACK HACK This is probably very wrong. I don't know what guarentees that + // the paramters and arguments are going to be in the same order exactly. + fori (i, 0, bh_arr_length(call->args.values)) { + symbol_introduce(argument_scope, + template->params[i].local->token, + (AstNode *) ((AstArgument *) call->args.values[i])->value); + } + + if (template->flags & Ast_Flag_From_Polymorphism) { + // SLOW DUMB HACKY WAY TO DO THIS!!!!! FIX IT!!!!! + + AstPolyProc* pp = (AstPolyProc *) macro->body; + bh_table_each_start(AstSolidifiedFunction, pp->concrete_funcs); + + if (value.func == template) { + scope_include(argument_scope, value.poly_scope, call->token->pos); + break; + } + + bh_table_each_end; + } + + *(AstNode **) pcall = subst; + return; +} + +AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite) { + switch (macro->body->kind) { + case Ast_Kind_Function: return (AstFunction *) macro->body; + + case Ast_Kind_Polymorphic_Proc: { + AstPolyProc* pp = (AstPolyProc *) macro->body; + ensure_polyproc_cache_is_created(pp); + + char* err_msg=NULL; + bh_arr(AstPolySolution) slns = find_polymorphic_slns(pp, PPLM_By_Arguments, args, &err_msg); + + if (slns == NULL) { + if (flag_to_yield) { + flag_to_yield = 0; + return (AstFunction *) &node_that_signals_a_yield; + } + + if (callsite) onyx_report_error(callsite->pos, err_msg); + + return NULL; + } + + // CLEANUP Copy'n'pasted from polymorphic_proc_build_only_header + AstSolidifiedFunction solidified_func; + + char* unique_key = build_poly_slns_unique_key(slns); + if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) { + solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key); + + } else { + // NOTE: This function is only going to have the header of it correctly created. + // Nothing should happen to this function's body or else the original will be corrupted. + // - brendanfh 2021/01/10 + solidified_func = generate_solidified_function(pp, slns, callsite, 1); + } + + if (solidified_func.header_complete) return solidified_func.func; + + Entity func_header_entity = { + .state = Entity_State_Resolve_Symbols, + .type = Entity_Type_Function_Header, + .function = solidified_func.func, + .package = NULL, + .scope = solidified_func.poly_scope, + }; + + b32 successful = entity_bring_to_state(&func_header_entity, Entity_State_Code_Gen); + if (onyx_has_errors()) return NULL; + + solidified_func.header_complete = successful; + + bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func); + if (!successful) return (AstFunction *) &node_that_signals_a_yield; + + return solidified_func.func; + } + + default: assert(("Bad macro body type.", 0)); + } +} + +b32 entity_bring_to_state(Entity* ent, EntityState state) { + EntityState last_state = ent->state; + + while (ent->state != state) { + switch (ent->state) { + case Entity_State_Resolve_Symbols: symres_entity(ent); break; + case Entity_State_Check_Types: check_entity(ent); break; + case Entity_State_Code_Gen: emit_entity(ent); break; + + default: return 0; + } + + if (ent->state == last_state) return 0; + last_state = ent->state; + + if (onyx_has_errors()) return 0; + } + + return 1; +} + + +// +// Arguments resolving +// +static i32 lookup_idx_by_name(AstNode* provider, char* name) { + switch (provider->kind) { + case Ast_Kind_Struct_Literal: { + AstStructLiteral* sl = (AstStructLiteral *) provider; + assert(sl->type); + + StructMember s; + if (!type_lookup_member(sl->type, name, &s)) return -1; + if (s.included_through_use) return -1; + + return s.idx; + } + + case Ast_Kind_Function: { + AstFunction* func = (AstFunction *) provider; + + i32 param_idx = -1; + i32 idx = 0; + bh_arr_each(AstParam, param, func->params) { + if (token_text_equals(param->local->token, name)) { + param_idx = idx; + break; + } + + idx++; + } + + return param_idx; + } + + default: return -1; + } +} + +static AstNode* lookup_default_value_by_idx(AstNode* provider, i32 idx) { + switch (provider->kind) { + case Ast_Kind_Struct_Literal: { + AstStructLiteral* sl = (AstStructLiteral *) provider; + assert(sl->type); + + if (sl->type->kind == Type_Kind_Struct) { + bh_arr(StructMember *) memarr = sl->type->Struct.memarr; + if (idx >= bh_arr_length(memarr)) return NULL; + + return (AstNode *) *memarr[idx]->initial_value; + } + + return NULL; + } + + case Ast_Kind_Function: { + AstFunction* func = (AstFunction *) provider; + + AstTyped* default_value = func->params[idx].default_value; + if (default_value == NULL) return NULL; + + AstArgument* arg = make_argument(context.ast_alloc, default_value); + return (AstNode *) arg; + } + + default: return NULL; + } +} + +static i32 maximum_argument_count(AstNode* provider) { + switch (provider->kind) { + case Ast_Kind_Struct_Literal: { + AstStructLiteral* sl = (AstStructLiteral *) provider; + assert(sl->type); + + return type_structlike_mem_count(sl->type); + } + } + + // NOTE: This returns int_max for anything other than struct literals because the + // bounds checking on the arguments will be done elsewhere. + return 0x7fffffff; +} + +// NOTE: The values array can be partially filled out, and is the resulting array. +// Returns if all the values were filled in. +b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) { + + { // Delete baked arguments + // :ArgumentResolvingIsComplicated + i32 max = bh_arr_length(args->values); + fori (i, 0, max) { + AstTyped* value = args->values[i]; + if (value == NULL) continue; + + if (value->kind == Ast_Kind_Argument) { + if (((AstArgument *) value)->is_baked) { + i--; + max--; + bh_arr_deleten(args->values, i, 1); + } + } + } + } + + if (args->named_values != NULL) { + bh_arr_each(AstNamedValue *, p_named_value, args->named_values) { + AstNamedValue* named_value = *p_named_value; + + if (named_value->value->kind == Ast_Kind_Argument) { + if (((AstArgument *) named_value->value)->is_baked) { + // :ArgumentResolvingIsComplicated + bh_arr_set_length(args->values, bh_arr_length(args->values) - 1); + continue; + } + } + + token_toggle_end(named_value->token); + i32 idx = lookup_idx_by_name(provider, named_value->token->text); + if (idx == -1) { + if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "'%s' is not a valid named parameter here.", named_value->token->text); + token_toggle_end(named_value->token); + return 0; + } + + // assert(idx < bh_arr_length(args->values)); + if (idx >= bh_arr_length(args->values)) { + token_toggle_end(named_value->token); + return 0; + } + + if (args->values[idx] != NULL && args->values[idx] != named_value->value) { + if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "Multiple values given for parameter named '%s'.", named_value->token->text); + token_toggle_end(named_value->token); + return 0; + } + + args->values[idx] = named_value->value; + token_toggle_end(named_value->token); + } + } + + b32 success = 1; + fori (idx, 0, bh_arr_length(args->values)) { + if (args->values[idx] == NULL) args->values[idx] = (AstTyped *) lookup_default_value_by_idx(provider, idx); + if (args->values[idx] == NULL) { + *err_msg = bh_aprintf(global_scratch_allocator, "No value given for %d%s argument.", idx + 1, bh_num_suffix(idx + 1)); + success = 0; + } + } + + i32 maximum_arguments = maximum_argument_count(provider); + if (bh_arr_length(args->values) > maximum_arguments) { + *err_msg = bh_aprintf(global_scratch_allocator, "Too many values provided. Expected at most %d.", maximum_arguments); + success = 0; + } + + return success; +} + +// +// String parsing helpers +// +u32 char_to_base16_value(char x) { + if (x >= '0' && x <= '9') return (u32) (x - '0'); + if (x >= 'A' && x <= 'F') return (u32) (x - 'A' + 10); + if (x >= 'a' && x <= 'f') return (u32) (x - 'a' + 10); + return 0xffffffff; +} + +i32 string_process_escape_seqs(char* dest, char* src, i32 len) { + i32 total_len = 0; + for (i32 i = 0; i < len; i++) { + if (src[i] == '\\') { + i++; + switch (src[i]) { + case '0': *dest++ = '\0'; total_len++; break; + case 'a': *dest++ = '\a'; total_len++; break; + case 'b': *dest++ = '\b'; total_len++; break; + case 'f': *dest++ = '\f'; total_len++; break; + case 'n': *dest++ = '\n'; total_len++; break; + case 't': *dest++ = '\t'; total_len++; break; + case 'r': *dest++ = '\r'; total_len++; break; + case 'v': *dest++ = '\v'; total_len++; break; + case 'e': *dest++ = '\e'; total_len++; break; + case '"': *dest++ = '"'; total_len++; break; + case '\\': *dest++ = '\\'; total_len++; break; + case 'x': { + u8 ch1 = src[i + 1]; + u8 ch2 = src[i + 2]; + *dest++ = (i8) (char_to_base16_value(ch1) << 4 | char_to_base16_value(ch2)); + total_len++; + i += 2; + break; + } + default: *dest++ = '\\'; + *dest++ = src[i]; + total_len += 2; + } + } else { + *dest++ = src[i]; + total_len += 1; + } + } + + // NOTE: Gotta null terminate + *dest = 0; + + return total_len; +} + +char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders) { + assert(relative_to != NULL); + + static char path[256]; + fori (i, 0, 256) path[i] = 0; + + static char fn[128]; + fori (i, 0, 128) fn[i] = 0; + + if (!bh_str_ends_with(filename, ".onyx") && add_onyx_suffix) { + bh_snprintf(fn, 128, "%s.onyx", filename); + } else { + bh_snprintf(fn, 128, "%s", filename); + } + +#if defined(_BH_LINUX) + #define DIR_SEPARATOR '/' +#elif defined(_BH_WINDOWS) + #define DIR_SEPARATOR '\\' +#endif + + fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR; + + if (bh_str_starts_with(filename, "./")) { + if (relative_to[strlen(relative_to) - 1] != DIR_SEPARATOR) + bh_snprintf(path, 256, "%s%c%s", relative_to, DIR_SEPARATOR, fn + 2); + else + bh_snprintf(path, 256, "%s%s", relative_to, fn + 2); + + if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); + + return fn; + } + + if (search_included_folders) { + bh_arr_each(const char *, folder, context.options->included_folders) { + if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR) + bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn); + else + bh_snprintf(path, 256, "%s%s", *folder, fn); + + if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); + } + } + + return fn; + +#undef DIR_SEPARATOR +} + diff --git a/src/onyxwasm.c b/src/wasm.c similarity index 99% rename from src/onyxwasm.c rename to src/wasm.c index beeddfb9..144deaba 100644 --- a/src/onyxwasm.c +++ b/src/wasm.c @@ -14,8 +14,8 @@ #define BH_DEBUG -#include "onyxwasm.h" -#include "onyxutils.h" +#include "wasm.h" +#include "utils.h" #define WASM_TYPE_INT32 0x7F #define WASM_TYPE_INT64 0x7E @@ -270,8 +270,8 @@ EMIT_FUNC_NO_ARGS(leave_structured_block); static void emit_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node); static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node); -#include "onyxwasm_intrinsics.c" -#include "onyxwasm_type_table.c" +#include "wasm_intrinsics.c" +#include "wasm_type_table.c" EMIT_FUNC(function_body, AstFunction* fd) { if (fd->body == NULL) return; @@ -3669,4 +3669,4 @@ void onyx_wasm_module_free(OnyxWasmModule* module) { } -#include "onyxwasm_output.c" +#include "wasm_output.c" diff --git a/src/onyxwasm_intrinsics.c b/src/wasm_intrinsics.c similarity index 100% rename from src/onyxwasm_intrinsics.c rename to src/wasm_intrinsics.c diff --git a/src/onyxwasm_output.c b/src/wasm_output.c similarity index 100% rename from src/onyxwasm_output.c rename to src/wasm_output.c diff --git a/src/onyxwasm_type_table.c b/src/wasm_type_table.c similarity index 100% rename from src/onyxwasm_type_table.c rename to src/wasm_type_table.c -- 2.25.1