// 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 {
}
}
+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;
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;
}
}
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);