test: group examples into per-category folders

Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
This commit is contained in:
agra
2026-06-21 14:41:34 +03:00
parent 6d1409bc1f
commit 66bdc70bf1
3357 changed files with 456 additions and 363 deletions

View File

@@ -0,0 +1,44 @@
#import "modules/std.sx";
math :: #import "modules/math";
dot :: (a: Vector(3,f32), b: Vector(3,f32)) -> f32 {
a.x*b.x + a.y*b.y + a.z*b.z
}
cross :: (a: Vector(3,f32), b: Vector(3,f32)) -> Vector(3,f32) {
.[a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x]
}
length :: (v: Vector(3,f32)) -> f32 {
math.sqrt(dot(v, v))
}
normalize :: (v: Vector(3,f32)) -> Vector(3,f32) {
v / length(v)
}
vec3 :: (x:f32, y:f32, z:f32) -> Vector(3,f32) {
.[x, y, z]
}
main :: () {
a := vec3(1, 0, 0);
b := vec3(0, 1, 0);
// dot product
d := dot(a, b);
print("dot: {}\n", d);
// cross product
cr := cross(a, b);
print("cross: {}\n", cr);
// length
v := vec3(3, 4, 0);
len := length(v);
print("length: {}\n", len);
// normalize
n := normalize(v);
print("norm: {}\n", n);
}

View File

@@ -0,0 +1,35 @@
// A `Vector` lane count from a named const or a constant-foldable expression
// resolves to the SAME layout as a literal lane — DIRECT (param / return type)
// and via a type ALIAS. A 3-lane (named const `N`) and a 4-lane (const expr
// `M + 1`) prove the lane VALUE is folded, not fabricated: reading `.w` requires
// the 4-lane vector to actually have four lanes.
//
// Regression (issue 0083): the stateful Vector lane resolvers hand-rolled an
// `else => 0` switch, so a module-const lane (`Vector(N, f32)`) lowered a 0-lane
// `<0 x float>` and died in LLVM verification ("huge alignment values are
// unsupported"); a const-expr lane (`Vector(M + 1, f32)`) was rejected at parse.
// Both now fold through the single shared const-int evaluator
// (`program_index.evalConstIntExpr`) — the same one the array-dimension path
// uses — so a named-const / const-expr lane is identical to a literal lane.
#import "modules/std.sx";
N :: 3;
M :: 3;
LaneAlias :: Vector(N, f32); // ALIAS: 3-lane via named const.
ExprAlias :: Vector(M + 1, f32); // ALIAS: 4-lane via const expression.
mk3 :: () -> Vector(N, f32) { .[1.0, 2.0, 3.0] } // DIRECT named-const lane.
mk4 :: () -> Vector(M + 1, f32) { .[1.0, 2.0, 3.0, 4.0] } // DIRECT const-expr lane.
main :: () {
a := mk3();
print("direct3: {} {} {}\n", a.x, a.y, a.z);
b := mk4();
print("direct4: {} {} {} {}\n", b.x, b.y, b.z, b.w);
c : LaneAlias = .[5.0, 6.0, 7.0];
print("alias3: {}\n", c.z);
d : ExprAlias = .[5.0, 6.0, 7.0, 8.0];
print("alias4: {}\n", d.w);
}

View File

@@ -0,0 +1,16 @@
// A `Vector` lane count that is not a compile-time integer (here a runtime
// function call) is a hard error — a clean sx diagnostic with a non-zero exit,
// NOT a fabricated `<0 x float>` lane that crashes LLVM verification.
//
// Regression (issue 0083): the Vector lane resolver hand-rolled an `else => 0`
// switch that silently fabricated a 0-lane vector for a non-const lane. It now
// folds the lane through the shared const-int evaluator and, when that yields no
// compile-time integer, emits this diagnostic and halts the build.
#import "modules/std.sx";
lanes :: () -> u32 { return 3; }
main :: () {
v : Vector(lanes(), f32) = ---;
print("unreachable: {}\n", v.x);
}

View File

@@ -0,0 +1,15 @@
// A `Vector` lane count that folds to a valid compile-time integer but exceeds a
// `u32` (`Vector(5_000_000_000, f32)`) is a hard error — a clean sx diagnostic
// with a non-zero exit, NOT a compiler panic.
//
// Regression (issue 0087 / F0.4 attempt 6): the lane folded to a valid i64 (5e9)
// and was then narrowed with an unchecked `@intCast` to u32, aborting the
// COMPILER with "integer does not fit in destination type". The lane now narrows
// through the single range-checked `program_index.foldDimU32`, which reports an
// out-of-u32-range lane as this diagnostic and halts the build.
#import "modules/std.sx";
main :: () {
v : Vector(5000000000, f32) = ---;
print("unreachable: {}\n", v.x);
}

View File

@@ -0,0 +1,12 @@
// A Vector lane count accepts an integral float constant — `L : f64 : 4.0` lays
// out the same `Vector(4, f32)` as the literal `4`. The lane resolver shares the
// const-int evaluator with the array-dim path, so the integral-float rule
// (issue 0083 / F0.4 attempt 8, Agra ruling) applies uniformly.
#import "modules/std.sx";
L : f64 : 4.0;
main :: () {
v : Vector(L, f32) = .[1.0, 2.0, 3.0, 4.0];
print("v0={} v2={} v3={}\n", v[0], v[2], v[3]);
}

View File

@@ -0,0 +1,15 @@
// A zero `Vector` lane count is rejected — a vector must have at least one lane
// (strictly positive). Contrast with an array dimension / value-param count,
// where zero is a valid length-0 instantiation (see 0147). This pins the
// zero-rejecting half of the context-dependent count rule (specs.md, Array
// Types).
//
// Regression (F0.4 attempt 12): the spec now states the zero rule per consumer;
// the `Vector` lane count stays strictly positive while array dims / value-param
// counts accept zero.
#import "modules/std.sx";
main :: () {
v : Vector(0, f32) = ---;
print("unreachable: {}\n", v.x);
}

View File

@@ -0,0 +1,46 @@
// Writing a `Vector` lane — `v.x = …` (and `.y`/`.z`/`.w`, plus the colour
// aliases `.r`/`.g`/`.b`/`.a`) — stores through a pointer to that lane and
// reads back the written value. Covers a `.[…]`-init write, a `= ---`
// (undefined) init write, writes to every lane of a 4-lane vector, the colour
// aliases, and a compound lane assignment (`+= / *=`).
//
// Regression (issue 0086): the lane STORE path fell through to struct-field
// lookup, where no field matched a vector lane, leaving the lane pointer's
// pointee as the `.unresolved` sentinel — which panicked at LLVM emission
// ("unresolved type reached LLVM emission"). The store path now resolves the
// lane index via the same shared `vectorLaneIndex` resolver the read path uses
// and GEPs a typed pointer to the lane, so the two paths never diverge.
#import "modules/std.sx";
main :: () {
// `.[…]`-init, then write each lane of a 4-lane vector.
v : Vector(4, f32) = .[0.0, 0.0, 0.0, 0.0];
v.x = 1.0;
v.y = 2.0;
v.z = 3.0;
v.w = 4.0;
print("x={}\n", v.x);
print("y={}\n", v.y);
print("z={}\n", v.z);
print("w={}\n", v.w);
// `= ---` (undefined) init, then write every lane.
u : Vector(4, f32) = ---;
u.x = 10.0;
u.y = 20.0;
u.z = 30.0;
u.w = 40.0;
print("u={} {} {} {}\n", u.x, u.y, u.z, u.w);
// Colour aliases on a 3-lane vector.
col : Vector(3, f32) = .[0.0, 0.0, 0.0];
col.r = 0.5;
col.g = 0.25;
col.b = 0.125;
print("col={} {} {}\n", col.r, col.g, col.b);
// Compound lane assignment.
col.r += 0.5;
col.g *= 4.0;
print("col2={} {}\n", col.r, col.g);
}

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,4 @@
dot: 0.000000
cross: [0.000000, 0.000000, 1.000000]
length: 5.000000
norm: [0.600000, 0.800000, 0.000000]

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,4 @@
direct3: 1.000000 2.000000 3.000000
direct4: 1.000000 2.000000 3.000000 4.000000
alias3: 7.000000
alias4: 8.000000

View File

@@ -0,0 +1,5 @@
error: Vector lane count must be a positive compile-time integer constant
--> examples/vectors/1502-vectors-runtime-lane-not-const.sx:14:16
|
14 | v : Vector(lanes(), f32) = ---;
| ^^^^^^^

View File

@@ -0,0 +1,5 @@
error: Vector lane count 5000000000 does not fit in u32
--> examples/vectors/1503-vectors-oversized-lane-not-u32.sx:13:16
|
13 | v : Vector(5000000000, f32) = ---;
| ^^^^^^^^^^

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@
v0=1.000000 v2=3.000000 v3=4.000000

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,5 @@
error: Vector lane count must be a positive compile-time integer constant
--> examples/vectors/1505-vectors-zero-lane-rejected.sx:13:16
|
13 | v : Vector(0, f32) = ---;
| ^

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,7 @@
x=1.000000
y=2.000000
z=3.000000
w=4.000000
u=10.000000 20.000000 30.000000 40.000000
col=0.500000 0.250000 0.125000
col2=1.000000 1.000000