refactor: precompute compiler enum mappings

This commit is contained in:
2026-10-30 10:10:43 +01:00
parent d7e637dc3b
commit 30a98db379
13 changed files with 452 additions and 279 deletions
+50 -34
View File
@@ -1,6 +1,7 @@
import "@std/mem"
import "@std/arraylist"
import "@std/debug"
import "@std/enummap"
import "@source/diagnostics"
FunctionId :: distinct u32
@@ -33,44 +34,51 @@ aggregate proc(type Type) bool {
return type == .array or type == .record
}
@hide:file
integer_widths :: $enummap.init_filled(Type, usize, usize(0), {
i8 = 8, u8 = 8,
i16 = 16, u16 = 16,
i32 = 32, u32 = 32,
int = 64, isize = 64, usize = 64, u64 = 64,
})
#! integer storage widths for the supported 64-bit target; zero for noninteger types.
integer_bits proc(type Type) usize {
return match type {
.i8, .u8: 8
.i16, .u16: 16
.i32, .u32: 32
.int, .isize, .usize, .u64: 64
else: 0
}
if (enummap.get(&integer_widths, type)) |width| return width
return 0
}
unsigned_integer proc(type Type) bool {
return type == .u8 or type == .u16 or type == .u32 or type == .u64 or type == .usize
}
@hide:file
integer_maxima :: $enummap.init_filled(Type, u64, u64(0), {
i8 = 127,
i16 = 32767,
i32 = 2147483647,
int = u64(maxval!(i64)), isize = u64(maxval!(i64)),
u8 = 255,
u16 = 65535,
u32 = 4294967295,
u64 = maxval!(u64), usize = maxval!(u64),
})
integer_max proc(type Type) u64 {
return match type {
.i8: 127
.i16: 32767
.i32: 2147483647
.int, .isize: u64(maxval!(i64))
.u8: 255
.u16: 65535
.u32: 4294967295
.u64, .usize: maxval!(u64)
else: unreachable
}
return enummap.get(&integer_maxima, type)?
}
@hide:file
integer_minima :: $enummap.init_filled(Type, i64, i64(0), {
i8 = i64(-128),
i16 = i64(-32768),
i32 = i64(-2147483648),
int = minval!(i64), isize = minval!(i64),
u8 = 0, u16 = 0, u32 = 0, u64 = 0, usize = 0,
})
integer_min proc(type Type) i64 {
return match type {
.i8: -128
.i16: -32768
.i32: -2147483648
.int, .isize: minval!(i64)
.u8, .u16, .u32, .u64, .usize: 0
else: unreachable
}
return enummap.get(&integer_minima, type)?
}
ValueData :: union {
@@ -412,24 +420,32 @@ aligned_size proc(size, alignment usize) usize {
return divtrunc!(size + alignment - 1, alignment) * alignment
}
@hide:file
scalar_alignments :: $enummap.init_filled(Type, usize, usize(1), {
float = 8, string = 8, function = 8, pointer = 8,
})
@hide:file
scalar_sizes :: $enummap.init_filled(Type, usize, usize(0), {
float = 8, function = 8, pointer = 8,
string = 16,
bool = 1,
void = 0,
})
storage_alignment proc(module @Module, type Type, shape ArrayId) usize {
if (aggregate(type)) return module.arrays.items[usize(shape)].alignment
bits :: integer_bits(type)
if (bits != 0) return divtrunc!(bits, 8)
return if (type == .float or type == .string or type == .function or type == .pointer) 8 else 1
if (enummap.get(&scalar_alignments, type)) |alignment| return alignment
return 1
}
storage_size proc(module @Module, type Type, shape ArrayId) usize {
if (aggregate(type)) return module.arrays.items[usize(shape)].byte_size
bits :: integer_bits(type)
if (bits != 0) return divtrunc!(bits, 8)
return match type {
.float, .function, .pointer: 8
.string: 16
.bool: 1
.void: 0
else: unreachable
}
return enummap.get(&scalar_sizes, type)?
}
#! loads a scalar or borrows an aggregate from byte cells without allocating.