Files
spl/stage2/utils/value.spl
T

101 lines
2.2 KiB
Plaintext

// Expect retcode = 0
// 显式装箱值:运行期格式化用的最小 ADT。调用方显式构造(如 Value.int(x)),
// 库内用 match 分派。不做隐式装箱、不带运行期类型系统。
// Str 借用 ByteView,不拥有存储;Ptr 是类型擦除指针。
type .{ .ByteView } = @import("byte_view.spl");
type Value = enum {
Int: i64,
Uint: u64,
Bool: bool,
Char: u8,
Str: ByteView,
Ptr: *any,
}
fn int(value: i64): Value {
ret .Int(value);
}
fn uint(value: u64): Value {
ret .Uint(value);
}
fn boolean(value: bool): Value {
ret .Bool(value);
}
fn char(value: u8): Value {
ret .Char(value);
}
fn str(bytes: []u8): Value {
ret .Str(ByteView.from_slice(bytes));
}
fn str_view(view: ByteView): Value {
ret .Str(view);
}
fn addr(value: *any): Value {
ret .Ptr(value);
}
// ---- 测试 ----
fn test_int_and_uint() {
match int(-5) {
.Int(v) => { @assert(v == -5, "int payload"); },
_ => { @assert(false, "expected int"); },
}
match uint(5) {
.Uint(v) => { @assert(v == 5, "uint payload"); },
_ => { @assert(false, "expected uint"); },
}
}
fn test_scalars() {
match boolean(true) {
.Bool(v) => { @assert(v, "bool payload"); },
_ => { @assert(false, "expected bool"); },
}
match char('A') {
.Char(v) => { @assert(v == 'A', "char payload"); },
_ => { @assert(false, "expected char"); },
}
}
fn test_borrowed_str() {
var text: [3]u8 = .[104, 105, 0];
var s = str(text[0..2]);
match s {
.Str(view) => {
@assert(view.len == 2 && view.ptr[0] == 104 && view.ptr[1] == 105,
"str payload borrows");
},
_ => { @assert(false, "expected str"); },
}
@assert(text[0] == 104, "source untouched");
}
fn test_ptr() {
var x: i32 = 7;
match addr(&x as *any) {
.Ptr(p) => { @assert((p as *i32).* == 7, "ptr payload"); },
_ => { @assert(false, "expected ptr"); },
}
match addr(null) {
.Ptr(p) => { @assert(p == null, "null ptr payload"); },
_ => { @assert(false, "expected ptr"); },
}
}
fn main() {
test_int_and_uint();
test_scalars();
test_borrowed_str();
test_ptr();
}