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:
67
examples/0025-basic-literals.sx
Normal file
67
examples/0025-basic-literals.sx
Normal file
@@ -0,0 +1,67 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
Color :: enum { red; green; blue; }
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 1. LITERALS
|
||||
// ========================================================
|
||||
print("=== 1. Literals ===\n");
|
||||
|
||||
// Integer literals
|
||||
print("decimal: {}\n", 42);
|
||||
print("hex: {}\n", 0xFF);
|
||||
print("binary: {}\n", 0b1010);
|
||||
|
||||
// Float literal
|
||||
pi := 3.14;
|
||||
print("float: {}\n", pi);
|
||||
|
||||
// Explicit f64
|
||||
big : f64 = 2.718281828;
|
||||
print("f64: {}\n", big);
|
||||
|
||||
// Boolean literals
|
||||
print("true: {}\n", true);
|
||||
print("false: {}\n", false);
|
||||
|
||||
// String with escapes
|
||||
print("escapes: hello\tworld\n");
|
||||
|
||||
// Multi-line string
|
||||
ml := "line1
|
||||
line2";
|
||||
print("multiline: {}\n", ml);
|
||||
|
||||
// Heredoc string
|
||||
hd := #string END
|
||||
raw heredoc
|
||||
END;
|
||||
print("heredoc: {}\n", hd);
|
||||
|
||||
// Undefined with type
|
||||
undef_val : s32 = ---;
|
||||
undef_val = 77;
|
||||
print("undef-then-set: {}\n", undef_val);
|
||||
|
||||
// Enum literal (context-inferred)
|
||||
c : Color = .green;
|
||||
print("enum-lit: {}\n", c);
|
||||
|
||||
// Null pointer
|
||||
np : *s32 = null;
|
||||
print("null-ptr: {}\n", np);
|
||||
|
||||
// String .len
|
||||
slen := "hello";
|
||||
print("string-len: {}\n", slen.len);
|
||||
|
||||
// Empty string .len
|
||||
es := "";
|
||||
print("empty-string: {}\n", es.len);
|
||||
}
|
||||
166
examples/0026-basic-operators.sx
Normal file
166
examples/0026-basic-operators.sx
Normal file
@@ -0,0 +1,166 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
mul :: (a: s32, b: s32) -> s32 { a * b; }
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
Chained :: protocol {
|
||||
base :: (msg: string) -> s32;
|
||||
wrap :: (msg: string) -> s32 {
|
||||
self.base(msg) + 1;
|
||||
}
|
||||
double_wrap :: (msg: string) -> s32 {
|
||||
self.wrap(msg) + self.wrap(msg);
|
||||
}
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 2. OPERATORS & PRECEDENCE
|
||||
// ========================================================
|
||||
print("=== 2. Operators ===\n");
|
||||
|
||||
// Arithmetic
|
||||
print("add: {}\n", 3 + 4);
|
||||
print("sub: {}\n", 10 - 3);
|
||||
print("mul: {}\n", 6 * 7);
|
||||
print("div: {}\n", 20 / 4);
|
||||
print("mod: {}\n", 17 % 5);
|
||||
print("neg: {}\n", -(5));
|
||||
|
||||
// Comparisons
|
||||
print("eq: {}\n", 5 == 5);
|
||||
print("neq: {}\n", 5 != 3);
|
||||
print("lt: {}\n", 3 < 5);
|
||||
print("gt: {}\n", 5 > 3);
|
||||
print("le: {}\n", 5 <= 5);
|
||||
print("ge: {}\n", 5 >= 3);
|
||||
|
||||
// Chained comparisons
|
||||
v := 50;
|
||||
print("chain: {}\n", 0 <= v <= 100);
|
||||
print("chain-gt: {}\n", 100 > v > 0);
|
||||
print("chain-mixed: {}\n", 100 > v >= 0);
|
||||
|
||||
// Equality chains
|
||||
print("eq-chain: {}\n", 5 == 5 == 5);
|
||||
print("eq-chain-f: {}\n", 5 == 5 == 6);
|
||||
|
||||
// Bitwise
|
||||
print("band: {}\n", 0xFF & 0x0F);
|
||||
print("bor: {}\n", 1 | 2 | 4);
|
||||
|
||||
// Bitwise XOR
|
||||
print("bxor: {}\n", 0xFF ^ 0x0F);
|
||||
print("bxor2: {}\n", 6 ^ 3);
|
||||
|
||||
// Bitwise NOT
|
||||
print("bnot: {}\n", ~0);
|
||||
print("bnot2: {}\n", ~1);
|
||||
|
||||
// Shifts
|
||||
print("shl: {}\n", 1 << 4);
|
||||
print("shr: {}\n", 256 >> 4);
|
||||
print("shl2: {}\n", 3 << 3);
|
||||
print("shr2: {}\n", 255 >> 1);
|
||||
|
||||
// Bitwise on variables
|
||||
bv1 := 0xFF;
|
||||
bv2 := 0x0F;
|
||||
print("band-var: {}\n", bv1 & bv2);
|
||||
bv3 := 1;
|
||||
bv4 := 6;
|
||||
print("bor-var: {}\n", bv3 | bv4);
|
||||
print("bxor-var: {}\n", bv1 ^ bv2);
|
||||
print("shl-var: {}\n", bv3 << 4);
|
||||
print("shr-var: {}\n", bv1 >> 4);
|
||||
print("bnot-var: {}\n", ~bv2);
|
||||
|
||||
// Bitwise compound assignment
|
||||
bca := 0xFF;
|
||||
bca &= 0x0F;
|
||||
print("and-assign: {}\n", bca);
|
||||
bco := 0x0F;
|
||||
bco |= 0xF0;
|
||||
print("or-assign: {}\n", bco);
|
||||
bcx := 0xFF;
|
||||
bcx ^= 0x0F;
|
||||
print("xor-assign: {}\n", bcx);
|
||||
bcs := 1;
|
||||
bcs <<= 8;
|
||||
print("shl-assign: {}\n", bcs);
|
||||
bcr := 256;
|
||||
bcr >>= 4;
|
||||
print("shr-assign: {}\n", bcr);
|
||||
|
||||
// Modulo on variables
|
||||
mv1 := 17;
|
||||
mv2 := 5;
|
||||
print("mod-var: {}\n", mv1 % mv2);
|
||||
|
||||
// Logical (short-circuit)
|
||||
print("and: {}\n", true and true);
|
||||
print("and-false: {}\n", true and false);
|
||||
print("or: {}\n", false or true);
|
||||
print("or-false: {}\n", false or false);
|
||||
|
||||
// Short-circuit verification
|
||||
print("short-and: {}\n", false and true);
|
||||
print("short-or: {}\n", true or false);
|
||||
|
||||
// Compound assignment
|
||||
ca := 10;
|
||||
ca += 5;
|
||||
print("ca+=: {}\n", ca);
|
||||
ca -= 3;
|
||||
print("ca-=: {}\n", ca);
|
||||
ca *= 2;
|
||||
print("ca*=: {}\n", ca);
|
||||
ca /= 6;
|
||||
print("ca/=: {}\n", ca);
|
||||
|
||||
// Precedence
|
||||
print("prec1: {}\n", 2 + 3 * 4);
|
||||
print("prec2: {}\n", (2 + 3) * 4);
|
||||
|
||||
// xx explicit cast
|
||||
big2 : f64 = 200.7;
|
||||
small : u8 = xx big2;
|
||||
print("xx-cast: {}\n", small);
|
||||
|
||||
// Implicit widening conversions
|
||||
wu : u8 = 200;
|
||||
ws : s64 = wu;
|
||||
print("widen-u8-s64: {}\n", ws);
|
||||
|
||||
wi3 : s32 = 42;
|
||||
wf : f64 = wi3;
|
||||
print("widen-s32-f64: {}\n", wf);
|
||||
|
||||
wf32 : f32 = 1.5;
|
||||
wf64 : f64 = wf32;
|
||||
print("widen-f32-f64: {}\n", wf64);
|
||||
|
||||
wu2 : u8 = 100;
|
||||
ws2 : s16 = wu2;
|
||||
print("widen-u8-s16: {}\n", ws2);
|
||||
|
||||
// More xx narrowing
|
||||
xl : s64 = 12345;
|
||||
xs : s32 = xx xl;
|
||||
print("xx-s64-s32: {}\n", xs);
|
||||
|
||||
xd : f64 = 1.5;
|
||||
xf : f32 = xx xd;
|
||||
print("xx-f64-f32: {}\n", xf);
|
||||
|
||||
xdf : f64 = 7.9;
|
||||
xdi : s32 = xx xdf;
|
||||
print("xx-f64-s32: {}\n", xdi);
|
||||
}
|
||||
201
examples/0027-basic-control-flow.sx
Normal file
201
examples/0027-basic-control-flow.sx
Normal file
@@ -0,0 +1,201 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 4. CONTROL FLOW
|
||||
// ========================================================
|
||||
print("=== 4. Control Flow ===\n");
|
||||
|
||||
// If-then-else (inline, as expression)
|
||||
ite := if true then 1 else 2;
|
||||
print("ite: {}\n", ite);
|
||||
|
||||
// If-then-else both branches
|
||||
ie_a := if true then 10 else 20;
|
||||
ie_b := if false then 10 else 20;
|
||||
print("ite-both: {} {}\n", ie_a, ie_b);
|
||||
|
||||
// If block
|
||||
if 1 < 2 {
|
||||
print("if-block: yes\n");
|
||||
}
|
||||
|
||||
// If without else (statement)
|
||||
if false { print("should-not-print\n"); }
|
||||
print("if-no-else: after\n");
|
||||
|
||||
// Nested if
|
||||
nx := 10;
|
||||
if nx > 5 {
|
||||
if nx > 8 {
|
||||
print("nested-if: deep\n");
|
||||
}
|
||||
}
|
||||
|
||||
// If-else-if chain
|
||||
eiv := 2;
|
||||
if eiv == 1 {
|
||||
print("if-else-if: first\n");
|
||||
} else if eiv == 2 {
|
||||
print("if-else-if: second\n");
|
||||
} else {
|
||||
print("if-else-if: other\n");
|
||||
}
|
||||
|
||||
// If block as expression
|
||||
ibe := 10 + if true { 5; } else { 0; };
|
||||
print("if-block-expr: {}\n", ibe);
|
||||
|
||||
// While basic
|
||||
wi := 0;
|
||||
while wi < 5 { wi += 1; }
|
||||
print("while: {}\n", wi);
|
||||
|
||||
// While with false condition (never executes)
|
||||
while false { print("should-not-print\n"); }
|
||||
print("while-false: skipped\n");
|
||||
|
||||
// While with break
|
||||
wb := 0;
|
||||
while wb < 100 {
|
||||
if wb == 7 { break; }
|
||||
wb += 1;
|
||||
}
|
||||
print("while-break: {}\n", wb);
|
||||
|
||||
// While with continue
|
||||
wsum := 0;
|
||||
wc := 0;
|
||||
while wc < 10 {
|
||||
wc += 1;
|
||||
if wc % 2 == 0 { continue; }
|
||||
wsum += wc;
|
||||
}
|
||||
print("while-continue: {}\n", wsum);
|
||||
|
||||
// While sum 1..10
|
||||
wsum2 := 0;
|
||||
wi2 := 1;
|
||||
while wi2 <= 10 {
|
||||
wsum2 += wi2;
|
||||
wi2 += 1;
|
||||
}
|
||||
print("while-sum: {}\n", wsum2);
|
||||
|
||||
// Nested while
|
||||
nw_outer := 0;
|
||||
nw_count := 0;
|
||||
while nw_outer < 3 {
|
||||
nw_inner := 0;
|
||||
while nw_inner < 3 {
|
||||
nw_count += 1;
|
||||
nw_inner += 1;
|
||||
}
|
||||
nw_outer += 1;
|
||||
}
|
||||
print("nested-while: {}\n", nw_count);
|
||||
|
||||
// Nested while with break in inner
|
||||
nb_outer := 0;
|
||||
nb_icount := 0;
|
||||
while nb_outer < 5 {
|
||||
nb_i := 0;
|
||||
while nb_i < 5 {
|
||||
if nb_i == 1 { break; }
|
||||
nb_i += 1;
|
||||
}
|
||||
nb_icount += nb_i;
|
||||
nb_outer += 1;
|
||||
if nb_outer == 2 { break; }
|
||||
}
|
||||
print("nested-break: {} {}\n", nb_outer, nb_icount);
|
||||
|
||||
// For loop basic
|
||||
farr : [4]s32 = .[10, 20, 30, 40];
|
||||
out("for:");
|
||||
for farr: (it) {
|
||||
out(" ");
|
||||
out(int_to_string(it));
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with print
|
||||
out("for-print:");
|
||||
for farr: (it) {
|
||||
print(" {}", it);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with index
|
||||
out("for-idx:");
|
||||
for farr: (_, ix) {
|
||||
out(" ");
|
||||
out(int_to_string(ix));
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with print two args
|
||||
out("for-2arg:");
|
||||
for farr: (it, ix) {
|
||||
print(" {}@{}", it, ix);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with break
|
||||
out("for-break:");
|
||||
for farr: (it) {
|
||||
if it == 30 { break; }
|
||||
print(" {}", it);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with continue
|
||||
out("for-continue:");
|
||||
for farr: (it) {
|
||||
if it == 20 { continue; }
|
||||
print(" {}", it);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For on slice
|
||||
fsl : []s32 = .[10, 20, 30];
|
||||
out("for-slice:");
|
||||
for fsl: (it) {
|
||||
print(" {}", it);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For on slice with index
|
||||
out("for-slice-idx:");
|
||||
for fsl: (it, ix) {
|
||||
print(" {}:{}", ix, it);
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// Nested for
|
||||
nf_a : [2]s32 = .[0, 1];
|
||||
nf_b : [2]s32 = .[0, 1];
|
||||
out("for-nested:");
|
||||
for nf_a: (oa) {
|
||||
for nf_b: (ob) {
|
||||
print(" ({},{})", oa, ob);
|
||||
}
|
||||
}
|
||||
out("\n");
|
||||
|
||||
// For with break preserving index
|
||||
fbi : [5]s32 = .[10, 20, 30, 40, 50];
|
||||
fbi_idx := 0;
|
||||
for fbi: (it, ix) {
|
||||
if it == 30 { fbi_idx = ix; break; }
|
||||
}
|
||||
print("for-break-idx: {}\n", fbi_idx);
|
||||
|
||||
// Multiple print placeholders
|
||||
print("multi: {} {} {}\n", 1, 2, 3);
|
||||
}
|
||||
106
examples/0028-basic-functions.sx
Normal file
106
examples/0028-basic-functions.sx
Normal file
@@ -0,0 +1,106 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
mul :: (a: s32, b: s32) -> s32 { a * b; }
|
||||
|
||||
identity :: (x: $T) -> T { x; }
|
||||
|
||||
pair_add :: (a: $T, b: $U) -> s64 {
|
||||
cast(s64) a + cast(s64) b;
|
||||
}
|
||||
|
||||
typed_sum :: (..args: []s32) -> s32 {
|
||||
result := 0;
|
||||
for args: (it) { result = result + it; }
|
||||
result;
|
||||
}
|
||||
|
||||
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
void_return :: () {
|
||||
return;
|
||||
}
|
||||
|
||||
implicit_return :: (x: s32) -> s32 {
|
||||
x * 2;
|
||||
}
|
||||
|
||||
early_return :: (x: s32) -> s32 {
|
||||
if x > 10 { return 99; }
|
||||
x;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 5. FUNCTIONS & DECLARATIONS
|
||||
// ========================================================
|
||||
print("=== 5. Functions ===\n");
|
||||
|
||||
// Constant binding
|
||||
FORTY_TWO :: 42;
|
||||
print("const: {}\n", FORTY_TWO);
|
||||
|
||||
// Typed constant
|
||||
TYPED_PI : f64 : 3.14;
|
||||
print("typed-const: {}\n", TYPED_PI);
|
||||
|
||||
// Variable with default init
|
||||
di : s32;
|
||||
print("default-init: {}\n", di);
|
||||
|
||||
// Implicit return
|
||||
print("implicit-ret: {}\n", implicit_return(21));
|
||||
|
||||
// Explicit return
|
||||
print("early-ret: {}\n", early_return(5));
|
||||
print("early-ret2: {}\n", early_return(20));
|
||||
|
||||
// Void return
|
||||
void_return();
|
||||
print("void-return: ok\n");
|
||||
|
||||
// Generic — single param
|
||||
print("generic-s32: {}\n", identity(42));
|
||||
print("generic-f32: {}\n", identity(1.5));
|
||||
print("generic-bool: {}\n", identity(true));
|
||||
|
||||
// Generic — multiple params
|
||||
print("generic-multi: {}\n", pair_add(10, 20));
|
||||
|
||||
// Lambda
|
||||
double :: (x: s32) => x * 2;
|
||||
print("lambda: {}\n", double(7));
|
||||
|
||||
// Lambda with return type
|
||||
halve :: (x: f32) -> f32 => x / 2.0;
|
||||
print("lambda-ret: {}\n", halve(10.0));
|
||||
|
||||
// Local function (non-lambda)
|
||||
local_add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
print("local-fn: {}\n", local_add(3, 4));
|
||||
|
||||
// Nested function calls
|
||||
print("fn-nested: {}\n", add(mul(2, 3), mul(4, 5)));
|
||||
|
||||
// Variadic (typed)
|
||||
print("varargs: {}\n", typed_sum(1, 2, 3, 4, 5));
|
||||
|
||||
// Spread
|
||||
spread_arr : [3]s32 = .[10, 20, 30];
|
||||
print("spread: {}\n", typed_sum(..spread_arr));
|
||||
|
||||
// Function pointers
|
||||
fp : (s32, s32) -> s32 = add;
|
||||
print("fp: {}\n", fp(3, 4));
|
||||
fp = mul;
|
||||
print("fp-reassign: {}\n", fp(3, 4));
|
||||
print("fp-apply: {}\n", apply(add, 10, 20));
|
||||
}
|
||||
79
examples/0029-basic-scoping.sx
Normal file
79
examples/0029-basic-scoping.sx
Normal file
@@ -0,0 +1,79 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 6. SCOPING & DEFER
|
||||
// ========================================================
|
||||
print("=== 6. Scoping ===\n");
|
||||
|
||||
// Scope block with shadowing
|
||||
sv := 100;
|
||||
{
|
||||
sv := 200;
|
||||
print("inner: {}\n", sv);
|
||||
}
|
||||
print("outer: {}\n", sv);
|
||||
|
||||
// Shadow with different type
|
||||
st_v := 42;
|
||||
print("shadow-type: {}\n", st_v);
|
||||
{
|
||||
st_v := 3.14;
|
||||
print("shadow-type: {}\n", st_v);
|
||||
}
|
||||
|
||||
// Nested scopes (3 levels)
|
||||
nv := 1;
|
||||
{
|
||||
nv := 2;
|
||||
{
|
||||
nv := 3;
|
||||
print("nest3: {}\n", nv);
|
||||
}
|
||||
print("nest2: {}\n", nv);
|
||||
}
|
||||
print("nest1: {}\n", nv);
|
||||
|
||||
// Scope isolation
|
||||
{ iso := 100; print("scope-isolate: {}\n", iso); }
|
||||
|
||||
// Reuse name after scope exit
|
||||
sr := 1;
|
||||
print("scope-reuse: {}\n", sr);
|
||||
{ sr := 2; print("scope-reuse: {}\n", sr); }
|
||||
print("scope-reuse: {}\n", sr);
|
||||
|
||||
// Multiple defers (LIFO order)
|
||||
{
|
||||
defer print("defer-c\n");
|
||||
defer print("defer-b\n");
|
||||
defer print("defer-a\n");
|
||||
}
|
||||
|
||||
// Four defers
|
||||
{
|
||||
defer print("d1\n");
|
||||
defer print("d2\n");
|
||||
defer print("d3\n");
|
||||
defer print("d4\n");
|
||||
}
|
||||
|
||||
// Defer in nested scopes
|
||||
{
|
||||
defer print("outer-defer\n");
|
||||
{
|
||||
defer print("inner-defer\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Defer in if block
|
||||
if true {
|
||||
defer print("defer-in-if: deferred\n");
|
||||
print("defer-in-if: body\n");
|
||||
}
|
||||
}
|
||||
127
examples/0030-basic-builtins.sx
Normal file
127
examples/0030-basic-builtins.sx
Normal file
@@ -0,0 +1,127 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 7. BUILT-IN FUNCTIONS
|
||||
// ========================================================
|
||||
print("=== 7. Builtins ===\n");
|
||||
|
||||
// out
|
||||
out("out-ok\n");
|
||||
|
||||
// sqrt
|
||||
print("sqrt: {}\n", sqrt(9.0));
|
||||
print("sqrt-f64: {}\n", sqrt(16.0));
|
||||
|
||||
// size_of
|
||||
print("sizeof-s32: {}\n", size_of(s32));
|
||||
print("sizeof-f64: {}\n", size_of(f64));
|
||||
print("sizeof-struct: {}\n", size_of(Point));
|
||||
|
||||
// align_of
|
||||
print("alignof-u8: {}\n", align_of(u8));
|
||||
print("alignof-s32: {}\n", align_of(s32));
|
||||
print("alignof-s64: {}\n", align_of(s64));
|
||||
print("alignof-struct: {}\n", align_of(Point));
|
||||
|
||||
// type_of + category matching
|
||||
tv := 42;
|
||||
ttype := type_of(tv);
|
||||
if ttype == {
|
||||
case int: print("typeof: int\n");
|
||||
case float: print("typeof: float\n");
|
||||
else: print("typeof: other\n");
|
||||
}
|
||||
|
||||
// type_of — float
|
||||
tf := 3.14;
|
||||
if type_of(tf) == {
|
||||
case float: print("typeof-float: float\n");
|
||||
else: print("typeof-float: other\n");
|
||||
}
|
||||
|
||||
// type_of — string
|
||||
ts := "hello";
|
||||
if type_of(ts) == {
|
||||
case string: print("typeof-string: string\n");
|
||||
else: print("typeof-string: other\n");
|
||||
}
|
||||
|
||||
// type_of — bool
|
||||
tb := true;
|
||||
if type_of(tb) == {
|
||||
case bool: print("typeof-bool: bool\n");
|
||||
else: print("typeof-bool: other\n");
|
||||
}
|
||||
|
||||
// type_of — struct
|
||||
tst := Point.{ 1, 2 };
|
||||
if type_of(tst) == {
|
||||
case struct: print("typeof-struct: struct\n");
|
||||
else: print("typeof-struct: other\n");
|
||||
}
|
||||
|
||||
// type_of — enum
|
||||
ten : Color = .red;
|
||||
if type_of(ten) == {
|
||||
case enum: print("typeof-enum: enum\n");
|
||||
else: print("typeof-enum: other\n");
|
||||
}
|
||||
|
||||
// type_name
|
||||
print("typename: {}\n", type_name(Point));
|
||||
|
||||
// field_count on struct
|
||||
print("fieldcount: {}\n", field_count(Point));
|
||||
|
||||
// field_count on enum
|
||||
print("fieldcount-enum: {}\n", field_count(Color));
|
||||
|
||||
// field_name on struct
|
||||
print("fieldname0: {}\n", field_name(Point, 0));
|
||||
print("fieldname1: {}\n", field_name(Point, 1));
|
||||
|
||||
// field_name on enum
|
||||
print("fieldname-enum0: {}\n", field_name(Color, 0));
|
||||
print("fieldname-enum2: {}\n", field_name(Color, 2));
|
||||
|
||||
// field_value (use any_to_string to avoid sext-on-Any bug)
|
||||
fv_pt := Point.{ 11, 22 };
|
||||
out("fieldval0: ");
|
||||
out(any_to_string(field_value(fv_pt, 0)));
|
||||
out("\n");
|
||||
out("fieldval1: ");
|
||||
out(any_to_string(field_value(fv_pt, 1)));
|
||||
out("\n");
|
||||
|
||||
// field_index on plain enum
|
||||
fi_c : Color = .green;
|
||||
print("fieldidx: {}\n", field_index(Color, fi_c));
|
||||
|
||||
// field_index on tagged enum
|
||||
fi_sh : Shape = .circle(1.0);
|
||||
print("fieldidx-tagged: {}\n", field_index(Shape, fi_sh));
|
||||
fi_sh2 : Shape = .none;
|
||||
print("fieldidx-tagged2: {}\n", field_index(Shape, fi_sh2));
|
||||
|
||||
// cast
|
||||
cval : f64 = 3.7;
|
||||
print("cast: {}\n", cast(s32) cval);
|
||||
cv2 : s32 = 42;
|
||||
print("cast-int-f64: {}\n", cast(f64) cv2);
|
||||
}
|
||||
30
examples/0031-basic-local-fn-return.sx
Normal file
30
examples/0031-basic-local-fn-return.sx
Normal file
@@ -0,0 +1,30 @@
|
||||
#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; }
|
||||
|
||||
Shape :: enum {
|
||||
circle: f32;
|
||||
rect: struct { w, h: f32; };
|
||||
none;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 19. LOCAL FUNCTION RETURNING STRUCT/ENUM
|
||||
// ========================================================
|
||||
print("=== 19. Local Fn Return ===\n");
|
||||
{
|
||||
local_pt :: () -> Point { Point.{42, 99}; }
|
||||
lp := local_pt();
|
||||
print("local-struct: {} {}\n", lp.x, lp.y);
|
||||
|
||||
local_sh :: () -> Shape { .circle(2.5); }
|
||||
ls := local_sh();
|
||||
print("local-enum: {}\n", ls);
|
||||
}
|
||||
}
|
||||
24
examples/0032-basic-ufcs-return-type.sx
Normal file
24
examples/0032-basic-ufcs-return-type.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
#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; }
|
||||
|
||||
point_sum :: (p: Point) -> s32 { p.x + p.y; }
|
||||
|
||||
// #run compile-time constants
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 20. PIPE UFCS RETURN TYPE INFERENCE
|
||||
// ========================================================
|
||||
print("=== 20. UFCS Return Type ===\n");
|
||||
{
|
||||
p := Point.{3, 4};
|
||||
print("direct: {}\n", point_sum(p));
|
||||
print("ufcs: {}\n", p |> point_sum());
|
||||
}
|
||||
}
|
||||
22
examples/0033-basic-if-struct.sx
Normal file
22
examples/0033-basic-if-struct.sx
Normal file
@@ -0,0 +1,22 @@
|
||||
#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; }
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 22. IF-EXPRESSION RETURNING STRUCT
|
||||
// ========================================================
|
||||
print("=== 22. If-Struct ===\n");
|
||||
{
|
||||
flag := true;
|
||||
p := if flag { Point.{10, 20}; } else { Point.{30, 40}; };
|
||||
print("if-struct: {} {}\n", p.x, p.y);
|
||||
q := if !flag { Point.{10, 20}; } else { Point.{30, 40}; };
|
||||
print("else-struct: {} {}\n", q.x, q.y);
|
||||
}
|
||||
}
|
||||
23
examples/0034-basic-string-comparison.sx
Normal file
23
examples/0034-basic-string-comparison.sx
Normal file
@@ -0,0 +1,23 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 24. STRING COMPARISON
|
||||
// ========================================================
|
||||
print("=== 24. String Comparison ===\n");
|
||||
{
|
||||
a := "hello";
|
||||
b := "hello";
|
||||
c := "world";
|
||||
print("str-eq: {}\n", a == b);
|
||||
print("str-neq: {}\n", a != c);
|
||||
print("str-diff: {}\n", a == c);
|
||||
empty := "";
|
||||
print("empty-eq: {}\n", empty == "");
|
||||
}
|
||||
}
|
||||
24
examples/0035-basic-array-loop-mutation.sx
Normal file
24
examples/0035-basic-array-loop-mutation.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 25. ARRAY LOOP MUTATION
|
||||
// ========================================================
|
||||
print("=== 25. Array Loop Mutation ===\n");
|
||||
{
|
||||
arr : [4]s32 = .[0, 0, 0, 0];
|
||||
i := 0;
|
||||
while i < 4 {
|
||||
arr[i] = xx (i + 1);
|
||||
i += 1;
|
||||
}
|
||||
print("loop-fill: {} {} {} {}\n", arr[0], arr[1], arr[2], arr[3]);
|
||||
arr[2] += 10;
|
||||
print("compound: {}\n", arr[2]);
|
||||
}
|
||||
}
|
||||
42
examples/0036-basic-ufcs-aliases.sx
Normal file
42
examples/0036-basic-ufcs-aliases.sx
Normal file
@@ -0,0 +1,42 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- UFCS Aliases & Pipe ---
|
||||
{
|
||||
print("=== UFCS Aliases ===\n");
|
||||
|
||||
num_sum :: (a: s64, b: s64) -> s64 { a + b; }
|
||||
sum :: ufcs num_sum;
|
||||
|
||||
print("{}\n", num_sum(40, 2)); // 42 — direct call
|
||||
print("{}\n", sum(40, 2)); // 42 — alias direct call
|
||||
print("{}\n", 40 |> sum(2)); // 42 — pipe UFCS via alias
|
||||
|
||||
print("{}\n", num_sum(40, 2)); // 42 — direct (was tuple full-splat)
|
||||
print("{}\n", 40 |> sum(2)); // 42 — pipe (was tuple partial-splat)
|
||||
|
||||
compute :: (a: s64, b: s64, c: s64, d: s64) -> s64 { a + b * c - d; }
|
||||
calc :: ufcs compute;
|
||||
|
||||
print("{}\n", compute(1, 2, 3, 4)); // 1+2*3-4 = 3 (was tuple full-splat)
|
||||
print("{}\n", compute(1, 2, 3, 4)); // same = 3 (was tuple partial-splat)
|
||||
print("{}\n", 1 |> calc(2, 3, 4)); // same = 3 — pipe UFCS
|
||||
|
||||
// Tuple return type
|
||||
swap :: (a: s64, b: s64) -> (s64, s64) { (b, a); }
|
||||
s := swap(1, 2);
|
||||
a := s.0;
|
||||
b := s.1;
|
||||
print("{}\n", a); // 2
|
||||
print("{}\n", b); // 1
|
||||
|
||||
wrap :: (x: s64) -> (s64) { (x,); }
|
||||
t := wrap(99);
|
||||
print("{}\n", t.0); // 99
|
||||
}
|
||||
}
|
||||
36
examples/0037-basic-trailing-commas.sx
Normal file
36
examples/0037-basic-trailing-commas.sx
Normal file
@@ -0,0 +1,36 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
main :: () {
|
||||
|
||||
// ── Trailing commas ──────────────────────────────────────────
|
||||
print("=== Trailing Commas ===\n");
|
||||
{
|
||||
// Struct literal with trailing comma
|
||||
Vec4 :: struct { x: f64; y: f64; z: f64; w: f64; }
|
||||
v := Vec4.{
|
||||
x = 1.0,
|
||||
y = 2.0,
|
||||
z = 3.0,
|
||||
w = 4.0,
|
||||
};
|
||||
assert(v.x == 1.0);
|
||||
assert(v.w == 4.0);
|
||||
|
||||
// Function call with trailing comma
|
||||
add :: (a: s64, b: s64) -> s64 { return a + b; }
|
||||
r := add(10, 20,);
|
||||
assert(r == 30);
|
||||
|
||||
// Array literal with trailing comma
|
||||
arr := s64.[1, 2, 3,];
|
||||
assert(arr[2] == 3);
|
||||
|
||||
print("trailing commas ok\n");
|
||||
}
|
||||
}
|
||||
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]);
|
||||
}
|
||||
106
examples/0122-types-flags.sx
Normal file
106
examples/0122-types-flags.sx
Normal file
@@ -0,0 +1,106 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
Perms :: enum flags { read; write; execute; }
|
||||
|
||||
WindowFlags :: enum flags u32 { vsync :: 64; resizable :: 4; hidden :: 128; }
|
||||
|
||||
// --- Top-level functions ---
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 9. FLAGS
|
||||
// ========================================================
|
||||
print("=== 9. Flags ===\n");
|
||||
|
||||
// Combine flags
|
||||
perm : Perms = .read | .write;
|
||||
print("flags: {}\n", perm);
|
||||
|
||||
// Test flag
|
||||
if perm & .read { print("has-read: yes\n"); }
|
||||
if perm & .execute { print("has-exec: yes\n"); }
|
||||
|
||||
// Test flag negative
|
||||
pt : Perms = .write;
|
||||
if pt & .read {
|
||||
print("flags-neg: has-read\n");
|
||||
} else {
|
||||
print("flags-neg: no-read\n");
|
||||
}
|
||||
|
||||
// Single flag
|
||||
ps : Perms = .execute;
|
||||
print("flags-single: {}\n", ps);
|
||||
|
||||
// All flags
|
||||
pall : Perms = .read | .write | .execute;
|
||||
print("flags-all: {}\n", pall);
|
||||
|
||||
// Cast to int
|
||||
print("flags-raw: {}\n", cast(s64) perm);
|
||||
|
||||
// Flags with explicit values
|
||||
wf : WindowFlags = .vsync | .resizable;
|
||||
print("flags-explicit: {}\n", wf);
|
||||
print("flags-explicit-raw: {}\n", cast(s64) wf);
|
||||
|
||||
// --- Multi-target assignment (swap) ---
|
||||
print("--- swap ---\n");
|
||||
|
||||
// Variable swap
|
||||
{
|
||||
sa := 10;
|
||||
sb := 20;
|
||||
sa, sb = sb, sa;
|
||||
print("var swap: {} {}\n", sa, sb);
|
||||
}
|
||||
|
||||
// Array element swap
|
||||
{
|
||||
sarr : [3]s64 = .[1, 2, 3];
|
||||
sarr[0], sarr[2] = sarr[2], sarr[0];
|
||||
print("arr swap: {} {}\n", sarr[0], sarr[2]);
|
||||
}
|
||||
|
||||
// 3-way rotation
|
||||
{
|
||||
ra := 1;
|
||||
rb := 2;
|
||||
rc := 3;
|
||||
ra, rb, rc = rc, ra, rb;
|
||||
print("3-way: {} {} {}\n", ra, rb, rc);
|
||||
}
|
||||
|
||||
// --- Tuple destructuring ---
|
||||
print("--- destructure ---\n");
|
||||
|
||||
// Basic tuple destructuring
|
||||
{
|
||||
da, db := (10, 20);
|
||||
print("basic: {} {}\n", da, db);
|
||||
}
|
||||
|
||||
// Destructure from function return
|
||||
{
|
||||
dswap :: (a: s64, b: s64) -> (s64, s64) { (b, a); }
|
||||
dx, dy := dswap(1, 2);
|
||||
print("fn: {} {}\n", dx, dy);
|
||||
}
|
||||
|
||||
// Discard with _
|
||||
{
|
||||
_, dsecond := (100, 200);
|
||||
print("discard: {}\n", dsecond);
|
||||
}
|
||||
|
||||
// Three elements
|
||||
{
|
||||
da3, db3, dc3 := (1, 2, 3);
|
||||
print("triple: {} {} {}\n", da3, db3, dc3);
|
||||
}
|
||||
}
|
||||
24
examples/0123-types-compound-assign.sx
Normal file
24
examples/0123-types-compound-assign.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 16. COMPOUND ASSIGNMENT TYPE CONVERSION
|
||||
// ========================================================
|
||||
print("=== 16. Compound Assign ===\n");
|
||||
{
|
||||
ca_a : f64 = 10.0;
|
||||
ca_b : f32 = 3.0;
|
||||
ca_a += ca_b;
|
||||
print("f64+=f32: {}\n", ca_a);
|
||||
|
||||
ca_c : s64 = 100;
|
||||
ca_d : s32 = 7;
|
||||
ca_c -= ca_d;
|
||||
print("s64-=s32: {}\n", ca_c);
|
||||
}
|
||||
}
|
||||
23
examples/0124-types-array-of-structs.sx
Normal file
23
examples/0124-types-array-of-structs.sx
Normal file
@@ -0,0 +1,23 @@
|
||||
#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; }
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 18. ARRAYS OF USER-DEFINED TYPES
|
||||
// ========================================================
|
||||
print("=== 18. Array of Structs ===\n");
|
||||
{
|
||||
spts : [2]Point = .[Point.{1, 2}, Point.{3, 4}];
|
||||
spt2 := spts[1];
|
||||
print("arr-struct-x: {}\n", spt2.x);
|
||||
for spts: (it) {
|
||||
print("for-struct: {}\n", it);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
examples/0125-types-type-named-vars.sx
Normal file
19
examples/0125-types-type-named-vars.sx
Normal file
@@ -0,0 +1,19 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 21. TYPE-NAMED VARIABLES (s2, u8, etc.)
|
||||
// ========================================================
|
||||
print("=== 21. Type-Named Vars ===\n");
|
||||
{
|
||||
s2 := 42;
|
||||
print("s2: {}\n", s2);
|
||||
s2 = s2 + 1;
|
||||
print("s2+1: {}\n", s2);
|
||||
}
|
||||
}
|
||||
20
examples/0126-types-nested-arrays.sx
Normal file
20
examples/0126-types-nested-arrays.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 23. NESTED ARRAYS (2D)
|
||||
// ========================================================
|
||||
print("=== 23. Nested Arrays ===\n");
|
||||
{
|
||||
matrix : [2][3]s32 = .[ .[1, 2, 3], .[4, 5, 6] ];
|
||||
print("m[0][0]: {}\n", matrix[0][0]);
|
||||
print("m[0][2]: {}\n", matrix[0][2]);
|
||||
print("m[1][0]: {}\n", matrix[1][0]);
|
||||
print("m[1][2]: {}\n", matrix[1][2]);
|
||||
}
|
||||
}
|
||||
47
examples/0127-types-using.sx
Normal file
47
examples/0127-types-using.sx
Normal file
@@ -0,0 +1,47 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// === 26. #using struct composition ===
|
||||
print("=== 26. #using ===\n");
|
||||
{
|
||||
UBase :: struct { x: s32; y: s32; }
|
||||
UExt :: struct { #using UBase; z: s32; }
|
||||
e := UExt.{ x = 1, y = 2, z = 3 };
|
||||
print("using-x: {}\n", e.x);
|
||||
print("using-y: {}\n", e.y);
|
||||
print("using-z: {}\n", e.z);
|
||||
|
||||
// #using in middle position
|
||||
UHeader :: struct { version: s32; }
|
||||
UPacket :: struct { id: s32; #using UHeader; payload: s32; }
|
||||
p := UPacket.{ id = 10, version = 42, payload = 99 };
|
||||
print("pkt-id: {}\n", p.id);
|
||||
print("pkt-ver: {}\n", p.version);
|
||||
print("pkt-pay: {}\n", p.payload);
|
||||
|
||||
// Multiple #using
|
||||
UPos :: struct { px: s32; py: s32; }
|
||||
UCol :: struct { r: s32; g: s32; }
|
||||
USprite :: struct { #using UPos; #using UCol; scale: s32; }
|
||||
s := USprite.{ px = 10, py = 20, r = 255, g = 128, scale = 1 };
|
||||
print("sprite-px: {}\n", s.px);
|
||||
print("sprite-r: {}\n", s.r);
|
||||
print("sprite-scale: {}\n", s.scale);
|
||||
}
|
||||
|
||||
// --- Comptime format ---
|
||||
{
|
||||
ct_body :: "hello";
|
||||
ct_msg :: format("say: {} (len={})", ct_body, ct_body.len);
|
||||
print("{}\n", ct_msg);
|
||||
|
||||
ct_num :: 42;
|
||||
ct_num_msg :: format("n={}", ct_num);
|
||||
print("{}\n", ct_num_msg);
|
||||
}
|
||||
}
|
||||
27
examples/0128-types-tuples.sx
Normal file
27
examples/0128-types-tuples.sx
Normal file
@@ -0,0 +1,27 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- Tuples ---
|
||||
{
|
||||
print("=== Tuples ===\n");
|
||||
pair := (40, 2);
|
||||
print("{}\n", pair.0);
|
||||
print("{}\n", pair.1);
|
||||
|
||||
named := (x: 10, y: 20);
|
||||
print("{}\n", named.x);
|
||||
print("{}\n", named.0);
|
||||
|
||||
single := (42,);
|
||||
print("{}\n", single.0);
|
||||
|
||||
zeroed : (s32, s32) = ---;
|
||||
print("{}\n", zeroed.0);
|
||||
print("{}\n", zeroed.1);
|
||||
}
|
||||
}
|
||||
1200
examples/0129-types-tuple-operators.sx
Normal file
1200
examples/0129-types-tuple-operators.sx
Normal file
File diff suppressed because it is too large
Load Diff
27
examples/0130-types-struct-constants.sx
Normal file
27
examples/0130-types-struct-constants.sx
Normal file
@@ -0,0 +1,27 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
// ============================================================
|
||||
// Struct constants test
|
||||
Phys :: struct {
|
||||
x, y: f32;
|
||||
GRAVITY :f32: 9.81;
|
||||
MAX_SPEED :: 100;
|
||||
}
|
||||
|
||||
// Init block test struct
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- Struct Constants ---
|
||||
print("=== Struct Constants ===\n");
|
||||
{
|
||||
print("gravity: {}\n", Phys.GRAVITY); // gravity: 9.810000
|
||||
print("max speed: {}\n", Phys.MAX_SPEED); // max speed: 100
|
||||
p := Phys.{ x = 0.0, y = Phys.GRAVITY };
|
||||
print("p.y: {}\n", p.y); // p.y: 9.810000
|
||||
}
|
||||
}
|
||||
200
examples/0131-types-init-blocks.sx
Normal file
200
examples/0131-types-init-blocks.sx
Normal file
@@ -0,0 +1,200 @@
|
||||
#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; }
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> s32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> s32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: s32; }
|
||||
|
||||
impl Counter for SimpleCounter {
|
||||
inc :: (self: *SimpleCounter) { self.val += 1; }
|
||||
get :: (self: *SimpleCounter) -> s32 { self.val; }
|
||||
}
|
||||
|
||||
impl Summable for Point {
|
||||
sum :: (self: *Point) -> s32 { self.x + self.y; }
|
||||
}
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
|
||||
// Phase 7: Generic struct impls
|
||||
Pair :: struct ($T: Type) {
|
||||
a: T;
|
||||
b: T;
|
||||
}
|
||||
|
||||
impl Summable for Pair($T) {
|
||||
sum :: (self: *Pair(T)) -> s32 {
|
||||
xx self.a + xx self.b;
|
||||
}
|
||||
}
|
||||
|
||||
// P6.5: Struct type param constraints
|
||||
|
||||
// Init block test struct
|
||||
Builder :: struct {
|
||||
total: s32;
|
||||
count: s32;
|
||||
|
||||
add :: (self: *Builder, val: s32) {
|
||||
self.total += val;
|
||||
self.count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Global variable for address-of test
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- Init Blocks (IB) ---
|
||||
print("=== Init Blocks ===\n");
|
||||
|
||||
// IB1: basic init block with struct methods
|
||||
{
|
||||
b := Builder.{ total = 0, count = 0 } {
|
||||
self.add(10);
|
||||
self.add(20);
|
||||
self.add(30);
|
||||
};
|
||||
print("IB1: {} {}\n", b.total, b.count);
|
||||
}
|
||||
|
||||
// IB2: nested init blocks (self shadows correctly)
|
||||
{
|
||||
b1 := Builder.{ total = 0, count = 0 } {
|
||||
self.add(100);
|
||||
b2 := Builder.{ total = 0, count = 0 } {
|
||||
self.add(42);
|
||||
};
|
||||
self.add(b2.total);
|
||||
};
|
||||
print("IB2: {} {}\n", b1.total, b1.count);
|
||||
}
|
||||
|
||||
// IB3: empty init block
|
||||
{
|
||||
b := Builder.{ total = 5, count = 1 } {};
|
||||
print("IB3: {} {}\n", b.total, b.count);
|
||||
}
|
||||
|
||||
// IB4: conditional inside init block
|
||||
{
|
||||
add_extra := true;
|
||||
b := Builder.{ total = 0, count = 0 } {
|
||||
self.add(10);
|
||||
if add_extra {
|
||||
self.add(90);
|
||||
}
|
||||
};
|
||||
print("IB4: {}\n", b.total);
|
||||
}
|
||||
|
||||
// IB5: init block + auto type erasure combined
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
|
||||
result := use_counter(SimpleCounter.{ val = 0 } {
|
||||
self.val = 50;
|
||||
});
|
||||
print("IB5: {}\n", result);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// SECTION: Struct static method shorthand (.method(args) syntax)
|
||||
// ============================================================
|
||||
print("--- struct static method shorthand ---\n");
|
||||
|
||||
// SM1: Basic shorthand — .create(args) resolves to Dims.create(args)
|
||||
{
|
||||
Dims :: struct {
|
||||
w: f32;
|
||||
h: f32;
|
||||
|
||||
create :: (w: f32, h: f32) -> Dims {
|
||||
Dims.{ w = w, h = h };
|
||||
}
|
||||
|
||||
square :: (size: f32) -> Dims {
|
||||
Dims.{ w = size, h = size };
|
||||
}
|
||||
}
|
||||
use_dims :: (d: Dims) { print("SM1: {} {}\n", d.w, d.h); }
|
||||
use_dims(.create(16.0, 8.0));
|
||||
use_dims(.square(5.0));
|
||||
}
|
||||
|
||||
// SM2: Shorthand in variable declaration with explicit type
|
||||
{
|
||||
Pair :: struct {
|
||||
a: s64;
|
||||
b: s64;
|
||||
|
||||
make :: (a: s64, b: s64) -> Pair {
|
||||
Pair.{ a = a, b = b };
|
||||
}
|
||||
}
|
||||
p : Pair = .make(10, 20);
|
||||
print("SM2: {} {}\n", p.a, p.b);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// OPTIONAL IF-ELSE COERCION
|
||||
// ============================================================
|
||||
{
|
||||
print("--- optional if-else coercion ---\n");
|
||||
OptF :: struct { width: ?f32; }
|
||||
x :f32: 10.0;
|
||||
|
||||
// null in then branch
|
||||
f1 := OptF.{ width = if true then null else x };
|
||||
print("opt-if1: {}\n", f1.width ?? 99.0);
|
||||
|
||||
// value in then branch, null in else
|
||||
f2 := OptF.{ width = if true then x else null };
|
||||
print("opt-if2: {}\n", f2.width ?? 99.0);
|
||||
|
||||
// both branches are values
|
||||
f3 := OptF.{ width = if false then 5.0 else x };
|
||||
print("opt-if3: {}\n", f3.width ?? 99.0);
|
||||
|
||||
// standalone optional variable
|
||||
val: ?f32 = if true then null else 42.0;
|
||||
print("opt-if4: {}\n", val ?? 0.0);
|
||||
|
||||
val2: ?f32 = if false then null else 42.0;
|
||||
print("opt-if5: {}\n", val2 ?? 0.0);
|
||||
}
|
||||
|
||||
// --- usize / isize ---
|
||||
{
|
||||
a : usize = 42;
|
||||
b : isize = 0 - 7;
|
||||
print("usize: {}\n", a);
|
||||
print("isize: {}\n", b);
|
||||
|
||||
// arithmetic
|
||||
c : usize = a + 8;
|
||||
print("usize+8: {}\n", c);
|
||||
|
||||
// coercion from s32
|
||||
x : s32 = 10;
|
||||
y : usize = xx x;
|
||||
print("s32->usize: {}\n", y);
|
||||
|
||||
// coercion to s64
|
||||
z : s64 = xx a;
|
||||
print("usize->s64: {}\n", z);
|
||||
}
|
||||
}
|
||||
617
examples/0415-protocols-protocols.sx
Normal file
617
examples/0415-protocols-protocols.sx
Normal file
@@ -0,0 +1,617 @@
|
||||
#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 = ---;
|
||||
}
|
||||
|
||||
OptNode :: struct {
|
||||
value: s32;
|
||||
next: ?s32;
|
||||
}
|
||||
|
||||
OptInner :: struct { val: s32; }
|
||||
|
||||
OptOuter :: struct { inner: ?OptInner; }
|
||||
|
||||
MyFloat :: f64;
|
||||
|
||||
Perms :: enum flags { read; write; execute; }
|
||||
|
||||
Status :: enum u8 { ok; err; timeout; }
|
||||
|
||||
WindowFlags :: enum flags u32 { vsync :: 64; resizable :: 4; hidden :: 128; }
|
||||
|
||||
// --- Top-level functions ---
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
mul :: (a: s32, b: s32) -> s32 { a * b; }
|
||||
|
||||
identity :: (x: $T) -> T { x; }
|
||||
|
||||
pair_add :: (a: $T, b: $U) -> s64 {
|
||||
cast(s64) a + cast(s64) b;
|
||||
}
|
||||
|
||||
typed_sum :: (..args: []s32) -> s32 {
|
||||
result := 0;
|
||||
for args: (it) { result = result + it; }
|
||||
result;
|
||||
}
|
||||
|
||||
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
void_return :: () {
|
||||
return;
|
||||
}
|
||||
|
||||
implicit_return :: (x: s32) -> s32 {
|
||||
x * 2;
|
||||
}
|
||||
|
||||
early_return :: (x: s32) -> s32 {
|
||||
if x > 10 { return 99; }
|
||||
x;
|
||||
}
|
||||
|
||||
vec3 :: (x: f32, y: f32, z: f32) -> Vector(3, f32) {
|
||||
.[x, y, z];
|
||||
}
|
||||
|
||||
point_sum :: (p: Point) -> s32 { p.x + p.y; }
|
||||
|
||||
// #run compile-time constants
|
||||
|
||||
// #run compile-time constants
|
||||
CT_VAL :: #run add(10, 15);
|
||||
|
||||
CT_MUL :: #run mul(6, 7);
|
||||
|
||||
CT_CHAIN :: #run add(CT_VAL, 5);
|
||||
|
||||
// #run compile-time optional tests
|
||||
|
||||
// #run compile-time optional tests
|
||||
ct_opt_coalesce :: () -> s32 {
|
||||
x: ?s32 = 42;
|
||||
y: ?s32 = null;
|
||||
return (x ?? 0) + (y ?? 99);
|
||||
}
|
||||
|
||||
ct_opt_unwrap :: () -> s32 {
|
||||
x: ?s32 = 77;
|
||||
return x!;
|
||||
}
|
||||
|
||||
ct_opt_guard :: () -> s32 {
|
||||
x: ?s32 = 10;
|
||||
if x == null { return -1; }
|
||||
return x;
|
||||
}
|
||||
|
||||
CT_OPT_COALESCE :: #run ct_opt_coalesce();
|
||||
|
||||
CT_OPT_UNWRAP :: #run ct_opt_unwrap();
|
||||
|
||||
CT_OPT_GUARD :: #run ct_opt_guard();
|
||||
|
||||
// #insert helpers
|
||||
|
||||
// #insert helpers
|
||||
gen_code :: () -> string {
|
||||
return "print(\"insert-ok\\n\");";
|
||||
}
|
||||
|
||||
gen_val :: () -> string {
|
||||
return "print(\"insert-gen: {}\\n\", 42);";
|
||||
}
|
||||
|
||||
// --- Error handling (failable functions: sets, raise/try/catch/or/onfail) ---
|
||||
|
||||
SmokeErr :: error { Empty, BadDigit, Overflow }
|
||||
|
||||
// value-carrying, named set: raise three tags or succeed
|
||||
|
||||
// value-carrying, named set: raise three tags or succeed
|
||||
sm_parse :: (n: s32) -> (s32, !SmokeErr) {
|
||||
if n < 0 { raise error.BadDigit; }
|
||||
if n == 0 { raise error.Empty; }
|
||||
if n > 99 { raise error.Overflow; }
|
||||
return n * 2;
|
||||
}
|
||||
|
||||
// pure failable, inferred set (ad-hoc tag minted into `!`)
|
||||
|
||||
// pure failable, inferred set (ad-hoc tag minted into `!`)
|
||||
sm_check :: (ok: bool) -> ! {
|
||||
if !ok { raise error.NotReady; }
|
||||
return;
|
||||
}
|
||||
|
||||
// multi-value, inferred set: `try` propagates; the SCC pass absorbs SmokeErr
|
||||
|
||||
// multi-value, inferred set: `try` propagates; the SCC pass absorbs SmokeErr
|
||||
sm_pair :: (a: s32, b: s32) -> (s32, s32, !) {
|
||||
x := try sm_parse(a);
|
||||
y := try sm_parse(b);
|
||||
return (x, y);
|
||||
}
|
||||
|
||||
// `catch` block that diverges (logs the tag, then returns a fallback)
|
||||
|
||||
// `catch` block that diverges (logs the tag, then returns a fallback)
|
||||
sm_or_default :: (n: s32) -> s32 {
|
||||
return sm_parse(n) catch e {
|
||||
print(" logged {}\n", e);
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// `onfail` + `defer` interleave: cleanup runs only on the error path
|
||||
|
||||
// `onfail` + `defer` interleave: cleanup runs only on the error path
|
||||
sm_acquire :: (fail: bool) -> (s32, !) {
|
||||
defer print(" smoke defer A\n");
|
||||
onfail print(" smoke onfail B\n");
|
||||
if fail { raise error.Acquire; }
|
||||
return 7;
|
||||
}
|
||||
|
||||
// `or`-chain: try a, fall to try b; propagate if both fail
|
||||
|
||||
// `or`-chain: try a, fall to try b; propagate if both fail
|
||||
sm_first :: (a: s32, b: s32) -> (s32, !) {
|
||||
v := try sm_parse(a) or try sm_parse(b);
|
||||
return v;
|
||||
}
|
||||
|
||||
// --- Foreign function binding ---
|
||||
|
||||
// --- Foreign function binding ---
|
||||
libc :: #library "c";
|
||||
|
||||
c_abs :: (n: s32) -> s32 #foreign libc "abs";
|
||||
|
||||
// --- Protocol declarations (Phase 1: static dispatch only) ---
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> s32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> s32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: s32; }
|
||||
|
||||
impl Counter for SimpleCounter {
|
||||
inc :: (self: *SimpleCounter) { self.val += 1; }
|
||||
get :: (self: *SimpleCounter) -> s32 { self.val; }
|
||||
}
|
||||
|
||||
impl Summable for Point {
|
||||
sum :: (self: *Point) -> s32 { self.x + self.y; }
|
||||
}
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
Adder :: protocol #inline {
|
||||
add :: (n: s32);
|
||||
value :: () -> s32;
|
||||
}
|
||||
|
||||
Accumulator :: struct {
|
||||
total: s32;
|
||||
}
|
||||
|
||||
impl Adder for Accumulator {
|
||||
add :: (self: *Accumulator, n: s32) { self.total += n; }
|
||||
value :: (self: *Accumulator) -> s32 { self.total; }
|
||||
}
|
||||
|
||||
Doubler :: struct { val: s32; }
|
||||
|
||||
impl Adder for Doubler {
|
||||
add :: (self: *Doubler, n: s32) { self.val = self.val + n + n; }
|
||||
value :: (self: *Doubler) -> s32 { self.val; }
|
||||
}
|
||||
|
||||
// Phase 4: default methods
|
||||
|
||||
// Phase 4: default methods
|
||||
Repeater :: protocol {
|
||||
say :: (msg: string);
|
||||
say_twice :: (msg: string) {
|
||||
self.say(msg);
|
||||
self.say(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Printer :: struct { count: s32; }
|
||||
|
||||
impl Repeater for Printer {
|
||||
say :: (self: *Printer, msg: string) {
|
||||
self.count += 1;
|
||||
out(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
|
||||
// P4 edge: Chained default→default calls
|
||||
Chained :: protocol {
|
||||
base :: (msg: string) -> s32;
|
||||
wrap :: (msg: string) -> s32 {
|
||||
self.base(msg) + 1;
|
||||
}
|
||||
double_wrap :: (msg: string) -> s32 {
|
||||
self.wrap(msg) + self.wrap(msg);
|
||||
}
|
||||
}
|
||||
|
||||
ChainImpl :: struct { val: s32; }
|
||||
impl Chained for ChainImpl {
|
||||
base :: (self: *ChainImpl, msg: string) -> s32 {
|
||||
self.val += 1;
|
||||
msg.len;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 5: Self type
|
||||
|
||||
// Phase 5: Self type
|
||||
Eq :: protocol {
|
||||
eq :: (other: Self) -> bool;
|
||||
}
|
||||
|
||||
impl Eq for Point {
|
||||
eq :: (self: *Point, other: Point) -> bool {
|
||||
self.x == other.x and self.y == other.y;
|
||||
}
|
||||
}
|
||||
|
||||
Cloneable :: protocol {
|
||||
clone :: () -> Self;
|
||||
}
|
||||
|
||||
impl Cloneable for Point {
|
||||
clone :: (self: *Point) -> Point {
|
||||
Point.{ x = self.x, y = self.y };
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for s64 {
|
||||
eq :: (self: *s64, other: s64) -> bool {
|
||||
self.* == other;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 6: Generic constraints
|
||||
|
||||
// Phase 6: Generic constraints
|
||||
are_equal :: ($T: Type/Eq, a: T, b: T) -> bool {
|
||||
a.eq(b);
|
||||
}
|
||||
|
||||
Hashable :: protocol {
|
||||
hash :: () -> s64;
|
||||
}
|
||||
|
||||
impl Hashable for Point {
|
||||
hash :: (self: *Point) -> s64 {
|
||||
xx self.x * 31 + xx self.y;
|
||||
}
|
||||
}
|
||||
|
||||
eq_and_hash :: ($T: Type/Eq/Hashable, a: T, b: T) -> bool {
|
||||
if a.hash() != b.hash() { return false; }
|
||||
a.eq(b);
|
||||
}
|
||||
|
||||
// P6.4: inline constraint syntax ($T/Protocol)
|
||||
|
||||
// P6.4: inline constraint syntax ($T/Protocol)
|
||||
sum_of_inline :: (a: $T/Summable, b: T) -> s32 {
|
||||
a.sum() + b.sum();
|
||||
}
|
||||
|
||||
// Phase 7: Generic struct impls
|
||||
|
||||
// Phase 7: Generic struct impls
|
||||
Pair :: struct ($T: Type) {
|
||||
a: T;
|
||||
b: T;
|
||||
}
|
||||
|
||||
impl Summable for Pair($T) {
|
||||
sum :: (self: *Pair(T)) -> s32 {
|
||||
xx self.a + xx self.b;
|
||||
}
|
||||
}
|
||||
|
||||
// P6.5: Struct type param constraints
|
||||
|
||||
// P6.5: Struct type param constraints
|
||||
SumBox :: struct ($T: Type/Summable) {
|
||||
val: T;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Struct constants test
|
||||
|
||||
// ============================================================
|
||||
// Struct constants test
|
||||
Phys :: struct {
|
||||
x, y: f32;
|
||||
GRAVITY :f32: 9.81;
|
||||
MAX_SPEED :: 100;
|
||||
}
|
||||
|
||||
// Init block test struct
|
||||
|
||||
// Init block test struct
|
||||
Builder :: struct {
|
||||
total: s32;
|
||||
count: s32;
|
||||
|
||||
add :: (self: *Builder, val: s32) {
|
||||
self.total += val;
|
||||
self.count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Global variable for address-of test
|
||||
|
||||
// Global variable for address-of test
|
||||
g_smoke_val : s32 = 42;
|
||||
|
||||
write_to_ptr :: (p: *s32) {
|
||||
p.* = 99;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// PROTOCOLS (Phase 1: static dispatch)
|
||||
// ========================================================
|
||||
print("=== Protocols ===\n");
|
||||
|
||||
// P1.1: Basic protocol + impl, direct call on concrete type
|
||||
{
|
||||
sc := SimpleCounter.{ val = 0 };
|
||||
sc.inc();
|
||||
sc.inc();
|
||||
sc.inc();
|
||||
print("P1.1: {}\n", sc.get());
|
||||
}
|
||||
|
||||
// P1.2: impl in separate scope (retroactive conformance)
|
||||
{
|
||||
p := Point.{ x = 10, y = 20 };
|
||||
print("P1.2: {}\n", p.sum());
|
||||
}
|
||||
|
||||
// P2.1: #inline protocol — xx conversion + dynamic dispatch
|
||||
{
|
||||
acc := Accumulator.{ total = 0 };
|
||||
a : Adder = xx @acc;
|
||||
a.add(10);
|
||||
a.add(20);
|
||||
a.add(12);
|
||||
print("P2.1: {}\n", a.value());
|
||||
}
|
||||
|
||||
// P2.2: pass protocol value to function
|
||||
{
|
||||
use_adder :: (a: Adder, n: s32) -> s32 {
|
||||
a.add(n);
|
||||
a.value();
|
||||
}
|
||||
acc := Accumulator.{ total = 100 };
|
||||
result := use_adder(xx @acc, 50);
|
||||
print("P2.2: {}\n", result);
|
||||
}
|
||||
|
||||
// P2.3: different impls through same protocol type
|
||||
{
|
||||
acc := Accumulator.{ total = 0 };
|
||||
dbl := Doubler.{ val = 0 };
|
||||
a1 : Adder = xx @acc;
|
||||
a2 : Adder = xx @dbl;
|
||||
a1.add(5);
|
||||
a2.add(5);
|
||||
print("P2.3: {} {}\n", a1.value(), a2.value());
|
||||
}
|
||||
|
||||
// P3.1: vtable-pointer protocol (default, no #inline)
|
||||
{
|
||||
sc := SimpleCounter.{ val = 0 };
|
||||
c : Counter = xx @sc;
|
||||
c.inc();
|
||||
c.inc();
|
||||
c.inc();
|
||||
c.inc();
|
||||
c.inc();
|
||||
print("P3.1: {}\n", c.get());
|
||||
}
|
||||
|
||||
// P3.2: vtable protocol passed to function
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 {
|
||||
c.inc();
|
||||
c.inc();
|
||||
c.get();
|
||||
}
|
||||
sc := SimpleCounter.{ val = 10 };
|
||||
result := use_counter(xx @sc);
|
||||
print("P3.2: {}\n", result);
|
||||
}
|
||||
|
||||
// P4.1: default method calls required method (static dispatch)
|
||||
{
|
||||
pr := Printer.{ count = 0 };
|
||||
pr.say_twice("hi ");
|
||||
print("\nP4.1: {}\n", pr.count);
|
||||
}
|
||||
|
||||
// P4.2: default method via dynamic dispatch (vtable)
|
||||
{
|
||||
pr := Printer.{ count = 0 };
|
||||
r : Repeater = xx @pr;
|
||||
r.say_twice("yo ");
|
||||
print("\nP4.2: {}\n", pr.count);
|
||||
}
|
||||
|
||||
// P4.3: chained default→default calls via vtable
|
||||
{
|
||||
ci := ChainImpl.{ val = 0 };
|
||||
ch : Chained = xx @ci;
|
||||
// double_wrap calls wrap twice, wrap calls base once each
|
||||
// base("hi") returns 2 (len), wrap adds 1 → 3, double_wrap = 3 + 3 = 6
|
||||
result := ch.double_wrap("hi");
|
||||
// base was called 2 times (once per wrap call)
|
||||
print("P4.3: {} {}\n", result, ci.val);
|
||||
}
|
||||
|
||||
// P5.1: Self type in protocol — static dispatch
|
||||
{
|
||||
p1 := Point.{ x = 1, y = 2 };
|
||||
p2 := Point.{ x = 1, y = 2 };
|
||||
p3 := Point.{ x = 3, y = 4 };
|
||||
print("P5.1: {} {}\n", p1.eq(p2), p1.eq(p3));
|
||||
}
|
||||
|
||||
// P5.2: Self in return position
|
||||
{
|
||||
p := Point.{ x = 10, y = 20 };
|
||||
p2 := p.clone();
|
||||
print("P5.2: {} {}\n", p2.x, p2.y);
|
||||
}
|
||||
|
||||
// P5.5: impl for primitive type
|
||||
{
|
||||
x := 42;
|
||||
y := 42;
|
||||
z := 99;
|
||||
r1 := x.eq(y);
|
||||
r2 := x.eq(z);
|
||||
print("P5.5: {} {}\n", r1, r2);
|
||||
}
|
||||
|
||||
// P5.3: Self with dynamic dispatch (erased to *void)
|
||||
{
|
||||
p1 := Point.{ x = 1, y = 2 };
|
||||
p2 := Point.{ x = 1, y = 2 };
|
||||
p3 := Point.{ x = 3, y = 4 };
|
||||
e : Eq = xx p1;
|
||||
print("P5.3: {} {}\n", e.eq(p2), e.eq(p3));
|
||||
}
|
||||
|
||||
// P6.1: Single constraint — constrained generic function
|
||||
{
|
||||
p1 := Point.{ x = 1, y = 2 };
|
||||
p2 := Point.{ x = 1, y = 2 };
|
||||
p3 := Point.{ x = 3, y = 4 };
|
||||
print("P6.1: {} {}\n", are_equal(p1, p2), are_equal(p1, p3));
|
||||
}
|
||||
|
||||
// P6.2: Constraint with primitive type
|
||||
{
|
||||
print("P6.2: {} {}\n", are_equal(42, 42), are_equal(42, 99));
|
||||
}
|
||||
|
||||
// P6.3: Multiple constraints
|
||||
{
|
||||
p1 := Point.{ x = 1, y = 2 };
|
||||
p2 := Point.{ x = 1, y = 2 };
|
||||
p3 := Point.{ x = 3, y = 4 };
|
||||
print("P6.3: {} {}\n", eq_and_hash(p1, p2), eq_and_hash(p1, p3));
|
||||
}
|
||||
|
||||
// P6.4: inline constraint syntax ($T/Protocol)
|
||||
{
|
||||
// sum_of_inline uses $T/Summable inline (not $T: Type/Summable)
|
||||
p1 := Point.{ x = 10, y = 20 };
|
||||
p2 := Point.{ x = 3, y = 7 };
|
||||
print("P6.4: {}\n", sum_of_inline(p1, p2));
|
||||
}
|
||||
|
||||
// P6.5: Struct type param constraints ($T: Type/Summable)
|
||||
{
|
||||
box := SumBox(Point).{ val = Point.{ x = 5, y = 15 } };
|
||||
print("P6.5: {}\n", box.val.sum());
|
||||
}
|
||||
|
||||
// P7.1: impl for generic struct
|
||||
{
|
||||
p := Pair(s32).{ a = 10, b = 20 };
|
||||
print("P7.1: {}\n", p.sum());
|
||||
}
|
||||
|
||||
// P7.2: generic struct impl with different type arg
|
||||
{
|
||||
p1 := Pair(s32).{ a = 3, b = 7 };
|
||||
p2 := Pair(s64).{ a = 100, b = 200 };
|
||||
print("P7.2: {} {}\n", p1.sum(), p2.sum());
|
||||
}
|
||||
|
||||
// P2.4: xx in function return position (tested in standalone test_return.sx)
|
||||
// Covered by: make_adder :: (acc: *Accumulator) -> Adder { xx acc; }
|
||||
|
||||
// P2.6: protocol values in arrays
|
||||
{
|
||||
acc := Accumulator.{ total = 0 };
|
||||
dbl := Doubler.{ val = 0 };
|
||||
adders : [2]Adder = .[xx @acc, xx @dbl];
|
||||
i := 0;
|
||||
while i < 2 {
|
||||
adders[i].add(5);
|
||||
i += 1;
|
||||
}
|
||||
print("P2.6: {} {}\n", acc.total, dbl.val);
|
||||
}
|
||||
|
||||
// P2.7: xx on inline struct literal (no intermediate variable)
|
||||
{
|
||||
use_adder :: (a: Adder) -> s32 { a.add(10); a.value(); }
|
||||
result := use_adder(xx Accumulator.{ total = 5 });
|
||||
print("P2.7: {}\n", result);
|
||||
}
|
||||
|
||||
// P3.3: xx on inline struct literal with vtable protocol
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
|
||||
result := use_counter(xx SimpleCounter.{ val = 100 });
|
||||
print("P3.3: {}\n", result);
|
||||
}
|
||||
}
|
||||
92
examples/0416-protocols-auto-type-erasure.sx
Normal file
92
examples/0416-protocols-auto-type-erasure.sx
Normal file
@@ -0,0 +1,92 @@
|
||||
#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; }
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
Counter :: protocol {
|
||||
inc :: ();
|
||||
get :: () -> s32;
|
||||
}
|
||||
|
||||
Summable :: protocol {
|
||||
sum :: () -> s32;
|
||||
}
|
||||
|
||||
SimpleCounter :: struct { val: s32; }
|
||||
|
||||
impl Counter for SimpleCounter {
|
||||
inc :: (self: *SimpleCounter) { self.val += 1; }
|
||||
get :: (self: *SimpleCounter) -> s32 { self.val; }
|
||||
}
|
||||
|
||||
impl Summable for Point {
|
||||
sum :: (self: *Point) -> s32 { self.x + self.y; }
|
||||
}
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
|
||||
// Phase 2: #inline protocol for dynamic dispatch
|
||||
Adder :: protocol #inline {
|
||||
add :: (n: s32);
|
||||
value :: () -> s32;
|
||||
}
|
||||
|
||||
Accumulator :: struct {
|
||||
total: s32;
|
||||
}
|
||||
|
||||
impl Adder for Accumulator {
|
||||
add :: (self: *Accumulator, n: s32) { self.total += n; }
|
||||
value :: (self: *Accumulator) -> s32 { self.total; }
|
||||
}
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- Auto type erasure (AE) ---
|
||||
print("=== Auto Type Erasure ===\n");
|
||||
|
||||
// AE1: function argument — concrete passed where protocol expected (no xx)
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
|
||||
sc := SimpleCounter.{ val = 10 };
|
||||
result := use_counter(sc);
|
||||
print("AE1: {}\n", result);
|
||||
}
|
||||
|
||||
// AE2: variable assignment — concrete to protocol variable (no xx)
|
||||
{
|
||||
acc := Accumulator.{ total = 0 };
|
||||
a: Adder = acc;
|
||||
a.add(5);
|
||||
a.add(3);
|
||||
print("AE2: {}\n", a.value());
|
||||
}
|
||||
|
||||
// AE3: struct literal passed directly (no xx)
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
|
||||
result := use_counter(SimpleCounter.{ val = 100 });
|
||||
print("AE3: {}\n", result);
|
||||
}
|
||||
|
||||
// AE4: explicit xx still works (not broken)
|
||||
{
|
||||
use_counter :: (c: Counter) -> s32 { c.inc(); c.get(); }
|
||||
result := use_counter(xx SimpleCounter.{ val = 50 });
|
||||
print("AE4: {}\n", result);
|
||||
}
|
||||
|
||||
// AE5: pointer auto-erasure — *ConcreteType to protocol
|
||||
{
|
||||
use_adder :: (a: Adder) { a.add(10); }
|
||||
acc := Accumulator.{ total = 5 };
|
||||
p := @acc;
|
||||
use_adder(p);
|
||||
print("AE5: {}\n", acc.total);
|
||||
}
|
||||
}
|
||||
83
examples/0608-comptime-comptime.sx
Normal file
83
examples/0608-comptime-comptime.sx
Normal file
@@ -0,0 +1,83 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
add :: (a: s32, b: s32) -> s32 { a + b; }
|
||||
|
||||
mul :: (a: s32, b: s32) -> s32 { a * b; }
|
||||
|
||||
// #run compile-time constants
|
||||
CT_VAL :: #run add(10, 15);
|
||||
|
||||
CT_MUL :: #run mul(6, 7);
|
||||
|
||||
CT_CHAIN :: #run add(CT_VAL, 5);
|
||||
|
||||
// #run compile-time optional tests
|
||||
|
||||
// #run compile-time optional tests
|
||||
ct_opt_coalesce :: () -> s32 {
|
||||
x: ?s32 = 42;
|
||||
y: ?s32 = null;
|
||||
return (x ?? 0) + (y ?? 99);
|
||||
}
|
||||
|
||||
ct_opt_unwrap :: () -> s32 {
|
||||
x: ?s32 = 77;
|
||||
return x!;
|
||||
}
|
||||
|
||||
ct_opt_guard :: () -> s32 {
|
||||
x: ?s32 = 10;
|
||||
if x == null { return -1; }
|
||||
return x;
|
||||
}
|
||||
|
||||
CT_OPT_COALESCE :: #run ct_opt_coalesce();
|
||||
|
||||
CT_OPT_UNWRAP :: #run ct_opt_unwrap();
|
||||
|
||||
CT_OPT_GUARD :: #run ct_opt_guard();
|
||||
|
||||
// #insert helpers
|
||||
|
||||
// #insert helpers
|
||||
gen_code :: () -> string {
|
||||
return "print(\"insert-ok\\n\");";
|
||||
}
|
||||
|
||||
gen_val :: () -> string {
|
||||
return "print(\"insert-gen: {}\\n\", 42);";
|
||||
}
|
||||
|
||||
// --- Error handling (failable functions: sets, raise/try/catch/or/onfail) ---
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 8. COMPILE-TIME
|
||||
// ========================================================
|
||||
print("=== 8. Comptime ===\n");
|
||||
|
||||
// #run constant
|
||||
print("run-const: {}\n", CT_VAL);
|
||||
|
||||
// #run with expression
|
||||
print("run-expr: {}\n", CT_MUL);
|
||||
|
||||
// #run chained dependency
|
||||
print("run-chain: {}\n", CT_CHAIN);
|
||||
|
||||
// #run comptime optionals
|
||||
print("ct-opt-coalesce: {}\n", CT_OPT_COALESCE); // ct-opt-coalesce: 141
|
||||
print("ct-opt-unwrap: {}\n", CT_OPT_UNWRAP); // ct-opt-unwrap: 77
|
||||
print("ct-opt-guard: {}\n", CT_OPT_GUARD); // ct-opt-guard: 10
|
||||
|
||||
// #insert with function
|
||||
#insert gen_code();
|
||||
|
||||
// #insert additional
|
||||
#insert gen_val();
|
||||
}
|
||||
46
examples/0609-comptime-inline-if.sx
Normal file
46
examples/0609-comptime-inline-if.sx
Normal file
@@ -0,0 +1,46 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// --- inline if (compile-time conditionals) ---
|
||||
print("=== inline if ===\n");
|
||||
{
|
||||
// POINTER_SIZE is 8 on desktop (64-bit)
|
||||
inline if POINTER_SIZE == 8 {
|
||||
print("64-bit\n");
|
||||
} else {
|
||||
print("32-bit\n");
|
||||
}
|
||||
|
||||
// OS enum comparison
|
||||
inline if OS == .wasm {
|
||||
print("wasm\n");
|
||||
} else {
|
||||
print("not wasm\n");
|
||||
}
|
||||
|
||||
// != comparison
|
||||
inline if OS != .unknown {
|
||||
print("known os\n");
|
||||
} else {
|
||||
print("unknown os\n");
|
||||
}
|
||||
|
||||
// nested inline if
|
||||
inline if POINTER_SIZE != 4 {
|
||||
inline if OS != .wasm {
|
||||
print("desktop 64-bit\n");
|
||||
} else {
|
||||
print("wasm 64-bit??\n");
|
||||
}
|
||||
}
|
||||
|
||||
// POINTER_SIZE in regular (non-inline) if expression
|
||||
ps := if POINTER_SIZE == 8 then "8" else "4";
|
||||
print("pointer size via if: {}\n", ps);
|
||||
}
|
||||
}
|
||||
20
examples/0810-memory-slice-ptr.sx
Normal file
20
examples/0810-memory-slice-ptr.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 17. SLICE/ARRAY .ptr ACCESS
|
||||
// ========================================================
|
||||
print("=== 17. Slice Ptr ===\n");
|
||||
{
|
||||
sarr : [5]s32 = .[10, 20, 30, 40, 50];
|
||||
ssl := sarr[1..4];
|
||||
sp := ssl.ptr;
|
||||
print("sl-ptr[0]: {}\n", sp[0]);
|
||||
print("sl-ptr[1]: {}\n", sp[1]);
|
||||
}
|
||||
}
|
||||
104
examples/1036-errors-failable-smoke.sx
Normal file
104
examples/1036-errors-failable-smoke.sx
Normal file
@@ -0,0 +1,104 @@
|
||||
// End-to-end error handling: failable functions (named + inferred sets) consumed
|
||||
// through every absorbing form — destructure, `try` (in helpers), `catch` (bare-
|
||||
// expr / match-body / diverging block / no-binding), `or` value-terminator,
|
||||
// `onfail` cleanup interleaved with `defer`, plus `error.X` as a value and `{}`
|
||||
// tag-name interpolation.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
SmokeErr :: error { Empty, BadDigit, Overflow }
|
||||
|
||||
// value-carrying, named set
|
||||
sm_parse :: (n: s32) -> (s32, !SmokeErr) {
|
||||
if n < 0 { raise error.BadDigit; }
|
||||
if n == 0 { raise error.Empty; }
|
||||
if n > 99 { raise error.Overflow; }
|
||||
return n * 2;
|
||||
}
|
||||
|
||||
// pure failable, inferred set (ad-hoc tag)
|
||||
sm_check :: (ok: bool) -> ! {
|
||||
if !ok { raise error.NotReady; }
|
||||
return;
|
||||
}
|
||||
|
||||
// multi-value, inferred set: `try` propagates; SCC absorbs SmokeErr
|
||||
sm_pair :: (a: s32, b: s32) -> (s32, s32, !) {
|
||||
x := try sm_parse(a);
|
||||
y := try sm_parse(b);
|
||||
return (x, y);
|
||||
}
|
||||
|
||||
// catch with a diverging block body
|
||||
sm_or_default :: (n: s32) -> s32 {
|
||||
return sm_parse(n) catch e {
|
||||
print(" logged {}\n", e);
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// onfail + defer interleave: cleanup runs only on the error path
|
||||
sm_acquire :: (fail: bool) -> (s32, !) {
|
||||
defer print(" defer A\n");
|
||||
onfail print(" onfail B\n");
|
||||
if fail { raise error.Acquire; }
|
||||
return 7;
|
||||
}
|
||||
|
||||
// or-chain: try a, fall to try b; propagate if both fail
|
||||
sm_first :: (a: s32, b: s32) -> (s32, !) {
|
||||
v := try sm_parse(a) or try sm_parse(b);
|
||||
return v;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
// error.X as a typed value + {} interpolation renders the tag name
|
||||
e0 : SmokeErr = error.BadDigit;
|
||||
print("tag: {}\n", e0);
|
||||
|
||||
// success destructure + error inspect
|
||||
v1, err1 := sm_parse(5);
|
||||
if !err1 { print("parsed: {}\n", v1); }
|
||||
v2, err2 := sm_parse(-1);
|
||||
if err2 == error.BadDigit { print("got: {}\n", err2); }
|
||||
|
||||
// catch — bare-expr body
|
||||
ce := sm_parse(0) catch e 100;
|
||||
print("catch-expr: {}\n", ce);
|
||||
|
||||
// catch — match-body per-tag dispatch
|
||||
cm := sm_parse(200) catch e == {
|
||||
case .Overflow: 1;
|
||||
case .Empty: 2;
|
||||
else: 3;
|
||||
};
|
||||
print("catch-match: {}\n", cm);
|
||||
|
||||
// catch — diverging block (in helper)
|
||||
print("or-default ok: {}\n", sm_or_default(5));
|
||||
print("or-default err: {}\n", sm_or_default(-5));
|
||||
|
||||
// or — value terminator (bare LHS; non-failable result)
|
||||
ov := sm_parse(0) or 55;
|
||||
print("or-value: {}\n", ov);
|
||||
|
||||
// or-chain via helper (first ok wins; propagation absorbed by destructure)
|
||||
g, gerr := sm_first(0, 8);
|
||||
if !gerr { print("or-chain: {}\n", g); }
|
||||
|
||||
// multi-value failable consumed by catch (tuple body)
|
||||
p, q := sm_pair(0, 3) catch e (0, 0);
|
||||
print("pair-catch: {} {}\n", p, q);
|
||||
p2, q2 := sm_pair(4, 5) catch e (0, 0);
|
||||
print("pair-ok: {} {}\n", p2, q2);
|
||||
|
||||
// pure failable: absorb with no-binding catch
|
||||
sm_check(false) catch { print("check absorbed\n"); };
|
||||
|
||||
// onfail/defer interleave on error vs success
|
||||
print("acquire fail:\n");
|
||||
hv, herr := sm_acquire(true);
|
||||
print("acquire ok:\n");
|
||||
iv, ierr := sm_acquire(false);
|
||||
print("errors ok\n");
|
||||
}
|
||||
23
examples/1219-ffi-foreign.sx
Normal file
23
examples/1219-ffi-foreign.sx
Normal file
@@ -0,0 +1,23 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math/math.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/test.sx";
|
||||
pkg :: #import "modules/testpkg";
|
||||
|
||||
// --- Foreign function binding ---
|
||||
libc :: #library "c";
|
||||
|
||||
c_abs :: (n: s32) -> s32 #foreign libc "abs";
|
||||
|
||||
// --- Protocol declarations (Phase 1: static dispatch only) ---
|
||||
|
||||
main :: () {
|
||||
|
||||
// ========================================================
|
||||
// 15. FOREIGN FUNCTION BINDING
|
||||
// ========================================================
|
||||
print("=== 15. Foreign ===\n");
|
||||
|
||||
// Symbol rename: c_abs maps to C's abs()
|
||||
print("foreign-rename: {}\n", c_abs(xx -42));
|
||||
}
|
||||
3214
examples/50-smoke.sx
3214
examples/50-smoke.sx
File diff suppressed because it is too large
Load Diff
1
examples/expected/0025-basic-literals.exit
Normal file
1
examples/expected/0025-basic-literals.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0025-basic-literals.stderr
Normal file
1
examples/expected/0025-basic-literals.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
18
examples/expected/0025-basic-literals.stdout
Normal file
18
examples/expected/0025-basic-literals.stdout
Normal file
@@ -0,0 +1,18 @@
|
||||
=== 1. Literals ===
|
||||
decimal: 42
|
||||
hex: 255
|
||||
binary: 10
|
||||
float: 3.140000
|
||||
f64: 2.718281
|
||||
true: true
|
||||
false: false
|
||||
escapes: hello world
|
||||
multiline: line1
|
||||
line2
|
||||
heredoc: raw heredoc
|
||||
|
||||
undef-then-set: 77
|
||||
enum-lit: .green
|
||||
null-ptr: null
|
||||
string-len: 5
|
||||
empty-string: 0
|
||||
1
examples/expected/0026-basic-operators.exit
Normal file
1
examples/expected/0026-basic-operators.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0026-basic-operators.stderr
Normal file
1
examples/expected/0026-basic-operators.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
60
examples/expected/0026-basic-operators.stdout
Normal file
60
examples/expected/0026-basic-operators.stdout
Normal file
@@ -0,0 +1,60 @@
|
||||
=== 2. Operators ===
|
||||
add: 7
|
||||
sub: 7
|
||||
mul: 42
|
||||
div: 5
|
||||
mod: 2
|
||||
neg: -5
|
||||
eq: true
|
||||
neq: true
|
||||
lt: true
|
||||
gt: true
|
||||
le: true
|
||||
ge: true
|
||||
chain: true
|
||||
chain-gt: true
|
||||
chain-mixed: true
|
||||
eq-chain: true
|
||||
eq-chain-f: false
|
||||
band: 15
|
||||
bor: 7
|
||||
bxor: 240
|
||||
bxor2: 5
|
||||
bnot: -1
|
||||
bnot2: -2
|
||||
shl: 16
|
||||
shr: 16
|
||||
shl2: 24
|
||||
shr2: 127
|
||||
band-var: 15
|
||||
bor-var: 7
|
||||
bxor-var: 240
|
||||
shl-var: 16
|
||||
shr-var: 15
|
||||
bnot-var: -16
|
||||
and-assign: 15
|
||||
or-assign: 255
|
||||
xor-assign: 240
|
||||
shl-assign: 256
|
||||
shr-assign: 16
|
||||
mod-var: 2
|
||||
and: true
|
||||
and-false: false
|
||||
or: true
|
||||
or-false: false
|
||||
short-and: false
|
||||
short-or: true
|
||||
ca+=: 15
|
||||
ca-=: 12
|
||||
ca*=: 24
|
||||
ca/=: 4
|
||||
prec1: 14
|
||||
prec2: 20
|
||||
xx-cast: 200
|
||||
widen-u8-s64: 200
|
||||
widen-s32-f64: 42.000000
|
||||
widen-f32-f64: 1.500000
|
||||
widen-u8-s16: 100
|
||||
xx-s64-s32: 12345
|
||||
xx-f64-f32: 1.500000
|
||||
xx-f64-s32: 7
|
||||
1
examples/expected/0027-basic-control-flow.exit
Normal file
1
examples/expected/0027-basic-control-flow.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0027-basic-control-flow.stderr
Normal file
1
examples/expected/0027-basic-control-flow.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
26
examples/expected/0027-basic-control-flow.stdout
Normal file
26
examples/expected/0027-basic-control-flow.stdout
Normal file
@@ -0,0 +1,26 @@
|
||||
=== 4. Control Flow ===
|
||||
ite: 1
|
||||
ite-both: 10 20
|
||||
if-block: yes
|
||||
if-no-else: after
|
||||
nested-if: deep
|
||||
if-else-if: second
|
||||
if-block-expr: 15
|
||||
while: 5
|
||||
while-false: skipped
|
||||
while-break: 7
|
||||
while-continue: 25
|
||||
while-sum: 55
|
||||
nested-while: 9
|
||||
nested-break: 2 2
|
||||
for: 10 20 30 40
|
||||
for-print: 10 20 30 40
|
||||
for-idx: 0 1 2 3
|
||||
for-2arg: 10@0 20@1 30@2 40@3
|
||||
for-break: 10 20
|
||||
for-continue: 10 30 40
|
||||
for-slice: 10 20 30
|
||||
for-slice-idx: 0:10 1:20 2:30
|
||||
for-nested: (0,0) (0,1) (1,0) (1,1)
|
||||
for-break-idx: 2
|
||||
multi: 1 2 3
|
||||
1
examples/expected/0028-basic-functions.exit
Normal file
1
examples/expected/0028-basic-functions.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0028-basic-functions.stderr
Normal file
1
examples/expected/0028-basic-functions.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
21
examples/expected/0028-basic-functions.stdout
Normal file
21
examples/expected/0028-basic-functions.stdout
Normal file
@@ -0,0 +1,21 @@
|
||||
=== 5. Functions ===
|
||||
const: 42
|
||||
typed-const: 3.140000
|
||||
default-init: 0
|
||||
implicit-ret: 42
|
||||
early-ret: 5
|
||||
early-ret2: 99
|
||||
void-return: ok
|
||||
generic-s32: 42
|
||||
generic-f32: 1.500000
|
||||
generic-bool: true
|
||||
generic-multi: 30
|
||||
lambda: 14
|
||||
lambda-ret: 5.000000
|
||||
local-fn: 7
|
||||
fn-nested: 26
|
||||
varargs: 15
|
||||
spread: 60
|
||||
fp: 7
|
||||
fp-reassign: 12
|
||||
fp-apply: 30
|
||||
1
examples/expected/0029-basic-scoping.exit
Normal file
1
examples/expected/0029-basic-scoping.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0029-basic-scoping.stderr
Normal file
1
examples/expected/0029-basic-scoping.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
23
examples/expected/0029-basic-scoping.stdout
Normal file
23
examples/expected/0029-basic-scoping.stdout
Normal file
@@ -0,0 +1,23 @@
|
||||
=== 6. Scoping ===
|
||||
inner: 200
|
||||
outer: 100
|
||||
shadow-type: 42
|
||||
shadow-type: 3.140000
|
||||
nest3: 3
|
||||
nest2: 2
|
||||
nest1: 1
|
||||
scope-isolate: 100
|
||||
scope-reuse: 1
|
||||
scope-reuse: 2
|
||||
scope-reuse: 1
|
||||
defer-a
|
||||
defer-b
|
||||
defer-c
|
||||
d4
|
||||
d3
|
||||
d2
|
||||
d1
|
||||
inner-defer
|
||||
outer-defer
|
||||
defer-in-if: body
|
||||
defer-in-if: deferred
|
||||
1
examples/expected/0030-basic-builtins.exit
Normal file
1
examples/expected/0030-basic-builtins.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0030-basic-builtins.stderr
Normal file
1
examples/expected/0030-basic-builtins.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
31
examples/expected/0030-basic-builtins.stdout
Normal file
31
examples/expected/0030-basic-builtins.stdout
Normal file
@@ -0,0 +1,31 @@
|
||||
=== 7. Builtins ===
|
||||
out-ok
|
||||
sqrt: 3.000000
|
||||
sqrt-f64: 4.000000
|
||||
sizeof-s32: 4
|
||||
sizeof-f64: 8
|
||||
sizeof-struct: 8
|
||||
alignof-u8: 1
|
||||
alignof-s32: 4
|
||||
alignof-s64: 8
|
||||
alignof-struct: 4
|
||||
typeof: int
|
||||
typeof-float: float
|
||||
typeof-string: string
|
||||
typeof-bool: bool
|
||||
typeof-struct: struct
|
||||
typeof-enum: enum
|
||||
typename: Point
|
||||
fieldcount: 2
|
||||
fieldcount-enum: 3
|
||||
fieldname0: x
|
||||
fieldname1: y
|
||||
fieldname-enum0: red
|
||||
fieldname-enum2: blue
|
||||
fieldval0: 11
|
||||
fieldval1: 22
|
||||
fieldidx: 1
|
||||
fieldidx-tagged: 0
|
||||
fieldidx-tagged2: 2
|
||||
cast: 3
|
||||
cast-int-f64: 42.000000
|
||||
1
examples/expected/0031-basic-local-fn-return.exit
Normal file
1
examples/expected/0031-basic-local-fn-return.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0031-basic-local-fn-return.stderr
Normal file
1
examples/expected/0031-basic-local-fn-return.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0031-basic-local-fn-return.stdout
Normal file
3
examples/expected/0031-basic-local-fn-return.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 19. Local Fn Return ===
|
||||
local-struct: 42 99
|
||||
local-enum: .circle(2.500000)
|
||||
1
examples/expected/0032-basic-ufcs-return-type.exit
Normal file
1
examples/expected/0032-basic-ufcs-return-type.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0032-basic-ufcs-return-type.stderr
Normal file
1
examples/expected/0032-basic-ufcs-return-type.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0032-basic-ufcs-return-type.stdout
Normal file
3
examples/expected/0032-basic-ufcs-return-type.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 20. UFCS Return Type ===
|
||||
direct: 7
|
||||
ufcs: 7
|
||||
1
examples/expected/0033-basic-if-struct.exit
Normal file
1
examples/expected/0033-basic-if-struct.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0033-basic-if-struct.stderr
Normal file
1
examples/expected/0033-basic-if-struct.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0033-basic-if-struct.stdout
Normal file
3
examples/expected/0033-basic-if-struct.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 22. If-Struct ===
|
||||
if-struct: 10 20
|
||||
else-struct: 30 40
|
||||
1
examples/expected/0034-basic-string-comparison.exit
Normal file
1
examples/expected/0034-basic-string-comparison.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0034-basic-string-comparison.stderr
Normal file
1
examples/expected/0034-basic-string-comparison.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
5
examples/expected/0034-basic-string-comparison.stdout
Normal file
5
examples/expected/0034-basic-string-comparison.stdout
Normal file
@@ -0,0 +1,5 @@
|
||||
=== 24. String Comparison ===
|
||||
str-eq: true
|
||||
str-neq: true
|
||||
str-diff: false
|
||||
empty-eq: true
|
||||
1
examples/expected/0035-basic-array-loop-mutation.exit
Normal file
1
examples/expected/0035-basic-array-loop-mutation.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0035-basic-array-loop-mutation.stderr
Normal file
1
examples/expected/0035-basic-array-loop-mutation.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0035-basic-array-loop-mutation.stdout
Normal file
3
examples/expected/0035-basic-array-loop-mutation.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 25. Array Loop Mutation ===
|
||||
loop-fill: 1 2 3 4
|
||||
compound: 13
|
||||
1
examples/expected/0036-basic-ufcs-aliases.exit
Normal file
1
examples/expected/0036-basic-ufcs-aliases.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0036-basic-ufcs-aliases.stderr
Normal file
1
examples/expected/0036-basic-ufcs-aliases.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
12
examples/expected/0036-basic-ufcs-aliases.stdout
Normal file
12
examples/expected/0036-basic-ufcs-aliases.stdout
Normal file
@@ -0,0 +1,12 @@
|
||||
=== UFCS Aliases ===
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
3
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
99
|
||||
1
examples/expected/0037-basic-trailing-commas.exit
Normal file
1
examples/expected/0037-basic-trailing-commas.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0037-basic-trailing-commas.stderr
Normal file
1
examples/expected/0037-basic-trailing-commas.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
examples/expected/0037-basic-trailing-commas.stdout
Normal file
2
examples/expected/0037-basic-trailing-commas.stdout
Normal file
@@ -0,0 +1,2 @@
|
||||
=== Trailing Commas ===
|
||||
trailing commas ok
|
||||
1
examples/expected/0121-types-types.exit
Normal file
1
examples/expected/0121-types-types.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0121-types-types.stderr
Normal file
1
examples/expected/0121-types-types.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
75
examples/expected/0121-types-types.stdout
Normal file
75
examples/expected/0121-types-types.stdout
Normal file
@@ -0,0 +1,75 @@
|
||||
=== 3. Types ===
|
||||
s8: 127
|
||||
s16: 32000
|
||||
s32: 100000
|
||||
u8: 255
|
||||
u16: 65000
|
||||
u32: 4000000
|
||||
alias: 1.500000
|
||||
struct-pos: Point{x: 1, y: 2}
|
||||
struct-prefix: Point{x: 3, y: 4}
|
||||
struct-named: Point{x: 20, y: 10}
|
||||
struct-shorthand: Point{x: 5, y: 6}
|
||||
defaults: a=0 b=99
|
||||
field-assign: Point{x: 42, y: 99}
|
||||
enum: .red
|
||||
enum-eq: true
|
||||
enum-neq: true
|
||||
backing: .err
|
||||
tagged: .circle(3.140000)
|
||||
payload: 3.140000
|
||||
void-variant: .none
|
||||
reassign: .circle(1.000000)
|
||||
reassign2: .rect(Shape.rect{w: 5.000000, h: 3.000000})
|
||||
enum-prefix: .circle(2.500000)
|
||||
match: rect
|
||||
match-expr: 10
|
||||
match-expr-else: 99
|
||||
capture: 9.500000
|
||||
capture-arrow: 7.500000
|
||||
else-match: other
|
||||
int-match: two
|
||||
int-match-else: unknown
|
||||
bool-match-t: yes
|
||||
bool-match-f: no
|
||||
bool: true
|
||||
union-f: 3.140000
|
||||
union-i: 1078523331
|
||||
promoted-x: 1.000000
|
||||
promoted-data0: 1.000000
|
||||
arr[2]: 30
|
||||
arr.len: 5
|
||||
arr-assign: [1, 99, 3]
|
||||
sl[0]: 1
|
||||
sl.len: 5
|
||||
sl-assign: [10, 55, 30]
|
||||
sub: [20, 30, 40]
|
||||
head: [10, 20, 30]
|
||||
tail: [30, 40, 50]
|
||||
slice-of-slice: [20, 30]
|
||||
strsub: world
|
||||
str-prefix: hello
|
||||
str-suffix: world
|
||||
global-addr-of: 99
|
||||
deref: Point{x: 10, y: 20}
|
||||
auto-deref: 10
|
||||
mp[0]: 10
|
||||
mp[3]: 40
|
||||
mp-write: 99
|
||||
ptr==null: true
|
||||
ptr!=null: false
|
||||
ptr2==null: false
|
||||
ptr2!=null: true
|
||||
ptr-nested-field: 1.000000 2.000000 3.000000
|
||||
mp-store-sentinel: 42
|
||||
vec-construct: [1.000000, 3.000000, 2.000000]
|
||||
vec-add: [5.000000, 7.000000, 9.000000]
|
||||
vec-sub: [4.000000, 3.000000, 2.000000]
|
||||
vec-mul: [2.000000, 6.000000, 12.000000]
|
||||
vec-div: [5.000000, 3.000000, 2.000000]
|
||||
vec-scalar: [2.000000, 6.000000, 4.000000]
|
||||
vec-neg: [-1.000000, -3.000000, -2.000000]
|
||||
vec-x: 10.000000
|
||||
vec-y: 20.000000
|
||||
vec-z: 30.000000
|
||||
vec-idx: 20.000000
|
||||
1
examples/expected/0122-types-flags.exit
Normal file
1
examples/expected/0122-types-flags.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0122-types-flags.stderr
Normal file
1
examples/expected/0122-types-flags.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
18
examples/expected/0122-types-flags.stdout
Normal file
18
examples/expected/0122-types-flags.stdout
Normal file
@@ -0,0 +1,18 @@
|
||||
=== 9. Flags ===
|
||||
flags: .read | .write
|
||||
has-read: yes
|
||||
flags-neg: no-read
|
||||
flags-single: .execute
|
||||
flags-all: .read | .write | .execute
|
||||
flags-raw: 3
|
||||
flags-explicit: .vsync | .resizable
|
||||
flags-explicit-raw: 68
|
||||
--- swap ---
|
||||
var swap: 20 10
|
||||
arr swap: 3 1
|
||||
3-way: 3 1 2
|
||||
--- destructure ---
|
||||
basic: 10 20
|
||||
fn: 2 1
|
||||
discard: 200
|
||||
triple: 1 2 3
|
||||
1
examples/expected/0123-types-compound-assign.exit
Normal file
1
examples/expected/0123-types-compound-assign.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0123-types-compound-assign.stderr
Normal file
1
examples/expected/0123-types-compound-assign.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0123-types-compound-assign.stdout
Normal file
3
examples/expected/0123-types-compound-assign.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 16. Compound Assign ===
|
||||
f64+=f32: 13.000000
|
||||
s64-=s32: 93
|
||||
1
examples/expected/0124-types-array-of-structs.exit
Normal file
1
examples/expected/0124-types-array-of-structs.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0124-types-array-of-structs.stderr
Normal file
1
examples/expected/0124-types-array-of-structs.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
4
examples/expected/0124-types-array-of-structs.stdout
Normal file
4
examples/expected/0124-types-array-of-structs.stdout
Normal file
@@ -0,0 +1,4 @@
|
||||
=== 18. Array of Structs ===
|
||||
arr-struct-x: 3
|
||||
for-struct: Point{x: 1, y: 2}
|
||||
for-struct: Point{x: 3, y: 4}
|
||||
1
examples/expected/0125-types-type-named-vars.exit
Normal file
1
examples/expected/0125-types-type-named-vars.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0125-types-type-named-vars.stderr
Normal file
1
examples/expected/0125-types-type-named-vars.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
3
examples/expected/0125-types-type-named-vars.stdout
Normal file
3
examples/expected/0125-types-type-named-vars.stdout
Normal file
@@ -0,0 +1,3 @@
|
||||
=== 21. Type-Named Vars ===
|
||||
s2: 42
|
||||
s2+1: 43
|
||||
1
examples/expected/0126-types-nested-arrays.exit
Normal file
1
examples/expected/0126-types-nested-arrays.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0126-types-nested-arrays.stderr
Normal file
1
examples/expected/0126-types-nested-arrays.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
5
examples/expected/0126-types-nested-arrays.stdout
Normal file
5
examples/expected/0126-types-nested-arrays.stdout
Normal file
@@ -0,0 +1,5 @@
|
||||
=== 23. Nested Arrays ===
|
||||
m[0][0]: 1
|
||||
m[0][2]: 3
|
||||
m[1][0]: 4
|
||||
m[1][2]: 6
|
||||
1
examples/expected/0127-types-using.exit
Normal file
1
examples/expected/0127-types-using.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0127-types-using.stderr
Normal file
1
examples/expected/0127-types-using.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
12
examples/expected/0127-types-using.stdout
Normal file
12
examples/expected/0127-types-using.stdout
Normal file
@@ -0,0 +1,12 @@
|
||||
=== 26. #using ===
|
||||
using-x: 1
|
||||
using-y: 2
|
||||
using-z: 3
|
||||
pkt-id: 10
|
||||
pkt-ver: 42
|
||||
pkt-pay: 99
|
||||
sprite-px: 10
|
||||
sprite-r: 255
|
||||
sprite-scale: 1
|
||||
say: hello (len=5)
|
||||
n=42
|
||||
1
examples/expected/0128-types-tuples.exit
Normal file
1
examples/expected/0128-types-tuples.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0128-types-tuples.stderr
Normal file
1
examples/expected/0128-types-tuples.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
8
examples/expected/0128-types-tuples.stdout
Normal file
8
examples/expected/0128-types-tuples.stdout
Normal file
@@ -0,0 +1,8 @@
|
||||
=== Tuples ===
|
||||
40
|
||||
2
|
||||
10
|
||||
10
|
||||
42
|
||||
0
|
||||
0
|
||||
1
examples/expected/0129-types-tuple-operators.exit
Normal file
1
examples/expected/0129-types-tuple-operators.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0129-types-tuple-operators.stderr
Normal file
1
examples/expected/0129-types-tuple-operators.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
203
examples/expected/0129-types-tuple-operators.stdout
Normal file
203
examples/expected/0129-types-tuple-operators.stdout
Normal file
@@ -0,0 +1,203 @@
|
||||
=== Tuple Operators ===
|
||||
true
|
||||
false
|
||||
true
|
||||
false
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
true
|
||||
false
|
||||
false
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
false
|
||||
--- directory imports ---
|
||||
7
|
||||
30
|
||||
hello from testpkg
|
||||
cwd-import-ok
|
||||
--- pipe operator ---
|
||||
7
|
||||
30
|
||||
14
|
||||
hello world
|
||||
piped ok!
|
||||
alloc len: 5
|
||||
alloc[0]: 10
|
||||
alloc[4]: 50
|
||||
bytes len: 3
|
||||
--- allocators ---
|
||||
gpa allocs: 2
|
||||
gpa final: 0
|
||||
arena chunks: 1
|
||||
arena overflow: 2
|
||||
arena a1: 42
|
||||
arena a3: 99
|
||||
arena reset idx: 0
|
||||
arena reset gpa: 1
|
||||
arena deinit: 0
|
||||
buf pos: 48
|
||||
buf overflow: 0
|
||||
buf reset: 0
|
||||
1 == (1)
|
||||
(1) == 1
|
||||
1 == 1
|
||||
--- optionals ---
|
||||
opt x: 42
|
||||
opt y: null
|
||||
unwrap: 10
|
||||
coalesce a: 42
|
||||
coalesce b: 99
|
||||
chained ?? c: 42
|
||||
chained ?? d: 99
|
||||
chained ?? e: 0
|
||||
if-bind x: 7
|
||||
if-bind y: none
|
||||
match some: 55
|
||||
match none: 0
|
||||
wrap pos: 5
|
||||
wrap neg: null
|
||||
opt field default: null
|
||||
opt field set: 42
|
||||
opt param a: 42
|
||||
opt param b: 0
|
||||
opt param 7: 7
|
||||
opt reassign: 42.500000
|
||||
opt compute assign: 15.000000
|
||||
opt re-null: 99.000000
|
||||
generic opt 1: 5
|
||||
generic opt 2: 7
|
||||
generic opt 3: null
|
||||
chain some: 10
|
||||
chain none: 0
|
||||
chain print: 20
|
||||
chain null: null
|
||||
deep chain 1: 99
|
||||
deep chain 2: 0
|
||||
narrow x: 42
|
||||
narrow y else: null
|
||||
narrow else x: 42
|
||||
guard some: 42
|
||||
guard none: 0
|
||||
and both: 10 20
|
||||
and one null
|
||||
or guard: 7
|
||||
or guard null: 0
|
||||
nested narrow: 10 20
|
||||
guard loop: 3
|
||||
block-lambda: 50
|
||||
block-lambda: 0
|
||||
block-lambda: 100
|
||||
hello block
|
||||
named-fn-type: 7
|
||||
xx-fnptr: 142
|
||||
closure-type: fn_ptr-nonnull=true
|
||||
closure-type: env-null=true
|
||||
closure-call: 15
|
||||
auto-promote: 20
|
||||
auto-promote-var: 10
|
||||
closure-capture: 52
|
||||
closure-snapshot: 15
|
||||
closure-nocap: 14
|
||||
closure-multi: 33
|
||||
closure-block: 60
|
||||
closure-block: 0
|
||||
closure-block: 100
|
||||
[LOG] hello
|
||||
closure-hof: 30
|
||||
closure-hof-bare: 20
|
||||
closure-f32: 10.000000
|
||||
closure-bool: hello
|
||||
closure-2p: 107
|
||||
closure-3p: 61
|
||||
closure-mix: Alice is 35
|
||||
closure-rbool: false true
|
||||
closure-reduce: 115
|
||||
closure-factory: 105 110
|
||||
closure-struct: 10 20
|
||||
closure-compose: 30
|
||||
closure-indep: 15 50
|
||||
opt-closure: none
|
||||
opt-closure: 15
|
||||
opt-closure-btn: 1 99
|
||||
opt-closure-btn: null
|
||||
closure-ptr: 3
|
||||
closure-enum: 2
|
||||
closure-rstr: [INFO] ok
|
||||
closure-rstruct: 11 22
|
||||
closure-linear: 37
|
||||
closure-clamp: 0 100 255
|
||||
closure-compose2: 12
|
||||
closure-chain: 22
|
||||
closure-map: 3 6 9 12 15
|
||||
closure-filter: 3 [3 4 5]
|
||||
closure-sort: 5 4 3 2 1
|
||||
closure-fe: item 0=10
|
||||
closure-fe: item 1=20
|
||||
closure-fe: item 2=30
|
||||
closure-find: 2
|
||||
closure-any: false true
|
||||
closure-struct-field: -5
|
||||
closure-btn: 1 99
|
||||
closure-counter: 1 2 3
|
||||
closure-acc: 105 115
|
||||
closure-loop: 115
|
||||
closure-reassign: 11
|
||||
closure-reassign: 20
|
||||
closure-snapstruct: 15
|
||||
closure-cap-promoted: 11
|
||||
closure-iife: 15
|
||||
closure-toggle: none
|
||||
closure-toggle: true
|
||||
closure-panel: main 800x600
|
||||
closure-chain-call: true
|
||||
closure-cond: 10
|
||||
closure-form: submitted
|
||||
closure-form: no cancel
|
||||
closure-null-env: true
|
||||
closure-slice: 10 20 30
|
||||
closure-arena: 15
|
||||
closure-gpa: 17 allocs=0
|
||||
closure-opt: 42
|
||||
closure-ropt: 50
|
||||
closure-ropt: none
|
||||
closure-mixed: 10
|
||||
closure-mixed: 15
|
||||
closure-mixed: 25
|
||||
closure-factory-indep: 20 30 40
|
||||
closure-deep-chain: 122
|
||||
closure-8cap: 36
|
||||
closure-4param: 10
|
||||
closure-shared-ptr: 7
|
||||
closure-f64: true
|
||||
closure-zerocap: 49 true
|
||||
closure-struct-method: 7
|
||||
closure-multi-factory: 10
|
||||
closure-multi-factory: 20
|
||||
closure-multi-factory: 30
|
||||
closure-bool-cap: true false
|
||||
closure-as-arg: 142
|
||||
closure-strfmt: hello world
|
||||
closure-ptr-before: 10
|
||||
closure-ptr-after: 42
|
||||
closure-neg: -70
|
||||
closure-proto-cap: true
|
||||
closure-chain-factory: 37
|
||||
closure-while-cond: 3
|
||||
closure-infer: 7
|
||||
closure-infer-arg: 15
|
||||
closure-infer-block: 12
|
||||
closure-infer-cap: 105
|
||||
closure-infer-factory: 35
|
||||
closure-infer-compose: 11
|
||||
closure-infer-void: 42
|
||||
1
examples/expected/0130-types-struct-constants.exit
Normal file
1
examples/expected/0130-types-struct-constants.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
examples/expected/0130-types-struct-constants.stderr
Normal file
1
examples/expected/0130-types-struct-constants.stderr
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user