From 73f68a9c5ed4c8139cc1c4f7695da29e5a3fb4c8 Mon Sep 17 00:00:00 2001 From: lemon Date: Tue, 16 Aug 2022 05:28:18 +0200 Subject: stuff --- src/type.cff | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/type.cff') diff --git a/src/type.cff b/src/type.cff index 33d78e6..97fc44a 100644 --- a/src/type.cff +++ b/src/type.cff @@ -136,3 +136,50 @@ extern fn putprimtypes(env *Env) void { ) ty_voidptr = interntype({ .size: g_targ.ptrsize, .u: :Ptr ty_void }); } + +extern fn isnumtype(ty *const Type) bool { + return ty->is(:Int) or ty->is(:Flo); +} + +fn numtype2rank(ty *const Type) int { + ty = unconstify(ty); + switch { + case ty->is(:Int) and (ty == ty_int or ty.size < ty_int.size); + return 0; + case ty == ty_uint; return 1; + case ty == ty_i32; return 2; + case ty == ty_u32; return 3; + case ty == ty_i64; return 4; + case ty == ty_u64; return 5; + case ty == ty_f32; return 6; + case ty == ty_f64; return 7; + } + return -1; +} + +fn rank2numtype(r int) *const Type { + static const types []**const Type = { + &ty_int, &ty_uint, &ty_i32, &ty_u32, + &ty_i64, &ty_u64, &ty_f32, &ty_f64, + }; + assert(r >= 0 and r < types.#len, "rank"); + return *types[r]; +} + +extern fn typeof2(a *const Type, b *const Type) *const Type { + if a == b and not a->is(:Int) { + return a; + } + if isnumtype(a) and isnumtype(b) { + let ra = numtype2rank(a), + rb = numtype2rank(b); + return rank2numtype(MAX(ra, rb)); + } + if unconstify(a) == b { + return a; + } + if a == unconstify(b) { + return b; + } + return #null; +} -- cgit v1.2.3