diff options
| author | 2022-08-15 12:22:47 +0200 | |
|---|---|---|
| committer | 2022-08-15 12:22:47 +0200 | |
| commit | f906d0b350b0b4ceb747669c9a9845d11bd0e486 (patch) | |
| tree | 5f09a7b714e6ce93f6094a06e5f736513110fb8d /src/type.cff | |
| parent | f802bb99263aaa5be492999babd44cd2fdb1c65f (diff) | |
self hosted progress
Diffstat (limited to 'src/type.cff')
| -rw-r--r-- | src/type.cff | 146 |
1 files changed, 126 insertions, 20 deletions
diff --git a/src/type.cff b/src/type.cff index a3c7021..33d78e6 100644 --- a/src/type.cff +++ b/src/type.cff @@ -1,32 +1,138 @@ import "cffc.hff"; import "util.hff"; +import "common.hff"; +import "set.hff"; -fn hashtype(ty *const Type) u32 { - let h = FNV1A_INI; - h = fnv1a_i(h, ty.konst ? 1 : 0); +struct TypeTraits { + fn hash(ty *const Type) u32 { + let h = FNV1A_INI; + h = fnv1a_i(h, as(int)ty.u.#tag); + h = fnv1a_i(h, ty.konst ? 1 : 0); - switch ty.u { - case Void; case Bool; + switch ty.u { + case Void; case Bool; - case Flo; - h = fnv1a_i(h, ty.size); - h = fnv1a_i(h, ty.align); + case Flo; + h = fnv1a_i(h, ty.size); - case Int i; - h = fnv1a_i(h, i.sgn ? 1 : 0); - h = fnv1a_i(h, ty.size); - h = fnv1a_i(h, ty.align); + case Int i; + h = fnv1a_i(h, i.sgn ? 1 : 0); + h = fnv1a_i(h, ty.size); - case Ptr child; - h = fnv1a_i(h, child.id); + case Ptr child; + h = fnv1a_i(h, child.id); - case Arr arr; - h = fnv1a_i(h, arr.child.id); - h = fnv1a_i(h, arr.length); + case Arr arr; + h = fnv1a_i(h, arr.child.id); + h = fnv1a_i(h, arr.length); - case Slice child; - h = fnv1a_i(h, child.id); + case Slice child; + h = fnv1a_i(h, child.id); + } + return h; } - return h; + + fn eq(a *const Type, b *const Type) bool { + if a.u.#tag != b.u.#tag or a.size != b.size + or a.align != b.align or a.konst != b.konst { + return #f; + } + switch a.u { + case Void; case Bool; case Flo; + case Int i; + return i.sgn == b.u.Int.sgn; + case Ptr child; + return child == b.u.Ptr; + case Arr arr; + let brr = b.u.Arr; + return arr.length == brr.length and arr.child == brr.child; + case Slice child; + return child == b.u.Slice; + case Fn f0; + let f1 = b.u.Fn; + if f0.variadic != f1.variadic { + return #f; + } + if f0.ret != f1.ret { + return #f; + } + if f0.params.#len != f1.params.#len { + return #f; + } + foreach(p, i, f0.params, + if p != f1.params[i] { + return #f; + } + ) + return #t; + } + return #f; + } + + fn dup(ty *const Type) *const Type { + let p *Type = xmalloc(sizeof Type); + static id int = 0; + *p = *ty; + p.id = id++; + return p; + } +} + +extern fn interntype(ty0 Type) *const Type { + static set Set<*const Type, TypeTraits> = {}; + + if ty0.align == 0 { + ty0.align = ty0.size; + } + + return *set->intern(&ty0); +} + +extern static ty_void *const Type = {}, + ty_bool *const Type = {}, + ty_i8 *const Type = {}, + ty_u8 *const Type = {}, + ty_i16 *const Type = {}, + ty_u16 *const Type = {}, + ty_i32 *const Type = {}, + ty_u32 *const Type = {}, + ty_int *const Type = {}, + ty_uint *const Type = {}, + ty_i64 *const Type = {}, + ty_u64 *const Type = {}, + ty_isize *const Type = {}, + ty_usize *const Type = {}, + ty_iptrint *const Type = {}, + ty_uptrint *const Type = {}, + ty_f32 *const Type = {}, + ty_f64 *const Type = {}, + ty_voidptr *const Type = {}; + +extern fn putprimtypes(env *Env) void { + let types []struct { name *const u8, gty **const Type, ty Type } = { + { "void", &ty_void, { .size: 0, .align: 1, .u: :Void }}, + { "bool", &ty_bool, { .size: 1, .align: 1, .u: :Bool }}, + { "f32", &ty_f32, { .size: 4, .u: :Flo }}, + { "f64", &ty_f64, { .size: 8, g_targ.f64align, .u: :Flo }}, + { "i8", &ty_i8, { .size: 1, .u: :Int { .sgn: #t }}}, + { "u8", &ty_u8, { .size: 1, .u: :Int { .sgn: #f }}}, + { "i16", &ty_i16, { .size: 2, .u: :Int { .sgn: #t }}}, + { "u16", &ty_u16, { .size: 2, .u: :Int { .sgn: #f }}}, + { "i32", &ty_i32, { .size: 4, .u: :Int { .sgn: #t }}}, + { "u32", &ty_u32, { .size: 4, .u: :Int { .sgn: #f }}}, + { "int", &ty_int, { g_targ.intsize, .u: :Int { .sgn: #t }}}, + { "uint", &ty_uint, { g_targ.intsize, .u: :Int { .sgn: #f }}}, + { "isize", &ty_isize,{ g_targ.sizesize, .u: :Int { .sgn: #t }}}, + { "usize", &ty_usize,{ g_targ.sizesize, .u: :Int { .sgn: #f }}}, + { "i64", &ty_i64, { .size: 8, g_targ.i64align, .u: :Int { .sgn: #t }}}, + { "u64", &ty_u64, { .size: 8, g_targ.i64align, .u: :Int { .sgn: #f }}}, + { "iptrint",&ty_iptrint, { g_targ.ptrsize, .u: :Int { .sgn: #t }}}, + { "uptrint",&ty_uptrint, { g_targ.ptrsize, .u: :Int { .sgn: #f }}}, + }; + + foreach(type, _, types[0::], + envput(env, { type.name, .u: :Ty (*type.gty = interntype(type.ty)) }, #null); + ) + ty_voidptr = interntype({ .size: g_targ.ptrsize, .u: :Ptr ty_void }); } |