test: split 50-smoke.sx into per-section examples + add errors smoke
Break the monolithic examples/50-smoke.sx into 30 focused per-section examples,
filed into their category blocks (basic/types/comptime/memory/protocols/ffi),
each carrying only the top-level decls its section references (the protocols
section keeps the full preamble — its deps flow through UFCS method calls that
name-based extraction can't see). Outputs verified identical to the original
section blocks.
Add examples/1036-errors-failable-smoke.sx — an end-to-end error-handling example
(the E5.4 work): named + inferred error sets consumed via destructure, try (in
helpers), catch (bare-expr / match-body / diverging / no-binding), or
value-terminator, onfail+defer interleave, and error.X value + {} tag
interpolation.
Remove examples/50-smoke.sx. Suite: 324 passed, 0 failed.
This commit is contained in:
342
examples/0121-types-types.sx
Normal file
342
examples/0121-types-types.sx
Normal file
@@ -0,0 +1,342 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
Point :: struct { x, y: s32; }
|
||||
|
||||
Color :: enum { red; green; blue; }
|
||||
|
||||
Shape :: enum {
|
||||
circle: f32;
|
||||
rect: struct { w, h: f32; };
|
||||
none;
|
||||
}
|
||||
|
||||
Overlay :: union {
|
||||
f: f32;
|
||||
i: s32;
|
||||
}
|
||||
|
||||
Vec2 :: union {
|
||||
data: [2]f32;
|
||||
struct { x, y: f32; };
|
||||
}
|
||||
|
||||
Defaults :: struct {
|
||||
a: s32;
|
||||
b: s32 = 99;
|
||||
c: s32 = ---;
|
||||
}
|
||||
|
||||
MyFloat :: f64;
|
||||
|
||||
Status :: enum u8 { ok; err; timeout; }
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
mul :: (a: s32, b: s32) -> s32 { a * b; }
|
||||
|
||||
vec3 :: (x: f32, y: f32, z: f32) -> Vector(3, f32) {
|
||||
.[x, y, z];
|
||||
}
|
||||
|
||||
// Global variable for address-of test
|
||||
g_smoke_val : s32 = 42;
|
||||
|
||||
write_to_ptr :: (p: *s32) {
|
||||
p.* = 99;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 3. TYPE SYSTEM
|
||||
// ========================================================
|
||||
print("=== 3. Types ===\n");
|
||||
|
||||
// Primitive types
|
||||
v_s8 : s8 = 127;
|
||||
v_s16 : s16 = 32000;
|
||||
v_s32 : s32 = 100000;
|
||||
v_u8 : u8 = 255;
|
||||
v_u16 : u16 = 65000;
|
||||
v_u32 : u32 = 4000000;
|
||||
print("s8: {}\n", v_s8);
|
||||
print("s16: {}\n", v_s16);
|
||||
print("s32: {}\n", v_s32);
|
||||
print("u8: {}\n", v_u8);
|
||||
print("u16: {}\n", v_u16);
|
||||
print("u32: {}\n", v_u32);
|
||||
|
||||
// Type alias
|
||||
mf : MyFloat = 1.5;
|
||||
print("alias: {}\n", mf);
|
||||
|
||||
// --- Structs ---
|
||||
// Positional literal
|
||||
p1 : Point = .{ 1, 2 };
|
||||
print("struct-pos: {}\n", p1);
|
||||
|
||||
// Type-prefix literal
|
||||
p2 := Point.{ 3, 4 };
|
||||
print("struct-prefix: {}\n", p2);
|
||||
|
||||
// Named fields
|
||||
p3 := Point.{ y=10, x=20 };
|
||||
print("struct-named: {}\n", p3);
|
||||
|
||||
// Shorthand (variable name = field name)
|
||||
x : s32 = 5;
|
||||
y : s32 = 6;
|
||||
p4 := Point.{ x, y };
|
||||
print("struct-shorthand: {}\n", p4);
|
||||
|
||||
// Field defaults
|
||||
d1 : Defaults;
|
||||
print("defaults: a={} b={}\n", d1.a, d1.b);
|
||||
|
||||
// Field access and assignment
|
||||
p5 := Point.{ 0, 0 };
|
||||
p5.x = 42;
|
||||
p5.y = 99;
|
||||
print("field-assign: {}\n", p5);
|
||||
|
||||
// --- Enum (payload-less) ---
|
||||
ec : Color = .red;
|
||||
print("enum: {}\n", ec);
|
||||
|
||||
// Enum comparison
|
||||
ce1 : Color = .red;
|
||||
ce2 : Color = .red;
|
||||
ce3 : Color = .blue;
|
||||
print("enum-eq: {}\n", ce1 == ce2);
|
||||
print("enum-neq: {}\n", ce1 != ce3);
|
||||
|
||||
// Backing type
|
||||
st : Status = .err;
|
||||
print("backing: {}\n", st);
|
||||
|
||||
// --- Enum (tagged union) ---
|
||||
sh : Shape = .circle(3.14);
|
||||
print("tagged: {}\n", sh);
|
||||
|
||||
// Payload access
|
||||
radius := sh.circle;
|
||||
print("payload: {}\n", radius);
|
||||
|
||||
// Void variant
|
||||
sh = .none;
|
||||
print("void-variant: {}\n", sh);
|
||||
|
||||
// Variant reassignment
|
||||
sh = .circle(1.0);
|
||||
print("reassign: {}\n", sh);
|
||||
sh = .rect(.{ 5, 3 });
|
||||
print("reassign2: {}\n", sh);
|
||||
|
||||
// Type-prefix construction
|
||||
tp := Shape.circle(2.5);
|
||||
print("enum-prefix: {}\n", tp);
|
||||
|
||||
// Pattern matching
|
||||
sh2 : Shape = .rect(.{ 5, 3 });
|
||||
if sh2 == {
|
||||
case .circle: print("match: circle\n");
|
||||
case .rect: print("match: rect\n");
|
||||
case .none: print("match: none\n");
|
||||
}
|
||||
|
||||
// Match as expression
|
||||
sh3 : Shape = .circle(1.0);
|
||||
ms := if sh3 == {
|
||||
case .circle: 10;
|
||||
case .rect: 20;
|
||||
case .none: 30;
|
||||
}
|
||||
print("match-expr: {}\n", ms);
|
||||
|
||||
// Match expression with else
|
||||
me_val := 42;
|
||||
me_res := if me_val == {
|
||||
case 1: 10;
|
||||
case 2: 20;
|
||||
else: 99;
|
||||
}
|
||||
print("match-expr-else: {}\n", me_res);
|
||||
|
||||
// Payload capture (block form)
|
||||
sh4 : Shape = .circle(9.5);
|
||||
if sh4 == {
|
||||
case .circle: (r) { print("capture: {}\n", r); }
|
||||
case .rect: (sz) { print("capture: {}\n", sz); }
|
||||
case .none: print("capture: none\n");
|
||||
}
|
||||
|
||||
// Payload capture (arrow form)
|
||||
sh_ca : Shape = .circle(7.5);
|
||||
if sh_ca == {
|
||||
case .circle: (r) => print("capture-arrow: {}\n", r);
|
||||
case .rect: (sz) => print("capture-arrow: rect\n");
|
||||
case .none: print("capture-arrow: none\n");
|
||||
}
|
||||
|
||||
// else arm in match
|
||||
num := 42;
|
||||
if num == {
|
||||
case 1: print("else-match: one\n");
|
||||
case 2: print("else-match: two\n");
|
||||
else: print("else-match: other\n");
|
||||
}
|
||||
|
||||
// Integer pattern matching
|
||||
code := 2;
|
||||
if code == {
|
||||
case 1: print("int-match: one\n");
|
||||
case 2: print("int-match: two\n");
|
||||
case 3: print("int-match: three\n");
|
||||
}
|
||||
|
||||
// Integer match with else
|
||||
im_code := 99;
|
||||
if im_code == {
|
||||
case 1: print("int-match-else: one\n");
|
||||
case 2: print("int-match-else: two\n");
|
||||
else: print("int-match-else: unknown\n");
|
||||
}
|
||||
|
||||
// Bool pattern matching
|
||||
bm := true;
|
||||
if bm == {
|
||||
case true: print("bool-match-t: yes\n");
|
||||
case false: print("bool-match-t: no\n");
|
||||
}
|
||||
bm2 := false;
|
||||
if bm2 == {
|
||||
case true: print("bool-match-f: yes\n");
|
||||
case false: print("bool-match-f: no\n");
|
||||
}
|
||||
|
||||
// Bool conditional
|
||||
flag := true;
|
||||
if flag { print("bool: true\n"); }
|
||||
|
||||
// --- Union (untagged) ---
|
||||
o : Overlay = ---;
|
||||
o.f = 3.14;
|
||||
print("union-f: {}\n", o.f);
|
||||
// Type punning — read same bits as s32
|
||||
print("union-i: {}\n", o.i);
|
||||
|
||||
// Union member promotion
|
||||
uv : Vec2 = ---;
|
||||
uv.x = 1.0;
|
||||
uv.y = 2.0;
|
||||
print("promoted-x: {}\n", uv.x);
|
||||
print("promoted-data0: {}\n", uv.data[0]);
|
||||
|
||||
// --- Arrays ---
|
||||
arr : [5]s32 = .[10, 20, 30, 40, 50];
|
||||
print("arr[2]: {}\n", arr[2]);
|
||||
print("arr.len: {}\n", arr.len);
|
||||
|
||||
// Array element assignment
|
||||
aa : [3]s32 = .[1, 2, 3];
|
||||
aa[1] = 99;
|
||||
print("arr-assign: {}\n", aa);
|
||||
|
||||
// --- Slices ---
|
||||
sl : []s32 = .[1, 2, 3, 4, 5];
|
||||
print("sl[0]: {}\n", sl[0]);
|
||||
print("sl.len: {}\n", sl.len);
|
||||
|
||||
// Slice element write
|
||||
sla : []s32 = .[10, 20, 30];
|
||||
sla[1] = 55;
|
||||
print("sl-assign: {}\n", sla);
|
||||
|
||||
// Subslicing
|
||||
sub := arr[1..4];
|
||||
print("sub: {}\n", sub);
|
||||
head := arr[..3];
|
||||
print("head: {}\n", head);
|
||||
tail := arr[2..];
|
||||
print("tail: {}\n", tail);
|
||||
|
||||
// Slice of slice
|
||||
sos : []s32 = .[10, 20, 30, 40, 50];
|
||||
mid := sos[1..4];
|
||||
inner := mid[0..2];
|
||||
print("slice-of-slice: {}\n", inner);
|
||||
|
||||
// String subslicing
|
||||
msg := "hello world";
|
||||
print("strsub: {}\n", msg[6..11]);
|
||||
print("str-prefix: {}\n", msg[..5]);
|
||||
print("str-suffix: {}\n", msg[6..]);
|
||||
|
||||
// --- Pointers ---
|
||||
// Address-of global variable
|
||||
write_to_ptr(@g_smoke_val);
|
||||
print("global-addr-of: {}\n", g_smoke_val);
|
||||
|
||||
pv := Point.{ 10, 20 };
|
||||
ptr := @pv;
|
||||
print("deref: {}\n", ptr.*);
|
||||
|
||||
// Auto-deref
|
||||
print("auto-deref: {}\n", ptr.x);
|
||||
|
||||
// Many-pointer
|
||||
mp : [*]s32 = @arr[0];
|
||||
print("mp[0]: {}\n", mp[0]);
|
||||
print("mp[3]: {}\n", mp[3]);
|
||||
|
||||
// Many-pointer write
|
||||
mpw : [5]s32 = .[10, 20, 30, 40, 50];
|
||||
mpw_ptr : [*]s32 = @mpw[0];
|
||||
mpw_ptr[2] = 99;
|
||||
print("mp-write: {}\n", mpw[2]);
|
||||
|
||||
// Pointer-null comparison
|
||||
np : *s32 = null;
|
||||
print("ptr==null: {}\n", np == null);
|
||||
print("ptr!=null: {}\n", np != null);
|
||||
np2 := @pv.x;
|
||||
print("ptr2==null: {}\n", np2 == null);
|
||||
print("ptr2!=null: {}\n", np2 != null);
|
||||
|
||||
// Pointer to nested struct field
|
||||
Inner3 :: struct { a: f32; b: f32; c: f32; }
|
||||
Outer3 :: struct { key: s32; inner: Inner3; }
|
||||
out3 := Outer3.{ key = 42, inner = Inner3.{ a = 1.0, b = 2.0, c = 3.0 } };
|
||||
ip3 := @out3.inner;
|
||||
print("ptr-nested-field: {} {} {}\n", ip3.a, ip3.b, ip3.c);
|
||||
|
||||
// Store to many-pointer field must not corrupt adjacent memory
|
||||
MpHolder :: struct { items: [*]s64; sentinel: s64; }
|
||||
mph := MpHolder.{ items = xx 0, sentinel = 42 };
|
||||
mph.items = xx 0;
|
||||
print("mp-store-sentinel: {}\n", mph.sentinel);
|
||||
|
||||
// --- Vectors ---
|
||||
vc := vec3(1, 3, 2);
|
||||
print("vec-construct: {}\n", vc);
|
||||
|
||||
va := vec3(1, 2, 3);
|
||||
vb := vec3(4, 5, 6);
|
||||
print("vec-add: {}\n", va + vb);
|
||||
print("vec-sub: {}\n", vec3(5, 5, 5) - vec3(1, 2, 3));
|
||||
print("vec-mul: {}\n", vec3(2, 3, 4) * vec3(1, 2, 3));
|
||||
print("vec-div: {}\n", vec3(10, 9, 8) / vec3(2, 3, 4));
|
||||
|
||||
print("vec-scalar: {}\n", vec3(1, 3, 2) * 2.0);
|
||||
print("vec-neg: {}\n", -vec3(1, 3, 2));
|
||||
|
||||
ve := vec3(10, 20, 30);
|
||||
print("vec-x: {}\n", ve.x);
|
||||
print("vec-y: {}\n", ve.y);
|
||||
print("vec-z: {}\n", ve.z);
|
||||
print("vec-idx: {}\n", ve[1]);
|
||||
}
|
||||
Reference in New Issue
Block a user