mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Add types.odin; Begin work on map
This commit is contained in:
+5
-1
@@ -11,7 +11,11 @@
|
|||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
T0 :: struct #align 8 {};
|
Value :: type f32;
|
||||||
|
m0: map[int]Value;
|
||||||
|
m1: map[string]Value;
|
||||||
|
m2: map[f32]Value;
|
||||||
|
// fm: map[128, int]f32;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#import "fmt.odin";
|
#import "fmt.odin";
|
||||||
#import "mem.odin";
|
#import "mem.odin";
|
||||||
#import "utf8.odin";
|
#import "utf8.odin";
|
||||||
|
#import "hash.odin";
|
||||||
|
|
||||||
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
|
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
|
||||||
// #shared_global_scope due to the internals of the compiler.
|
// #shared_global_scope due to the internals of the compiler.
|
||||||
@@ -346,6 +347,16 @@ Raw_Dynamic_Array :: struct #ordered {
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Raw_Dynamic_Map :: struct #ordered {
|
||||||
|
hashes: [dynamic]int,
|
||||||
|
entries: Raw_Dynamic_Array,
|
||||||
|
};
|
||||||
|
|
||||||
|
__default_hash :: proc(data: rawptr, len: int) -> u64 {
|
||||||
|
return hash.murmur64(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capacity: int) -> bool {
|
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capacity: int) -> bool {
|
||||||
array := cast(^Raw_Dynamic_Array)array_;
|
array := cast(^Raw_Dynamic_Array)array_;
|
||||||
|
|
||||||
@@ -398,3 +409,4 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
|||||||
array.count += item_count;
|
array.count += item_count;
|
||||||
return array.count;
|
return array.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+54
-1
@@ -50,13 +50,66 @@ fnv32a :: proc(data: rawptr, len: int) -> u32 {
|
|||||||
fnv64a :: proc(data: rawptr, len: int) -> u64 {
|
fnv64a :: proc(data: rawptr, len: int) -> u64 {
|
||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
|
|
||||||
h :u64 = 0xcbf29ce484222325;
|
h: u64 = 0xcbf29ce484222325;
|
||||||
for i in 0..<len {
|
for i in 0..<len {
|
||||||
h = (h ~ cast(u64)s[i]) * 0x100000001b3;
|
h = (h ~ cast(u64)s[i]) * 0x100000001b3;
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
murmur32 :: proc(data: rawptr, len: int) -> u32 {
|
||||||
|
compile_assert(ODIN_ENDIAN == "little");
|
||||||
|
|
||||||
|
SEED :: 0x9747b28c;
|
||||||
|
|
||||||
|
key := cast(^u8)data;
|
||||||
|
h: u32 = SEED;
|
||||||
|
|
||||||
|
if len > 3 {
|
||||||
|
key_x4 := cast(^u32)key;
|
||||||
|
i := len>>2;
|
||||||
|
for {
|
||||||
|
k := key_x4^; key_x4 += 1;
|
||||||
|
k *= 0xcc9e2d51;
|
||||||
|
k = (k << 15) | (k >> 17);
|
||||||
|
k *= 0x1b873593;
|
||||||
|
h ~= k;
|
||||||
|
h = (h << 13) | (h >> 19);
|
||||||
|
h += (h << 2) + 0xe6546b64;
|
||||||
|
i -= 1;
|
||||||
|
if i == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key = cast(^u8)key_x4;
|
||||||
|
}
|
||||||
|
if len&3 != 0 {
|
||||||
|
i := len&3;
|
||||||
|
k: u32 = 0;
|
||||||
|
key += i-1;
|
||||||
|
for {
|
||||||
|
k <<= 8;
|
||||||
|
k |= cast(u32)key^;
|
||||||
|
key -= 1;
|
||||||
|
i -= 1;
|
||||||
|
if i == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k *= 0xcc9e2d51;
|
||||||
|
k = (k << 15) | (k >> 17);
|
||||||
|
k *= 0x1b873593;
|
||||||
|
h ~= k;
|
||||||
|
}
|
||||||
|
|
||||||
|
h ~= cast(u32)len;
|
||||||
|
h ~= h >> 16;
|
||||||
|
h *= 0x85ebca6b;
|
||||||
|
h ~= h >> 13;
|
||||||
|
h *= 0xc2b2ae35;
|
||||||
|
h ~= h >> 16;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
murmur64 :: proc(data_: rawptr, len: int) -> u64 {
|
murmur64 :: proc(data_: rawptr, len: int) -> u64 {
|
||||||
SEED :: 0x9747b28c;
|
SEED :: 0x9747b28c;
|
||||||
|
|||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
is_signed :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if is_integer(info) {
|
||||||
|
i := cast(^Type_Info.Integer)info;
|
||||||
|
return i.signed;
|
||||||
|
}
|
||||||
|
if is_float(info) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_integer :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Integer: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_float :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Float: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_any :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Any: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_string :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.String: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Boolean: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_pointer :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Pointer: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_maybe :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Maybe: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Procedure: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_array :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Array: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Dynamic_Array: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_slice :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Slice: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_vector :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Vector: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Tuple: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_struct :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Struct: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_union :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Union: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Raw_Union: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_enum :: proc(info: ^Type_Info) -> bool {
|
||||||
|
if info == nil { return false; }
|
||||||
|
|
||||||
|
match type i in type_info_base(info) {
|
||||||
|
case Type_Info.Enum: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
typedef struct BuildContext {
|
typedef struct BuildContext {
|
||||||
String ODIN_OS; // target operating system
|
String ODIN_OS; // target operating system
|
||||||
String ODIN_ARCH; // target architecture
|
String ODIN_ARCH; // target architecture
|
||||||
|
String ODIN_ENDIAN; // target endian
|
||||||
String ODIN_VENDOR; // compiler vendor
|
String ODIN_VENDOR; // compiler vendor
|
||||||
String ODIN_VERSION; // compiler version
|
String ODIN_VERSION; // compiler version
|
||||||
String ODIN_ROOT; // Odin ROOT
|
String ODIN_ROOT; // Odin ROOT
|
||||||
@@ -243,9 +244,11 @@ void init_build_context(BuildContext *bc) {
|
|||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
bc->ODIN_OS = str_lit("windows");
|
bc->ODIN_OS = str_lit("windows");
|
||||||
bc->ODIN_ARCH = str_lit("amd64");
|
bc->ODIN_ARCH = str_lit("amd64");
|
||||||
|
bc->ODIN_ENDIAN = str_lit("little");
|
||||||
#elif defined(GB_SYSTEM_OSX)
|
#elif defined(GB_SYSTEM_OSX)
|
||||||
bc->ODIN_OS = str_lit("osx");
|
bc->ODIN_OS = str_lit("osx");
|
||||||
bc->ODIN_ARCH = str_lit("amd64");
|
bc->ODIN_ARCH = str_lit("amd64");
|
||||||
|
bc->ODIN_ENDIAN = str_lit("little");
|
||||||
#else
|
#else
|
||||||
#error Implement system
|
#error Implement system
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+82
-11
File diff suppressed because one or more lines are too long
@@ -28,6 +28,7 @@ typedef enum BuiltinProcId {
|
|||||||
BuiltinProc_free,
|
BuiltinProc_free,
|
||||||
|
|
||||||
BuiltinProc_reserve,
|
BuiltinProc_reserve,
|
||||||
|
BuiltinProc_clear,
|
||||||
BuiltinProc_append,
|
BuiltinProc_append,
|
||||||
|
|
||||||
BuiltinProc_size_of,
|
BuiltinProc_size_of,
|
||||||
@@ -69,6 +70,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
|||||||
{STR_LIT("free"), 1, false, Expr_Stmt},
|
{STR_LIT("free"), 1, false, Expr_Stmt},
|
||||||
|
|
||||||
{STR_LIT("reserve"), 2, false, Expr_Stmt},
|
{STR_LIT("reserve"), 2, false, Expr_Stmt},
|
||||||
|
{STR_LIT("clear"), 1, false, Expr_Stmt},
|
||||||
{STR_LIT("append"), 1, true, Expr_Expr},
|
{STR_LIT("append"), 1, true, Expr_Expr},
|
||||||
|
|
||||||
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
||||||
@@ -610,6 +612,7 @@ void init_universal_scope(BuildContext *bc) {
|
|||||||
// TODO(bill): Set through flags in the compiler
|
// TODO(bill): Set through flags in the compiler
|
||||||
add_global_string_constant(a, str_lit("ODIN_OS"), bc->ODIN_OS);
|
add_global_string_constant(a, str_lit("ODIN_OS"), bc->ODIN_OS);
|
||||||
add_global_string_constant(a, str_lit("ODIN_ARCH"), bc->ODIN_ARCH);
|
add_global_string_constant(a, str_lit("ODIN_ARCH"), bc->ODIN_ARCH);
|
||||||
|
add_global_string_constant(a, str_lit("ODIN_ENDIAN"), bc->ODIN_ENDIAN);
|
||||||
add_global_string_constant(a, str_lit("ODIN_VENDOR"), bc->ODIN_VENDOR);
|
add_global_string_constant(a, str_lit("ODIN_VENDOR"), bc->ODIN_VENDOR);
|
||||||
add_global_string_constant(a, str_lit("ODIN_VERSION"), bc->ODIN_VERSION);
|
add_global_string_constant(a, str_lit("ODIN_VERSION"), bc->ODIN_VERSION);
|
||||||
add_global_string_constant(a, str_lit("ODIN_ROOT"), bc->ODIN_ROOT);
|
add_global_string_constant(a, str_lit("ODIN_ROOT"), bc->ODIN_ROOT);
|
||||||
@@ -1141,6 +1144,11 @@ void init_preload(Checker *c) {
|
|||||||
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t_raw_dynamic_array == NULL) {
|
||||||
|
Entity *e = find_core_entity(c, str_lit("Raw_Dynamic_Array"));
|
||||||
|
t_raw_dynamic_array = e->type;
|
||||||
|
}
|
||||||
|
|
||||||
c->done_preload = true;
|
c->done_preload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2987,6 +2987,14 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|||||||
return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4);
|
return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case BuiltinProc_clear: {
|
||||||
|
ir_emit_comment(proc, str_lit("reserve"));
|
||||||
|
irValue *array_ptr = ir_build_expr(proc, ce->args.e[0]);
|
||||||
|
irValue *count_ptr = ir_emit_struct_ep(proc, array_ptr, 1);
|
||||||
|
ir_emit_store(proc, count_ptr, v_zero);
|
||||||
|
return NULL;
|
||||||
|
} break;
|
||||||
|
|
||||||
case BuiltinProc_append: {
|
case BuiltinProc_append: {
|
||||||
ir_emit_comment(proc, str_lit("append"));
|
ir_emit_comment(proc, str_lit("append"));
|
||||||
gbAllocator a = proc->module->allocator;
|
gbAllocator a = proc->module->allocator;
|
||||||
|
|||||||
@@ -292,6 +292,18 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
}
|
}
|
||||||
ir_fprintf(f, ")*");
|
ir_fprintf(f, ")*");
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
|
case Type_Map: {
|
||||||
|
if (t->Map.count > 0) {
|
||||||
|
// ir_fprintf(f, "void");
|
||||||
|
} else {
|
||||||
|
ir_fprintf(f, "{");
|
||||||
|
ir_print_type(f, m, t_raw_dynamic_array);
|
||||||
|
ir_fprintf(f, ", ");
|
||||||
|
ir_print_type(f, m, t_raw_dynamic_array);
|
||||||
|
ir_fprintf(f, "}");
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+112
-27
@@ -95,35 +95,40 @@ typedef struct TypeRecord {
|
|||||||
Entity * enum_max_value;
|
Entity * enum_max_value;
|
||||||
} TypeRecord;
|
} TypeRecord;
|
||||||
|
|
||||||
#define TYPE_KINDS \
|
#define TYPE_KINDS \
|
||||||
TYPE_KIND(Basic, BasicType) \
|
TYPE_KIND(Basic, BasicType) \
|
||||||
TYPE_KIND(Pointer, struct { Type *elem; }) \
|
TYPE_KIND(Pointer, struct { Type *elem; }) \
|
||||||
TYPE_KIND(Array, struct { Type *elem; i64 count; }) \
|
TYPE_KIND(Array, struct { Type *elem; i64 count; }) \
|
||||||
TYPE_KIND(DynamicArray, struct { Type *elem; }) \
|
TYPE_KIND(DynamicArray, struct { Type *elem; }) \
|
||||||
TYPE_KIND(Vector, struct { Type *elem; i64 count; }) \
|
TYPE_KIND(Vector, struct { Type *elem; i64 count; }) \
|
||||||
TYPE_KIND(Slice, struct { Type *elem; }) \
|
TYPE_KIND(Slice, struct { Type *elem; }) \
|
||||||
TYPE_KIND(Maybe, struct { Type *elem; }) \
|
TYPE_KIND(Maybe, struct { Type *elem; }) \
|
||||||
TYPE_KIND(Record, TypeRecord) \
|
TYPE_KIND(Record, TypeRecord) \
|
||||||
TYPE_KIND(Named, struct { \
|
TYPE_KIND(Named, struct { \
|
||||||
String name; \
|
String name; \
|
||||||
Type * base; \
|
Type * base; \
|
||||||
Entity *type_name; /* Entity_TypeName */ \
|
Entity *type_name; /* Entity_TypeName */ \
|
||||||
}) \
|
}) \
|
||||||
TYPE_KIND(Tuple, struct { \
|
TYPE_KIND(Tuple, struct { \
|
||||||
Entity **variables; /* Entity_Variable */ \
|
Entity **variables; /* Entity_Variable */ \
|
||||||
i32 variable_count; \
|
i32 variable_count; \
|
||||||
bool are_offsets_set; \
|
bool are_offsets_set; \
|
||||||
i64 * offsets; \
|
i64 * offsets; \
|
||||||
}) \
|
}) \
|
||||||
TYPE_KIND(Proc, struct { \
|
TYPE_KIND(Proc, struct { \
|
||||||
Scope *scope; \
|
Scope *scope; \
|
||||||
Type * params; /* Type_Tuple */ \
|
Type * params; /* Type_Tuple */ \
|
||||||
Type * results; /* Type_Tuple */ \
|
Type * results; /* Type_Tuple */ \
|
||||||
i32 param_count; \
|
i32 param_count; \
|
||||||
i32 result_count; \
|
i32 result_count; \
|
||||||
bool variadic; \
|
bool variadic; \
|
||||||
ProcCallingConvention calling_convention; \
|
ProcCallingConvention calling_convention; \
|
||||||
})
|
}) \
|
||||||
|
TYPE_KIND(Map, struct { \
|
||||||
|
i64 count; /* 0 if dynamic */ \
|
||||||
|
Type *key; \
|
||||||
|
Type *value; \
|
||||||
|
}) \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -319,6 +324,7 @@ gb_global Type *t_allocator_ptr = NULL;
|
|||||||
gb_global Type *t_context = NULL;
|
gb_global Type *t_context = NULL;
|
||||||
gb_global Type *t_context_ptr = NULL;
|
gb_global Type *t_context_ptr = NULL;
|
||||||
|
|
||||||
|
gb_global Type *t_raw_dynamic_array = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -477,6 +483,23 @@ Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_coun
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_type_valid_for_keys(Type *t);
|
||||||
|
|
||||||
|
Type *make_type_map(gbAllocator a, i64 count, Type *key, Type *value) {
|
||||||
|
Type *t = alloc_type(a, Type_Map);
|
||||||
|
if (key != NULL) {
|
||||||
|
GB_ASSERT(is_type_valid_for_keys(key));
|
||||||
|
}
|
||||||
|
t->Map.count = count;
|
||||||
|
t->Map.key = key;
|
||||||
|
t->Map.value = value;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Type *type_deref(Type *t) {
|
Type *type_deref(Type *t) {
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
@@ -679,6 +702,21 @@ bool is_type_enum(Type *t) {
|
|||||||
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum);
|
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_type_map(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
return t->kind == Type_Map;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_type_fixed_map(Type *t) {
|
||||||
|
t = base_type(t);
|
||||||
|
return t->kind == Type_Map && t->Map.count > 0;
|
||||||
|
}
|
||||||
|
bool is_type_dynamic_map(Type *t) {
|
||||||
|
t = base_type(t); return t->kind == Type_Map && t->Map.count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool is_type_any(Type *t) {
|
bool is_type_any(Type *t) {
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
@@ -691,6 +729,28 @@ bool is_type_untyped_nil(Type *t) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool is_type_valid_for_keys(Type *t) {
|
||||||
|
t = base_type(base_enum_type(t));
|
||||||
|
if (is_type_untyped(t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_type_integer(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (is_type_float(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (is_type_string(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (is_type_pointer(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_type_indexable(Type *t) {
|
bool is_type_indexable(Type *t) {
|
||||||
return is_type_array(t) || is_type_slice(t) || is_type_vector(t) || is_type_string(t);
|
return is_type_array(t) || is_type_slice(t) || is_type_vector(t) || is_type_string(t);
|
||||||
}
|
}
|
||||||
@@ -1458,6 +1518,14 @@ i64 type_align_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, Type
|
|||||||
return align;
|
return align;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Type_Map: {
|
||||||
|
if (t->Map.count == 0) { // Dynamic
|
||||||
|
// NOTE(bill): same as a dynamic array
|
||||||
|
return s.word_size;
|
||||||
|
}
|
||||||
|
GB_PANIC("TODO(bill): Fixed map alignment");
|
||||||
|
} break;
|
||||||
|
|
||||||
case Type_Record: {
|
case Type_Record: {
|
||||||
switch (t->Record.kind) {
|
switch (t->Record.kind) {
|
||||||
case TypeRecord_Struct:
|
case TypeRecord_Struct:
|
||||||
@@ -1667,6 +1735,14 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP
|
|||||||
return align_formula(size, align);
|
return align_formula(size, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Type_Map: {
|
||||||
|
if (t->Map.count == 0) { // Dynamic
|
||||||
|
// NOTE(bill): same as a two dynamic arrays
|
||||||
|
return 2 * type_size_of_internal(s, allocator, t_raw_dynamic_array, path);
|
||||||
|
}
|
||||||
|
GB_PANIC("TODO(bill): Fixed map size");
|
||||||
|
}
|
||||||
|
|
||||||
case Type_Tuple: {
|
case Type_Tuple: {
|
||||||
i64 count, align, size;
|
i64 count, align, size;
|
||||||
count = t->Tuple.variable_count;
|
count = t->Tuple.variable_count;
|
||||||
@@ -1924,6 +2000,15 @@ gbString write_type_to_string(gbString str, Type *type) {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Type_Map: {
|
||||||
|
str = gb_string_appendc(str, "map[");
|
||||||
|
if (type->Map.count > 0) {
|
||||||
|
str = gb_string_appendc(str, gb_bprintf("%lld, ", type->Map.count));
|
||||||
|
}
|
||||||
|
str = write_type_to_string(str, type->Map.key);
|
||||||
|
str = gb_string_appendc(str, "]");
|
||||||
|
str = write_type_to_string(str, type->Map.value);
|
||||||
|
} break;
|
||||||
|
|
||||||
case Type_Named:
|
case Type_Named:
|
||||||
if (type->Named.type_name != NULL) {
|
if (type->Named.type_name != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user