fix: propagate contextual compile-time execution

This commit is contained in:
2026-11-01 18:31:50 +01:00
parent 1f457d6b41
commit 22b40d3718
6 changed files with 836 additions and 46 deletions
+14 -22
View File
@@ -251,13 +251,10 @@ FormatToken :: struct {
@hide:file
parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
tokens [N]mut FormatToken := undefined
for (usize(0)..N) |index|
tokens[index] = FormatToken{ kind = .unused, start = 0, end = 0, field = "" }
mem.set(FormatToken, tokens[..], FormatToken{ kind = .unused, start = 0, end = 0, field = "" })
# retained metadata makes parsing constant-input execution, including guarded errors.
info :: typeinfo!(Args)
field_count := usize(0)
match info {
field_count := 0
match typeinfo!(Args) {
.record |r|: {
if (!r.is_tuple) compile_error!("io.print arguments must be a tuple")
field_count = r.fields.len
@@ -265,10 +262,10 @@ parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
else: compile_error!("io.print arguments must be a tuple")
}
token_count := usize(0)
argument_count := usize(0)
literal_start := usize(0)
cursor := usize(0)
token_count := 0
argument_count := 0
literal_start := 0
cursor := 0
while cursor < format.len {
byte :: format[cursor]
if byte == '{' {
@@ -297,7 +294,7 @@ parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
}
kind FormatTokenKind := .default
width := usize(2)
width := 2
if next != '}' {
if (cursor + 2 >= format.len or format[cursor + 2] != '}') compile_error!("io.print format expects a one-character specifier")
@@ -370,12 +367,7 @@ parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
@hide:file
format_field_name proc($T type, index usize) []u8 {
match typeinfo!(T) {
.record |r|: {
inline for r.fields |field| {
if (index == field.index) return field.name
}
unreachable
}
.record |r|: return r.fields[index].name
else: compile_error!("io.print arguments must be a tuple")
}
}
@@ -410,7 +402,7 @@ write_integer proc(
} else {
try write_integer_unsigned(output, u64(value), base, uppercase)
}
.distinct |backing|: if $(scalar_or_distinct_type(backing)) {
.distinct |backing|: if scalar_or_distinct_type(backing) {
try write_integer(output, distinct_value(backing, T, value), base, uppercase)
} else {
compile_error!("io.print integer format requires an integer argument")
@@ -437,7 +429,7 @@ write_float proc($T type, output Writer, value T, scientific bool) void ! WriteE
if (count < 0 or usize(count) >= buffer.len) return .write_failed
try write_all(output, buffer[0..usize(count)])
}
.distinct |backing|: if $(scalar_or_distinct_type(backing)) {
.distinct |backing|: if scalar_or_distinct_type(backing) {
try write_float(output, distinct_value(backing, T, value), scientific)
} else {
compile_error!("io.print float format requires a float argument")
@@ -451,7 +443,7 @@ write_decimal proc($T type, output Writer, value T) void ! WriteError {
match typeinfo!(T) {
.integer: try write_integer(output, value, 10, false)
.float: try write_float(output, value, false)
.distinct |backing|: if $(scalar_or_distinct_type(backing)) {
.distinct |backing|: if scalar_or_distinct_type(backing) {
try write_decimal(output, distinct_value(backing, T, value))
} else {
compile_error!("io.print '{d}' requires an integer or float argument")
@@ -468,7 +460,7 @@ write_character proc($T type, output Writer, value T) void ! WriteError {
buffer [1]u8 :: [u8(value)]
try write_all(output, buffer[..])
}
.distinct |backing|: if $(scalar_or_distinct_type(backing)) {
.distinct |backing|: if scalar_or_distinct_type(backing) {
try write_character(output, distinct_value(backing, T, value))
} else {
compile_error!("io.print '{c}' requires an unsigned integer that fits in u8")
@@ -500,7 +492,7 @@ write_default proc($T type, output Writer, value T) void ! WriteError {
}
return .write_failed
}
.distinct |backing|: if $(scalar_or_distinct_type(backing)) {
.distinct |backing|: if scalar_or_distinct_type(backing) {
try write_default(output, distinct_value(backing, T, value))
} else {
compile_error!("io.print '{}' does not support this argument type")