From: Brendan Hansen Date: Fri, 31 Dec 2021 18:05:23 +0000 (-0600) Subject: made enums behave better with static ifs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=0e8dfdb4d6cd256f8b3e4d6a381c9fb7001c701b;p=onyx.git made enums behave better with static ifs --- diff --git a/core/builtin.onyx b/core/builtin.onyx index f1a674ff..5bdb9641 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -62,7 +62,7 @@ OnyxContext :: struct { thread_id : i32; } -#if runtime.Runtime != runtime.Runtime_Custom { +#if runtime.runtime != .Custom { #local default_logger :: (data: rawptr, msg: str) { use package core println(msg); @@ -135,7 +135,7 @@ cresize :: (ptr: rawptr, size: u32) -> rawptr do return raw_resize(context.alloc cfree :: (ptr: rawptr) do raw_free(context.allocator, ptr); // CLEANUP: Does this really need to be limited to a non-custom runtime? -#if runtime.Runtime != runtime.Runtime_Custom { +#if runtime.runtime != .Custom { new :: ($T: type_expr, allocator := context.allocator) -> ^T { use package core.intrinsics.onyx { __initialize } diff --git a/core/os/os.onyx b/core/os/os.onyx index 23c77f80..c5aacf79 100644 --- a/core/os/os.onyx +++ b/core/os/os.onyx @@ -1,7 +1,7 @@ package core.os -#if runtime.Runtime != runtime.Runtime_Wasi - && runtime.Runtime != runtime.Runtime_Onyx { +#if runtime.runtime != .Wasi + && runtime.runtime != .Onyx { #error "The os library is currently only available on the WASI runtime, and should only be included if that is the chosen runtime." } diff --git a/core/os/process.onyx b/core/os/process.onyx index 5f66ab4a..76186568 100644 --- a/core/os/process.onyx +++ b/core/os/process.onyx @@ -1,6 +1,6 @@ package core.os -#if runtime.Runtime != runtime.Runtime_Onyx { +#if runtime.runtime != .Onyx { #error "This file can only be included in the 'onyx' runtime, because Wasi has not defined how to spawn and manage processes."; } diff --git a/core/runtime/build_opts.onyx b/core/runtime/build_opts.onyx index af42c699..1016bdb9 100644 --- a/core/runtime/build_opts.onyx +++ b/core/runtime/build_opts.onyx @@ -1,27 +1,15 @@ -// This following sybmols are not meant to be included in any compilation. -// Instead, all of the commented out symbols are defined automatically by the compiler -// and can be used in compile time #if statements. - -// Runtime :: Runtime_Wasi OR Runtime_Js OR Runtime_Custom - - - - - package runtime - -// At some point, these will become an enum. The problem at the moment is that -// compile-time if statements are not well integrated into other language features -// such as enums. They can only really handle compile time number math and boolean -// logic. - brendanfh 2020/02/08 - -Runtime_Onyx :: 1 -Runtime_Wasi :: 2 -Runtime_Js :: 3 -Runtime_Custom :: 4 - - - -OS_Linux :: 1 -OS_Windows :: 2 \ No newline at end of file +// runtime: Runtime This is set by the compiler +Runtime :: enum { + Onyx :: 1; + Wasi :: 2; + Js :: 3; + Custom :: 4; +} + +// compiler_os This is set by the compiler. It is not called 'os' because that conflicts with the 'core.os' package. +OS :: enum { + Linux :: 1; + Windows :: 2; +} \ No newline at end of file diff --git a/core/std.onyx b/core/std.onyx index 91f67e4d..e4db4636 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -38,26 +38,26 @@ package core #load "./type_info/helper" #local runtime :: package runtime -#if runtime.Runtime == runtime.Runtime_Wasi || runtime.Runtime == runtime.Runtime_Onyx { +#if runtime.runtime == .Wasi || runtime.runtime == .Onyx { #load "./os/file" #load "./os/os" #load "./os/dir" } -#if runtime.Runtime == runtime.Runtime_Onyx { +#if runtime.runtime == .Onyx { #load "./runtime/onyx_run" #load "./os/process" #load "./os/onyx_fs" } -#if runtime.Runtime == runtime.Runtime_Wasi { +#if runtime.runtime == .Wasi { #load "./wasi/wasi" #load "./runtime/wasi" #load "./wasi/clock" #load "./wasi/env" #load "./wasi/wasi_fs" } -#if runtime.Runtime == runtime.Runtime_Js { #load "./runtime/js" } -#if runtime.Runtime != runtime.Runtime_Custom { #load "./stdio" } +#if runtime.runtime == .Js { #load "./runtime/js" } +#if runtime.runtime != .Custom { #load "./stdio" } #if runtime.Multi_Threading_Enabled { #load "./intrinsics/atomics" diff --git a/core/stdio.onyx b/core/stdio.onyx index edc82140..6e7b19ff 100644 --- a/core/stdio.onyx +++ b/core/stdio.onyx @@ -8,7 +8,7 @@ package core #local runtime :: package runtime -#if runtime.Runtime == runtime.Runtime_Custom { +#if runtime.runtime == .Custom { #error "'stdio' can only be included in the 'wasi' or 'js' runtime." } diff --git a/core/wasi/clock.onyx b/core/wasi/clock.onyx index e3dd7080..468327f4 100644 --- a/core/wasi/clock.onyx +++ b/core/wasi/clock.onyx @@ -1,8 +1,8 @@ package core.clock #local runtime :: package runtime -#if runtime.Runtime != runtime.Runtime_Wasi - && runtime.Runtime != runtime.Runtime_Onyx { +#if runtime.runtime != .Wasi + && runtime.runtime != .Onyx { #error "'core.clock' is only available with the 'wasi' or 'onyx' runtimes."; } diff --git a/core/wasi/env.onyx b/core/wasi/env.onyx index 09dfa057..7cd5b3bc 100644 --- a/core/wasi/env.onyx +++ b/core/wasi/env.onyx @@ -1,8 +1,8 @@ package core.env #local runtime :: package runtime -#if runtime.Runtime != runtime.Runtime_Wasi - && runtime.Runtime != runtime.Runtime_Onyx { +#if runtime.runtime != .Wasi + && runtime.runtime != .Onyx { #error "'core.env' is only available with the 'wasi' and 'onyx' runtimes."; } diff --git a/core/wasi/wasi_fs.onyx b/core/wasi/wasi_fs.onyx index 501840a4..7c7c2f6a 100644 --- a/core/wasi/wasi_fs.onyx +++ b/core/wasi/wasi_fs.onyx @@ -1,7 +1,7 @@ package runtime.fs #local runtime :: package runtime -#if runtime.Runtime != runtime.Runtime_Wasi { +#if runtime.runtime != .Wasi { #error "The file system library is currently only available on the WASI runtime, and should only be included if that is the chosen runtime." } diff --git a/include/astnodes.h b/include/astnodes.h index 04c18923..2bdbe975 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -962,6 +962,8 @@ struct AstMemRes { u64 addr; AstTyped *initial_value; + struct Entity *type_entity; + b32 threadlocal : 1; }; struct AstGlobal { diff --git a/misc/vscode/onyx-0.0.2.vsix b/misc/vscode/onyx-0.0.2.vsix index 083a8045..1802361b 100644 Binary files a/misc/vscode/onyx-0.0.2.vsix and b/misc/vscode/onyx-0.0.2.vsix differ diff --git a/misc/vscode/out/extension.js b/misc/vscode/out/extension.js index 3135afa3..bec2b3fd 100644 --- a/misc/vscode/out/extension.js +++ b/misc/vscode/out/extension.js @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.activate = void 0; const vscode = require("vscode"); const vsctmls = require("vscode-textmate-languageservice"); function activate(context) { diff --git a/misc/vscode/syntaxes/onyx.tmLanguage b/misc/vscode/syntaxes/onyx.tmLanguage index 844d2912..1cd19c12 100644 --- a/misc/vscode/syntaxes/onyx.tmLanguage +++ b/misc/vscode/syntaxes/onyx.tmLanguage @@ -281,7 +281,7 @@ match - \b(void)\b + \b(void|rawptr)\b name storage.type.onyx diff --git a/modules/webgl2/webgl2.onyx b/modules/webgl2/webgl2.onyx index 637bec2f..863cb225 100644 --- a/modules/webgl2/webgl2.onyx +++ b/modules/webgl2/webgl2.onyx @@ -4,7 +4,7 @@ package gl // There are many things that are missing but this suffices for me. #local runtime :: package runtime -#if runtime.Runtime != runtime.Runtime_Js { +#if runtime.runtime != .Js { #error "'webgl' can only be used with the 'js' runtime." } diff --git a/scripts/run_tests.onyx b/scripts/run_tests.onyx index 01569939..b36bf39d 100644 --- a/scripts/run_tests.onyx +++ b/scripts/run_tests.onyx @@ -69,7 +69,7 @@ print_color :: (color: Color, format: str, args: ..any) { buffer: [2048] u8; output := conv.str_format_va(buffer, format, args); - if runtime.OS == runtime.OS_Linux && !settings.no_color { + if runtime.compiler_os == .Linux && !settings.no_color { color_code: str; switch color { case .Red do color_code = "\x1b[91m"; @@ -226,12 +226,12 @@ main :: (args) => { args_parse(args, ^settings); printf("Using {p*}\n", ^settings); - switch runtime.OS { - case runtime.OS_Linux { + switch runtime.compiler_os { + case .Linux { onyx_cmd = "./bin/onyx"; if settings.debug do onyx_cmd = "./bin/onyx-debug"; } - case runtime.OS_Windows do onyx_cmd = "onyx.exe"; + case .Windows do onyx_cmd = "onyx.exe"; } cases := array.make(Test_Case, capacity=256); diff --git a/src/builtins.c b/src/builtins.c index b1ded77d..ec6f217d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -474,8 +474,16 @@ void initialize_builtins(bh_allocator a) { void introduce_build_options(bh_allocator a) { Package* p = package_lookup_or_create("runtime", context.global_scope, a); + AstType* Runtime_Type = (AstType *) symbol_raw_resolve(p->scope, "Runtime"); + if (Runtime_Type == NULL) { + onyx_report_error((OnyxFilePos) {0}, "'Runtime' type not found in package runtime."); + return; + } + AstNumLit* runtime_type = make_int_literal(a, context.options->runtime); - symbol_builtin_introduce(p->scope, "Runtime", (AstNode *) runtime_type); + runtime_type->type_node = Runtime_Type; + add_entities_for_node(NULL, (AstNode *) runtime_type, NULL, NULL); + symbol_builtin_introduce(p->scope, "runtime", (AstNode *) runtime_type); AstNumLit* multi_threaded = make_int_literal(a, context.options->use_multi_threading); multi_threaded->type_node = (AstType *) &basic_type_bool; @@ -492,6 +500,15 @@ void introduce_build_options(bh_allocator a) { #ifdef _BH_WINDOWS os = 2; #endif + + AstType* OS_Type = (AstType *) symbol_raw_resolve(p->scope, "OS"); + if (OS_Type == NULL) { + onyx_report_error((OnyxFilePos) {0}, "'OS' type not found in package runtime."); + return; + } + AstNumLit* os_type = make_int_literal(a, os); - symbol_builtin_introduce(p->scope, "OS", (AstNode *) os_type); + os_type->type_node = OS_Type; + add_entities_for_node(NULL, (AstNode *) os_type, NULL, NULL); + symbol_builtin_introduce(p->scope, "compiler_os", (AstNode *) os_type); } diff --git a/src/checker.c b/src/checker.c index f9ffff11..8f25ee7e 100644 --- a/src/checker.c +++ b/src/checker.c @@ -743,6 +743,10 @@ CheckStatus check_binaryop_assignment(AstBinaryOp** pbinop) { // If a left operand has an unknown type, fill it in with the type of // the right hand side. if (binop->left->type == NULL) { + if (binop->left->type_node != NULL && binop->left->entity && binop->left->entity->state <= Entity_State_Check_Types) { + YIELD(binop->token->pos, "Waiting for type to be constructed on left hand side."); + } + resolve_expression_type(binop->right); Type* right_type = get_expression_type(binop->right); @@ -970,16 +974,6 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) { CHECK(expression, &binop->right); current_checking_level = current_checking_level_store; - if ((binop->left->flags & Ast_Flag_Comptime) && (binop->right->flags & Ast_Flag_Comptime)) { - binop->flags |= Ast_Flag_Comptime; - } - - if (expression_types_must_be_known) { - if (binop->left->type == NULL || binop->right->type == NULL) { - ERROR(binop->token->pos, "Internal compiler error: one of the operands types is unknown here."); - } - } - // :UnaryFieldAccessIsGross if (binop->left->kind == Ast_Kind_Unary_Field_Access || binop->right->kind == Ast_Kind_Unary_Field_Access) { TYPE_CHECK(&binop->left, binop->right->type) { @@ -989,6 +983,16 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) { } } } + + if ((binop->left->flags & Ast_Flag_Comptime) && (binop->right->flags & Ast_Flag_Comptime)) { + binop->flags |= Ast_Flag_Comptime; + } + + if (expression_types_must_be_known) { + if (binop->left->type == NULL || binop->right->type == NULL) { + ERROR(binop->token->pos, "Internal compiler error: one of the operands types is unknown here."); + } + } // NOTE: Try operator overloading before checking everything else. if ((binop->left->type != NULL && binop->left->type->kind != Type_Kind_Basic) @@ -2245,6 +2249,9 @@ CheckStatus check_memres_type(AstMemRes* memres) { } CheckStatus check_memres(AstMemRes* memres) { + assert(memres->type_entity); + if (memres->type_entity->state < Entity_State_Code_Gen) YIELD(memres->token->pos, "Waiting for global to pass type construction."); + if (memres->initial_value != NULL) { if (memres->threadlocal) { onyx_report_error(memres->token->pos, "'#thread_local' variables cannot have an initializer at the moment."); @@ -2368,8 +2375,8 @@ CheckStatus check_type(AstType* type) { CheckStatus check_static_if(AstIf* static_if) { expression_types_must_be_known = 1; CheckStatus result = check_expression(&static_if->cond); - if (result == Check_Yield_Macro) return Check_Yield_Macro; expression_types_must_be_known = 0; + if (result == Check_Yield_Macro) return Check_Yield_Macro; if (result > Check_Errors_Start || !(static_if->cond->flags & Ast_Flag_Comptime)) { ERROR(static_if->token->pos, "Expected this condition to be compile time known."); diff --git a/src/entities.c b/src/entities.c index 172e8099..f58da9fc 100644 --- a/src/entities.c +++ b/src/entities.c @@ -293,6 +293,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ent.type = Entity_Type_Memory_Reservation_Type; ent.mem_res = (AstMemRes *) node; ENTITY_INSERT(ent); + ((AstMemRes *) node)->type_entity = entity; ent.id = entities->next_id++; ent.type = Entity_Type_Memory_Reservation; diff --git a/src/onyx.c b/src/onyx.c index d091f884..60327a1a 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -251,6 +251,13 @@ static void context_init(CompileOptions* opts) { .package = NULL, .include = create_load(context.ast_alloc, "core/type_info/type_info"), })); + + entity_heap_insert(&context.entities, ((Entity) { + .state = Entity_State_Parse_Builtin, + .type = Entity_Type_Load_File, + .package = NULL, + .include = create_load(context.ast_alloc, "core/runtime/build_opts"), + })); add_entities_for_node(NULL, (AstNode *) &builtin_stack_top, context.global_scope, NULL); add_entities_for_node(NULL, (AstNode *) &builtin_tls_base, context.global_scope, NULL); diff --git a/tests/caller_location.onyx b/tests/caller_location.onyx index ec628d09..be91947a 100644 --- a/tests/caller_location.onyx +++ b/tests/caller_location.onyx @@ -4,7 +4,7 @@ use package core using_callsite :: (value: $T, site := #callsite) { println(value); - path := string.split(site.file, ~~(#char "\\" if runtime.OS == runtime.OS_Windows else #char "/")); + path := string.split(site.file, ~~(#char "\\" if runtime.compiler_os == .Windows else #char "/")); printf("I was called from {}:{}:{}\n", path[path.count - 1], site.line, site.column); }