changed tag syntax; added runtime variant of 'new'
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Feb 2022 02:45:53 +0000 (20:45 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Feb 2022 02:45:53 +0000 (20:45 -0600)
core/builtin.onyx
core/type_info/helper.onyx
scripts/run_tests.onyx
src/parser.c

index 496ac64dad74f334966813d0726661a9a0649cef..3d22d7c076ea437a5190867652a22079ab6423c6 100644 (file)
@@ -136,15 +136,40 @@ 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 != .Custom {
-    new :: ($T: type_expr, allocator := context.allocator) -> ^T {
-        use package core.intrinsics.onyx { __initialize }
-        memory :: package core.memory
-
-        res := cast(^T) raw_alloc(allocator, sizeof T);
-        memory.set(res, 0, sizeof T);
-        __initialize(res);
-
-        return res;
+    new :: #match {
+        ($T: type_expr, allocator := context.allocator) -> ^T {
+            use package core.intrinsics.onyx { __initialize }
+            memory :: package core.memory
+
+            res := cast(^T) raw_alloc(allocator, sizeof T);
+            memory.set(res, 0, sizeof T);
+            __initialize(res);
+
+            return res;
+        },
+
+        (T: type_expr, allocator := context.allocator) -> rawptr {
+            memory :: package core.memory
+
+            info := type_info.get_type_info(T);
+            size := type_info.size_of(T);
+            if size == 0 do return null;
+
+            res := raw_alloc(allocator, size);
+            memory.set(res, 0, size);
+
+            if info.kind == .Struct {
+                s_info := cast(^type_info.Type_Info_Struct) info;
+                for s_info.members {
+                    if it.default != null {
+                        member_size := type_info.size_of(it.type);
+                        memory.copy(cast(^u8) res + it.offset, it.default, member_size);
+                    }
+                }
+            }
+
+            return res;
+        }
     }
 
     make :: ($T: type_expr, allocator := context.allocator) -> ^T {
index 358aeeb73094db9c86e2fadbc9705ed19963b859..6864278e7d9b70e68d3ec009a256f1076b6a49e5 100644 (file)
@@ -125,6 +125,63 @@ write_type_name :: (writer: ^io.Writer, t: type_expr) {
     }
 }
 
+size_of :: (t: type_expr) -> u32 {
+    info := get_type_info(t);
+    if info == null do return 0;
+
+    switch info.kind {
+        case .Basic {
+            basic := cast(^Type_Info_Basic) info;
+
+            switch basic.basic_kind {
+                case .Void do return 0;
+                case .Bool, .U8, .I8 do return 1;
+                case .U16, .I16 do return 2;
+                case .U32, .I32, .F32, .Type_Index do return 4;
+                case .U64, .I64, .F64 do return 8;
+                case .I8X16, .I16X8, .I32X4, .I64X2, .F32X4, .F64X2, .V128 do return 16;
+                case .Rawptr do return sizeof rawptr;
+
+                case .Unsized_Int do return 0;
+                case .Unsized_Float do return 0;
+            }
+        }
+
+        case .Pointer do return sizeof rawptr;
+
+        case .Array {
+            arr := cast(^Type_Info_Array) info;
+            return size_of(arr.of) * arr.count;
+        }
+
+        case .Slice do return sizeof str;
+        case .Dynamic_Array do return sizeof [..] void;
+        case .Variadic_Argument do return sizeof str;
+        case .Enum {
+            e := cast(^Type_Info_Enum) info;
+            return e.size;
+        }
+
+        case .Struct {
+            s := cast(^Type_Info_Struct) info;
+            return s.size;
+        }
+
+        case .Polymorphic_Struct do return 0;
+
+        case .Compound do return 0;
+
+        case .Function do return 4;
+
+        case .Distinct {
+            d := cast(^Type_Info_Distinct) info;
+            return size_of(d.base_type);
+        }
+    }
+
+    return 0;
+}
+
 offset_of :: (T: type_expr, member: str) -> u32 {
     info := get_type_info(T);
     if info == null         do return 0;
index c0490a79afe5c49405c9cf48d2c10cd70cdbe7d7..0df2023c4857a48b2d394bb77c0e22a62558aac4 100644 (file)
@@ -72,19 +72,19 @@ find_onyx_files :: (root: str, cases: ^[..] Test_Case) {
 settings := Settings.{};
 
 Settings :: struct {
-    ["--debug", "-d"]
+    #tag "--debug", "-d"
     debug := false;
 
-    ["--threads"]
+    #tag "--threads"
     threads := 4;
 
-    ["--no-color"]
+    #tag "--no-color"
     no_color := false;
 
-    ["--tests"]
+    #tag "--tests"
     test_folder := "./tests";
 
-    ["--compile-only"]
+    #tag "--compile-only"
     compile_only := false;
 }
 
index 5e96e892c5ac2b43c62d1bac2a15afe76a3802ee..342b55647ea9df9951c5583386ceff9d4bf4c368 100644 (file)
@@ -1988,20 +1988,13 @@ static AstStructType* parse_struct(OnyxParser* parser) {
         }
 
         bh_arr(AstTyped *) meta_tags=NULL;
-        while (parser->curr->type == '[') {
+        while (parse_possible_directive(parser, "tag")) {
             if (meta_tags == NULL) bh_arr_new(global_heap_allocator, meta_tags, 1);
 
-            expect_token(parser, '[');
-            while (parser->curr->type != ']') {
+            do {
                 AstTyped* expr = parse_expression(parser, 0);
                 bh_arr_push(meta_tags, expr);
-
-                if (parser->curr->type != ']') {
-                    expect_token(parser, ',');
-                }
-            }
-
-            expect_token(parser, ']');
+            } while (consume_token_if_next(parser, ','));
         }
 
         member_is_used = consume_token_if_next(parser, Token_Type_Keyword_Use);