made enums behave better with static ifs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 31 Dec 2021 18:05:23 +0000 (12:05 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 31 Dec 2021 18:05:23 +0000 (12:05 -0600)
20 files changed:
core/builtin.onyx
core/os/os.onyx
core/os/process.onyx
core/runtime/build_opts.onyx
core/std.onyx
core/stdio.onyx
core/wasi/clock.onyx
core/wasi/env.onyx
core/wasi/wasi_fs.onyx
include/astnodes.h
misc/vscode/onyx-0.0.2.vsix
misc/vscode/out/extension.js
misc/vscode/syntaxes/onyx.tmLanguage
modules/webgl2/webgl2.onyx
scripts/run_tests.onyx
src/builtins.c
src/checker.c
src/entities.c
src/onyx.c
tests/caller_location.onyx

index f1a674ff69532850ec1d7f3a09a609bb5e1f56b4..5bdb96417001a30855fac029ce5320a2c8d27659 100644 (file)
@@ -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 }
 
index 23c77f80cef936f4a9890654984229099057e7e9..c5aacf79f8e9bc3bf903ed373ed2e4b2a01037d8 100644 (file)
@@ -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."
 }
 
index 5f66ab4ab0f0a9fef3b74dc80322f172c5220ba5..761865684252f56b4c072b61b1a686926884eebb 100644 (file)
@@ -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.";
 }
 
index af42c69969e36f0a0bcb0b9462eefd8978cb9f75..1016bdb95b7d9915f5effc6e592a82e54a55489d 100644 (file)
@@ -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
index 91f67e4d47abb73bd852f3baca6adf82ecaa3a2a..e4db463608fd9fbc754b187960186b95925fe8ff 100644 (file)
@@ -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"
index edc821408752b704d35801d64cb4672a863204d5..6e7b19ff79172d1480f48ac556ee5ea44f2cd13a 100644 (file)
@@ -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."
 }
 
index e3dd70806a6c769e6800d3ec9403050a8285b076..468327f4ed211d5c5c4ca88ac9df12539c1a9d28 100644 (file)
@@ -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.";
 }
 
index 09dfa057d850a83d24da15dec9ae17d438acfc0c..7cd5b3bcfa681be8646ce48de1c1f62dfe39d221 100644 (file)
@@ -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.";
 }
 
index 501840a4fba755d538a90acbebb73c828a73209a..7c7c2f6a3c8b4dc62af07187af05add3ab902c0c 100644 (file)
@@ -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."
 }
 
index 04c18923476bb781d74958221043d8e7bcd8b947..2bdbe97599b0a232763a30a2806abaf10d670e35 100644 (file)
@@ -962,6 +962,8 @@ struct AstMemRes        {
     u64 addr;
     AstTyped *initial_value;
 
+    struct Entity *type_entity;
+
     b32 threadlocal : 1;
 };
 struct AstGlobal        {
index 083a8045f0cc809bb5181150a00c68273e39d5e2..1802361b50f482a9e9d2987443d1e88bfd75c670 100644 (file)
Binary files a/misc/vscode/onyx-0.0.2.vsix and b/misc/vscode/onyx-0.0.2.vsix differ
index 3135afa353b02be44775ee8be3b032e6781c05d5..bec2b3fd035548f0a319bd167adc7617a2430e1c 100644 (file)
@@ -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) {
index 844d29126c18cc3d9489636d12685767f4e66627..1cd19c128dd4e7f1e79214faf5fa73c7ae1da412 100644 (file)
                                </dict>
                                <dict>
                                        <key>match</key>
-                                       <string>\b(void)\b</string>
+                                       <string>\b(void|rawptr)\b</string>
                                        <key>name</key>
                                        <string>storage.type.onyx</string>
                                </dict>
index 637bec2f414824ada24d0f17289784de0e154946..863cb225485460d1a5f51a5b18241044a74f7973 100644 (file)
@@ -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."
 }
 
index 01569939a8289be327550cdb7f08939fa9644d03..b36bf39d9da052700cc533b1412e9ca5c681f1a4 100644 (file)
@@ -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);
index b1ded77d1d02d82af4728ef9ce9bb4cf52177405..ec6f217d3e8c10699650ce3fb0262074bd4db8f6 100644 (file)
@@ -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);
 }
index f9ffff1132d2245f0eb8e9f7bbdea808efd09a39..8f25ee7efb8182849c9c742ea42fb4139975c136 100644 (file)
@@ -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.");
index 172e809990d7acbfe27998c9d25c9cbe2ecc0fd9..f58da9fcc1dd25216d8261c75f2ef90dafdbc907 100644 (file)
@@ -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;
index d091f884da1069ac767750c85cfe791370a6b20f..60327a1aeacccb1eb61370533eb87d0fcbbebe10 100644 (file)
@@ -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);
index ec628d098976f72624b3c13f0dec8942342f734c..be91947a580dcc73e306461a3ca64b3e9662d149 100644 (file)
@@ -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);
 }