lang: rename signed integer types sN -> iN
Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
This commit is contained in:
@@ -34,15 +34,15 @@ test "interpret: compute(5) = 25" {
|
||||
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// func compute(x: s64) -> s64 { return x * x; }
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "compute"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "compute"), params, .s64);
|
||||
// func compute(x: i64) -> i64 { return x * x; }
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "compute"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "compute"), params, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const x_ref = Ref.fromIndex(0);
|
||||
const result = b.mul(x_ref, x_ref, .s64);
|
||||
b.ret(result, .s64);
|
||||
const result = b.mul(x_ref, x_ref, .i64);
|
||||
b.ret(result, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -61,8 +61,8 @@ test "interpret: if/else branching" {
|
||||
|
||||
var b = Builder.init(&module);
|
||||
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "abs"), params, .s64);
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "abs"), params, .i64);
|
||||
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
const then_bb = b.appendBlock(str(&module, "then"), &.{});
|
||||
@@ -70,16 +70,16 @@ test "interpret: if/else branching" {
|
||||
|
||||
b.switchToBlock(entry);
|
||||
const x = Ref.fromIndex(0);
|
||||
const zero = b.constInt(0, .s64);
|
||||
const zero = b.constInt(0, .i64);
|
||||
const is_neg = b.cmpLt(x, zero);
|
||||
b.condBr(is_neg, then_bb, &.{}, else_bb, &.{});
|
||||
|
||||
b.switchToBlock(then_bb);
|
||||
const neg_x = b.emit(.{ .neg = .{ .operand = x } }, .s64);
|
||||
b.ret(neg_x, .s64);
|
||||
const neg_x = b.emit(.{ .neg = .{ .operand = x } }, .i64);
|
||||
b.ret(neg_x, .i64);
|
||||
|
||||
b.switchToBlock(else_bb);
|
||||
b.ret(x, .s64);
|
||||
b.ret(x, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -101,30 +101,30 @@ test "interpret: function calling another function" {
|
||||
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// func square(x: s64) -> s64 { return x * x; }
|
||||
const params_sq = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "square"), params_sq, .s64);
|
||||
// func square(x: i64) -> i64 { return x * x; }
|
||||
const params_sq = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "square"), params_sq, .i64);
|
||||
const entry1 = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry1);
|
||||
const x = Ref.fromIndex(0);
|
||||
const sq = b.mul(x, x, .s64);
|
||||
b.ret(sq, .s64);
|
||||
const sq = b.mul(x, x, .i64);
|
||||
b.ret(sq, .i64);
|
||||
b.finalize();
|
||||
|
||||
// func sum_of_squares(a, b) -> s64 { return square(a) + square(b); }
|
||||
// func sum_of_squares(a, b) -> i64 { return square(a) + square(b); }
|
||||
const params_ss = &[_]Function.Param{
|
||||
.{ .name = str(&module, "a"), .ty = .s64 },
|
||||
.{ .name = str(&module, "b"), .ty = .s64 },
|
||||
.{ .name = str(&module, "a"), .ty = .i64 },
|
||||
.{ .name = str(&module, "b"), .ty = .i64 },
|
||||
};
|
||||
_ = b.beginFunction(str(&module, "sum_of_squares"), params_ss, .s64);
|
||||
_ = b.beginFunction(str(&module, "sum_of_squares"), params_ss, .i64);
|
||||
const entry2 = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry2);
|
||||
const a = Ref.fromIndex(0);
|
||||
const b_param = Ref.fromIndex(1);
|
||||
const sq_a = b.call(FuncId.fromIndex(0), &.{a}, .s64);
|
||||
const sq_b = b.call(FuncId.fromIndex(0), &.{b_param}, .s64);
|
||||
const sum = b.add(sq_a, sq_b, .s64);
|
||||
b.ret(sum, .s64);
|
||||
const sq_a = b.call(FuncId.fromIndex(0), &.{a}, .i64);
|
||||
const sq_b = b.call(FuncId.fromIndex(0), &.{b_param}, .i64);
|
||||
const sum = b.add(sq_a, sq_b, .i64);
|
||||
b.ret(sum, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -143,19 +143,19 @@ test "interpret: alloca/store/load" {
|
||||
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "test"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "test"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const slot = b.alloca(.s64);
|
||||
const ten = b.constInt(10, .s64);
|
||||
const slot = b.alloca(.i64);
|
||||
const ten = b.constInt(10, .i64);
|
||||
b.store(slot, ten);
|
||||
const loaded = b.load(slot, .s64);
|
||||
const five = b.constInt(5, .s64);
|
||||
const sum = b.add(loaded, five, .s64);
|
||||
const loaded = b.load(slot, .i64);
|
||||
const five = b.constInt(5, .i64);
|
||||
const sum = b.add(loaded, five, .i64);
|
||||
b.store(slot, sum);
|
||||
const result = b.load(slot, .s64);
|
||||
b.ret(result, .s64);
|
||||
const result = b.load(slot, .i64);
|
||||
b.ret(result, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -168,7 +168,7 @@ test "interpret: alloca/store/load" {
|
||||
// ── Comptime parity tests ───────────────────────────────────────────────
|
||||
|
||||
// ── Test: while loop (sumOf10 from 15-while.sx) ─────────────────────────
|
||||
// sumOf10 :: () -> s32 { i:=1; s:=0; while i<=10 { s+=i; i+=1; } s; }
|
||||
// sumOf10 :: () -> i32 { i:=1; s:=0; while i<=10 { s+=i; i+=1; } s; }
|
||||
// Expected: 55
|
||||
|
||||
test "comptime: while loop — sumOf10 = 55" {
|
||||
@@ -179,7 +179,7 @@ test "comptime: while loop — sumOf10 = 55" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "sumOf10"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "sumOf10"), &.{}, .i64);
|
||||
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
const hdr = b.appendBlock(str(&module, "while.hdr"), &.{});
|
||||
@@ -188,37 +188,37 @@ test "comptime: while loop — sumOf10 = 55" {
|
||||
|
||||
// entry: i=1, s=0, br while.hdr
|
||||
b.switchToBlock(entry);
|
||||
const i_slot = b.alloca(.s64);
|
||||
const one = b.constInt(1, .s64);
|
||||
const i_slot = b.alloca(.i64);
|
||||
const one = b.constInt(1, .i64);
|
||||
b.store(i_slot, one);
|
||||
const s_slot = b.alloca(.s64);
|
||||
const zero = b.constInt(0, .s64);
|
||||
const s_slot = b.alloca(.i64);
|
||||
const zero = b.constInt(0, .i64);
|
||||
b.store(s_slot, zero);
|
||||
b.br(hdr, &.{});
|
||||
|
||||
// while.hdr: if i <= 10 → body, else → exit
|
||||
b.switchToBlock(hdr);
|
||||
const i_load = b.load(i_slot, .s64);
|
||||
const ten = b.constInt(10, .s64);
|
||||
const i_load = b.load(i_slot, .i64);
|
||||
const ten = b.constInt(10, .i64);
|
||||
const cond = b.emit(.{ .cmp_le = .{ .lhs = i_load, .rhs = ten } }, .bool);
|
||||
b.condBr(cond, body, &.{}, exit, &.{});
|
||||
|
||||
// while.body: s += i; i += 1; br while.hdr
|
||||
b.switchToBlock(body);
|
||||
const s_load = b.load(s_slot, .s64);
|
||||
const i_load2 = b.load(i_slot, .s64);
|
||||
const s_new = b.add(s_load, i_load2, .s64);
|
||||
const s_load = b.load(s_slot, .i64);
|
||||
const i_load2 = b.load(i_slot, .i64);
|
||||
const s_new = b.add(s_load, i_load2, .i64);
|
||||
b.store(s_slot, s_new);
|
||||
const i_load3 = b.load(i_slot, .s64);
|
||||
const one2 = b.constInt(1, .s64);
|
||||
const i_new = b.add(i_load3, one2, .s64);
|
||||
const i_load3 = b.load(i_slot, .i64);
|
||||
const one2 = b.constInt(1, .i64);
|
||||
const i_new = b.add(i_load3, one2, .i64);
|
||||
b.store(i_slot, i_new);
|
||||
b.br(hdr, &.{});
|
||||
|
||||
// while.exit: return s
|
||||
b.switchToBlock(exit);
|
||||
const s_final = b.load(s_slot, .s64);
|
||||
b.ret(s_final, .s64);
|
||||
const s_final = b.load(s_slot, .i64);
|
||||
b.ret(s_final, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -228,7 +228,7 @@ test "comptime: while loop — sumOf10 = 55" {
|
||||
}
|
||||
|
||||
// ── Test: optional coalesce (ct_sum from 32-optionals.sx) ────────────────
|
||||
// ct_sum :: () -> s32 { x:?s32=42; y:?s32=null; return (x??0)+(y??99); }
|
||||
// ct_sum :: () -> i32 { x:?i32=42; y:?i32=null; return (x??0)+(y??99); }
|
||||
// Expected: 42 + 99 = 141
|
||||
|
||||
test "comptime: optional coalesce — ct_sum = 141" {
|
||||
@@ -239,33 +239,33 @@ test "comptime: optional coalesce — ct_sum = 141" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "ct_sum"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "ct_sum"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
// x: ?s32 = 42 → alloca, store 42
|
||||
const x_slot = b.alloca(.s64);
|
||||
const forty_two = b.constInt(42, .s64);
|
||||
// x: ?i32 = 42 → alloca, store 42
|
||||
const x_slot = b.alloca(.i64);
|
||||
const forty_two = b.constInt(42, .i64);
|
||||
b.store(x_slot, forty_two);
|
||||
|
||||
// y: ?s32 = null → alloca, store null
|
||||
const y_slot = b.alloca(.s64);
|
||||
const null_val = b.constNull(.s64);
|
||||
// y: ?i32 = null → alloca, store null
|
||||
const y_slot = b.alloca(.i64);
|
||||
const null_val = b.constNull(.i64);
|
||||
b.store(y_slot, null_val);
|
||||
|
||||
// (x ?? 0)
|
||||
const x_load = b.load(x_slot, .s64);
|
||||
const zero = b.constInt(0, .s64);
|
||||
const x_coalesced = b.emit(.{ .optional_coalesce = .{ .lhs = x_load, .rhs = zero } }, .s64);
|
||||
const x_load = b.load(x_slot, .i64);
|
||||
const zero = b.constInt(0, .i64);
|
||||
const x_coalesced = b.emit(.{ .optional_coalesce = .{ .lhs = x_load, .rhs = zero } }, .i64);
|
||||
|
||||
// (y ?? 99)
|
||||
const y_load = b.load(y_slot, .s64);
|
||||
const ninety_nine = b.constInt(99, .s64);
|
||||
const y_coalesced = b.emit(.{ .optional_coalesce = .{ .lhs = y_load, .rhs = ninety_nine } }, .s64);
|
||||
const y_load = b.load(y_slot, .i64);
|
||||
const ninety_nine = b.constInt(99, .i64);
|
||||
const y_coalesced = b.emit(.{ .optional_coalesce = .{ .lhs = y_load, .rhs = ninety_nine } }, .i64);
|
||||
|
||||
// return x_coalesced + y_coalesced
|
||||
const sum = b.add(x_coalesced, y_coalesced, .s64);
|
||||
b.ret(sum, .s64);
|
||||
const sum = b.add(x_coalesced, y_coalesced, .i64);
|
||||
b.ret(sum, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -275,7 +275,7 @@ test "comptime: optional coalesce — ct_sum = 141" {
|
||||
}
|
||||
|
||||
// ── Test: optional unwrap (ct_opt_unwrap from 50-smoke.sx) ───────────────
|
||||
// ct_opt_unwrap :: () -> s32 { x:?s32 = 77; return x!; }
|
||||
// ct_opt_unwrap :: () -> i32 { x:?i32 = 77; return x!; }
|
||||
// Expected: 77
|
||||
|
||||
test "comptime: optional unwrap — 77" {
|
||||
@@ -286,17 +286,17 @@ test "comptime: optional unwrap — 77" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "ct_opt_unwrap"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "ct_opt_unwrap"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const slot = b.alloca(.s64);
|
||||
const val77 = b.constInt(77, .s64);
|
||||
const slot = b.alloca(.i64);
|
||||
const val77 = b.constInt(77, .i64);
|
||||
b.store(slot, val77);
|
||||
|
||||
const loaded = b.load(slot, .s64);
|
||||
const unwrapped = b.optionalUnwrap(loaded, .s64);
|
||||
b.ret(unwrapped, .s64);
|
||||
const loaded = b.load(slot, .i64);
|
||||
const unwrapped = b.optionalUnwrap(loaded, .i64);
|
||||
b.ret(unwrapped, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -306,7 +306,7 @@ test "comptime: optional unwrap — 77" {
|
||||
}
|
||||
|
||||
// ── Test: recursive fibonacci ────────────────────────────────────────────
|
||||
// fib :: (n: s64) -> s64 { if n <= 1 return n; return fib(n-1) + fib(n-2); }
|
||||
// fib :: (n: i64) -> i64 { if n <= 1 return n; return fib(n-1) + fib(n-2); }
|
||||
// Expected: fib(10) = 55
|
||||
|
||||
test "comptime: recursive fibonacci — fib(10) = 55" {
|
||||
@@ -317,8 +317,8 @@ test "comptime: recursive fibonacci — fib(10) = 55" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "n"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "fib"), params, .s64);
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "n"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "fib"), params, .i64);
|
||||
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
const base_bb = b.appendBlock(str(&module, "base"), &.{});
|
||||
@@ -327,23 +327,23 @@ test "comptime: recursive fibonacci — fib(10) = 55" {
|
||||
// entry: if n <= 1 → base, else → recurse
|
||||
b.switchToBlock(entry);
|
||||
const n = Ref.fromIndex(0);
|
||||
const one = b.constInt(1, .s64);
|
||||
const one = b.constInt(1, .i64);
|
||||
const is_base = b.emit(.{ .cmp_le = .{ .lhs = n, .rhs = one } }, .bool);
|
||||
b.condBr(is_base, base_bb, &.{}, rec_bb, &.{});
|
||||
|
||||
// base: return n
|
||||
b.switchToBlock(base_bb);
|
||||
b.ret(n, .s64);
|
||||
b.ret(n, .i64);
|
||||
|
||||
// recurse: return fib(n-1) + fib(n-2)
|
||||
b.switchToBlock(rec_bb);
|
||||
const n_minus_1 = b.sub(n, one, .s64);
|
||||
const two = b.constInt(2, .s64);
|
||||
const n_minus_2 = b.sub(n, two, .s64);
|
||||
const fib1 = b.call(FuncId.fromIndex(0), &.{n_minus_1}, .s64);
|
||||
const fib2 = b.call(FuncId.fromIndex(0), &.{n_minus_2}, .s64);
|
||||
const sum = b.add(fib1, fib2, .s64);
|
||||
b.ret(sum, .s64);
|
||||
const n_minus_1 = b.sub(n, one, .i64);
|
||||
const two = b.constInt(2, .i64);
|
||||
const n_minus_2 = b.sub(n, two, .i64);
|
||||
const fib1 = b.call(FuncId.fromIndex(0), &.{n_minus_1}, .i64);
|
||||
const fib2 = b.call(FuncId.fromIndex(0), &.{n_minus_2}, .i64);
|
||||
const sum = b.add(fib1, fib2, .i64);
|
||||
b.ret(sum, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -353,7 +353,7 @@ test "comptime: recursive fibonacci — fib(10) = 55" {
|
||||
}
|
||||
|
||||
// ── Test: compute(5) = 7 (from 05-run.sx) ──────────────────────────────
|
||||
// compute :: (v: s32) -> s32 => v + 2;
|
||||
// compute :: (v: i32) -> i32 => v + 2;
|
||||
// Expected: compute(5) = 7
|
||||
|
||||
test "comptime: compute(5) = 7" {
|
||||
@@ -364,15 +364,15 @@ test "comptime: compute(5) = 7" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "v"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "compute"), params, .s64);
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "v"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "compute"), params, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const v = Ref.fromIndex(0);
|
||||
const two = b.constInt(2, .s64);
|
||||
const result = b.add(v, two, .s64);
|
||||
b.ret(result, .s64);
|
||||
const two = b.constInt(2, .i64);
|
||||
const result = b.add(v, two, .i64);
|
||||
b.ret(result, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -382,7 +382,7 @@ test "comptime: compute(5) = 7" {
|
||||
}
|
||||
|
||||
// ── Test: chained comptime (CT_CHAIN from 50-smoke.sx) ───────────────────
|
||||
// add :: (a: s32, b: s32) -> s32 => a + b;
|
||||
// add :: (a: i32, b: i32) -> i32 => a + b;
|
||||
// CT_VAL :: #run add(10, 15); → 25
|
||||
// CT_CHAIN :: #run add(CT_VAL, 5); → 30
|
||||
// Simulates calling add(25, 5) to verify chaining works.
|
||||
@@ -395,18 +395,18 @@ test "comptime: chained — add(add(10,15), 5) = 30" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// func add(a, b) -> s64 { return a + b; }
|
||||
// func add(a, b) -> i64 { return a + b; }
|
||||
const params = &[_]Function.Param{
|
||||
.{ .name = str(&module, "a"), .ty = .s64 },
|
||||
.{ .name = str(&module, "b"), .ty = .s64 },
|
||||
.{ .name = str(&module, "a"), .ty = .i64 },
|
||||
.{ .name = str(&module, "b"), .ty = .i64 },
|
||||
};
|
||||
_ = b.beginFunction(str(&module, "add"), params, .s64);
|
||||
_ = b.beginFunction(str(&module, "add"), params, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
const a = Ref.fromIndex(0);
|
||||
const b_ref = Ref.fromIndex(1);
|
||||
const sum = b.add(a, b_ref, .s64);
|
||||
b.ret(sum, .s64);
|
||||
const sum = b.add(a, b_ref, .i64);
|
||||
b.ret(sum, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -433,20 +433,20 @@ test "comptime: struct init and field access — 7" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "test_struct"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "test_struct"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
// Point{x: 3, y: 4}
|
||||
const three = b.constInt(3, .s64);
|
||||
const four = b.constInt(4, .s64);
|
||||
const point = b.structInit(&.{ three, four }, .s64);
|
||||
const three = b.constInt(3, .i64);
|
||||
const four = b.constInt(4, .i64);
|
||||
const point = b.structInit(&.{ three, four }, .i64);
|
||||
|
||||
// p.x + p.y
|
||||
const px = b.structGet(point, 0, .s64);
|
||||
const py = b.structGet(point, 1, .s64);
|
||||
const sum = b.add(px, py, .s64);
|
||||
b.ret(sum, .s64);
|
||||
const px = b.structGet(point, 0, .i64);
|
||||
const py = b.structGet(point, 1, .i64);
|
||||
const sum = b.add(px, py, .i64);
|
||||
b.ret(sum, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -538,14 +538,14 @@ test "comptime: negation — int and float" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// func neg_int(x: s64) -> s64 { return -x; }
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "neg_int"), params, .s64);
|
||||
// func neg_int(x: i64) -> i64 { return -x; }
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "x"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "neg_int"), params, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
const x = Ref.fromIndex(0);
|
||||
const neg = b.emit(.{ .neg = .{ .operand = x } }, .s64);
|
||||
b.ret(neg, .s64);
|
||||
const neg = b.emit(.{ .neg = .{ .operand = x } }, .i64);
|
||||
b.ret(neg, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -564,14 +564,14 @@ test "comptime: modulo — 17 mod 5 = 2" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "test_mod"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "test_mod"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const seventeen = b.constInt(17, .s64);
|
||||
const five = b.constInt(5, .s64);
|
||||
const result = b.emit(.{ .mod = .{ .lhs = seventeen, .rhs = five } }, .s64);
|
||||
b.ret(result, .s64);
|
||||
const seventeen = b.constInt(17, .i64);
|
||||
const five = b.constInt(5, .i64);
|
||||
const result = b.emit(.{ .mod = .{ .lhs = seventeen, .rhs = five } }, .i64);
|
||||
b.ret(result, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -591,8 +591,8 @@ test "comptime: switch_br dispatch" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "tag"), .ty = .s64 }};
|
||||
_ = b.beginFunction(str(&module, "dispatch"), params, .s64);
|
||||
const params = &[_]Function.Param{.{ .name = str(&module, "tag"), .ty = .i64 }};
|
||||
_ = b.beginFunction(str(&module, "dispatch"), params, .i64);
|
||||
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
const case0 = b.appendBlock(str(&module, "case0"), &.{});
|
||||
@@ -607,16 +607,16 @@ test "comptime: switch_br dispatch" {
|
||||
}, default, &.{});
|
||||
|
||||
b.switchToBlock(case0);
|
||||
const ten = b.constInt(10, .s64);
|
||||
b.ret(ten, .s64);
|
||||
const ten = b.constInt(10, .i64);
|
||||
b.ret(ten, .i64);
|
||||
|
||||
b.switchToBlock(case1);
|
||||
const twenty = b.constInt(20, .s64);
|
||||
b.ret(twenty, .s64);
|
||||
const twenty = b.constInt(20, .i64);
|
||||
b.ret(twenty, .i64);
|
||||
|
||||
b.switchToBlock(default);
|
||||
const thirty = b.constInt(30, .s64);
|
||||
b.ret(thirty, .s64);
|
||||
const thirty = b.constInt(30, .i64);
|
||||
b.ret(thirty, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -642,14 +642,14 @@ test "comptime: enum init and tag" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "test_enum"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "test_enum"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
// Create enum with tag=2, no payload
|
||||
const e = b.enumInit(2, Ref.none, .s64);
|
||||
const tag = b.emit(.{ .enum_tag = .{ .operand = e } }, .s64);
|
||||
b.ret(tag, .s64);
|
||||
const e = b.enumInit(2, Ref.none, .i64);
|
||||
const tag = b.emit(.{ .enum_tag = .{ .operand = e } }, .i64);
|
||||
b.ret(tag, .i64);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -668,14 +668,14 @@ test "comptime: widen/narrow passthrough" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
_ = b.beginFunction(str(&module, "test_conv"), &.{}, .s64);
|
||||
_ = b.beginFunction(str(&module, "test_conv"), &.{}, .i64);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
|
||||
const val = b.constInt(42, .s32);
|
||||
const widened = b.emit(.{ .widen = .{ .operand = val, .from = .s32, .to = .s64 } }, .s64);
|
||||
const narrowed = b.emit(.{ .narrow = .{ .operand = widened, .from = .s64, .to = .s32 } }, .s32);
|
||||
b.ret(narrowed, .s32);
|
||||
const val = b.constInt(42, .i32);
|
||||
const widened = b.emit(.{ .widen = .{ .operand = val, .from = .i32, .to = .i64 } }, .i64);
|
||||
const narrowed = b.emit(.{ .narrow = .{ .operand = widened, .from = .i64, .to = .i32 } }, .i32);
|
||||
b.ret(narrowed, .i32);
|
||||
b.finalize();
|
||||
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
@@ -694,13 +694,13 @@ test "comptime: const_type yields type_tag" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// Build a fn that returns `s64` as a Type-typed Any value (matches
|
||||
// Build a fn that returns `i64` as a Type-typed Any value (matches
|
||||
// the .any IR type assigned by `constType`). The interp returns the
|
||||
// raw Value; we assert on the variant.
|
||||
_ = b.beginFunction(str(&module, "test_type_tag"), &.{}, .any);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
const t = b.constType(.s64);
|
||||
const t = b.constType(.i64);
|
||||
b.ret(t, .any);
|
||||
b.finalize();
|
||||
|
||||
@@ -711,7 +711,7 @@ test "comptime: const_type yields type_tag" {
|
||||
// The Value MUST be a .type_tag, not an .int — proves the variant
|
||||
// is honestly distinguished. asTypeId returns the inner TypeId;
|
||||
// asInt MUST return null (no coercion).
|
||||
try std.testing.expectEqual(@as(?TypeId, .s64), result.asTypeId());
|
||||
try std.testing.expectEqual(@as(?TypeId, .i64), result.asTypeId());
|
||||
try std.testing.expectEqual(@as(?i64, null), result.asInt());
|
||||
}
|
||||
|
||||
@@ -725,23 +725,23 @@ test "comptime: type_tag comparison" {
|
||||
defer module.deinit();
|
||||
var b = Builder.init(&module);
|
||||
|
||||
// Returns (s64 == s64) — should yield bool true via the new
|
||||
// Returns (i64 == i64) — should yield bool true via the new
|
||||
// evalCmp arm for .type_tag operands.
|
||||
_ = b.beginFunction(str(&module, "test_type_eq_true"), &.{}, .bool);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
const a = b.constType(.s64);
|
||||
const c = b.constType(.s64);
|
||||
const a = b.constType(.i64);
|
||||
const c = b.constType(.i64);
|
||||
const eq = b.cmpEq(a, c);
|
||||
b.ret(eq, .bool);
|
||||
b.finalize();
|
||||
|
||||
// Different TypeIds: (s64 == s32) should be false.
|
||||
// Different TypeIds: (i64 == i32) should be false.
|
||||
_ = b.beginFunction(str(&module, "test_type_eq_false"), &.{}, .bool);
|
||||
const entry2 = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry2);
|
||||
const a2 = b.constType(.s64);
|
||||
const c2 = b.constType(.s32);
|
||||
const a2 = b.constType(.i64);
|
||||
const c2 = b.constType(.i32);
|
||||
const eq2 = b.cmpEq(a2, c2);
|
||||
b.ret(eq2, .bool);
|
||||
b.finalize();
|
||||
@@ -767,7 +767,7 @@ test "comptime: type_name builtin on type_tag" {
|
||||
_ = b.beginFunction(str(&module, "test_type_name"), &.{}, .string);
|
||||
const entry = b.appendBlock(str(&module, "entry"), &.{});
|
||||
b.switchToBlock(entry);
|
||||
const t = b.constType(.s64);
|
||||
const t = b.constType(.i64);
|
||||
var args = [_]inst_mod.Ref{t};
|
||||
const r = b.callBuiltin(.type_name, &args, .string);
|
||||
b.ret(r, .string);
|
||||
@@ -776,7 +776,7 @@ test "comptime: type_name builtin on type_tag" {
|
||||
var interp = Interpreter.init(&module, alloc);
|
||||
defer interp.deinit();
|
||||
const result = try interp.call(FuncId.fromIndex(0), &.{});
|
||||
try std.testing.expectEqualStrings("s64", result.asString(&interp).?);
|
||||
try std.testing.expectEqualStrings("i64", result.asString(&interp).?);
|
||||
}
|
||||
|
||||
// ── Test: type_eq builtin on two .type_tag operands ────────────────────
|
||||
@@ -809,7 +809,7 @@ test "comptime: type_eq builtin on type_tag values" {
|
||||
// A reflection builtin on an Any must report the type OF a held value (the
|
||||
// tag) and only read the payload when the Any holds a Type value (tag ==
|
||||
// `.any`). Regression: a boxed value like
|
||||
// `av : Any = 6` (`{ tag = s64, value = 6 }`) must resolve to `s64`, NOT
|
||||
// `av : Any = 6` (`{ tag = i64, value = 6 }`) must resolve to `i64`, NOT
|
||||
// `types[6]` (`u8`).
|
||||
test "reflect: reflectTypeId branches on the Any tag" {
|
||||
const any_idx: i64 = @intCast(TypeId.any.index());
|
||||
@@ -817,10 +817,10 @@ test "reflect: reflectTypeId branches on the Any tag" {
|
||||
// Native first-class Type value → the held TypeId directly.
|
||||
try std.testing.expectEqual(@as(?TypeId, .u64), (Value{ .type_tag = .u64 }).reflectTypeId());
|
||||
|
||||
// Any holding a VALUE: `{ tag = s64, value = 6 }` → s64 (the tag),
|
||||
// Any holding a VALUE: `{ tag = i64, value = 6 }` → i64 (the tag),
|
||||
// never `types[6]` (u8). This is the bug the fix closes.
|
||||
var held_value = [_]Value{ .{ .int = @intCast(TypeId.s64.index()) }, .{ .int = 6 } };
|
||||
try std.testing.expectEqual(@as(?TypeId, .s64), (Value{ .aggregate = &held_value }).reflectTypeId());
|
||||
var held_value = [_]Value{ .{ .int = @intCast(TypeId.i64.index()) }, .{ .int = 6 } };
|
||||
try std.testing.expectEqual(@as(?TypeId, .i64), (Value{ .aggregate = &held_value }).reflectTypeId());
|
||||
|
||||
// Any holding a VALUE of an unsigned type: `{ tag = u32, value = 7 }` → u32.
|
||||
var held_u32 = [_]Value{ .{ .int = @intCast(TypeId.u32.index()) }, .{ .int = 7 } };
|
||||
|
||||
Reference in New Issue
Block a user