feat(lang): block value requires no trailing ; (Rust-style)

A block's value is now its last statement ONLY when that statement is a
trailing expression with no `;`. A trailing `;` discards the value,
leaving the block void. This makes value-vs-statement explicit and lets
the compiler reject "this block was supposed to produce a value".

Compiler:
- Parser records `Block.produces_value` (last stmt is a no-`;` trailing
  expression) + `Block.discarded_semi` (the `;` that discarded a value),
  via `expectSemicolonAfter`. A trailing expression before `}` may now
  omit its `;` (previously a parse error). Match-arm and else-arm bodies
  are built value-producing regardless of the arm `;` (arms are exempt —
  the `;` is an arm terminator).
- Lowering: `lowerBlockValue` / the block-expr path / `inferExprType`
  respect `produces_value`. A value-position block that discards its value
  is a hard error (`lowerValueBody` for function bodies; the value-context
  `.block` path for if/else branches, `catch` bodies, value bindings,
  match arms). Pure-failable `-> !` bodies (value rides the error channel)
  and a value-if whose branches are void are handled without false errors.
- `defer`/`onfail` cleanup bodies lower as statements (void), so a
  trailing `;` there is fine.

Migration (behavior-preserving — output unchanged):
- stdlib + ~210 examples: dropped the trailing `;` on value-position last
  expressions. `format` now ends with an explicit `#insert "return
  result;"` (it relied on `#insert`-as-block-value, which `;` discards).
- Two `main :: () -> s32` examples that relied on the old silent
  default-return got an explicit trailing `0`.
- Rejection snapshots 0412 / 1013 regenerated (their quoted source lines
  lost a `;`); the diagnostics themselves are unchanged.

Docs/tests: specs.md "Block values" section; examples 0040 (rules) + 0041
(rejection); 3 parser unit tests. Filed issue 0066 (pre-existing
match-arm negated-literal phi-width quirk, surfaced not caused here).

Gates: zig build, zig build test, run_examples.sh -> 343 passed,
cross_compile.sh -> 7 passed (also refreshed its stale example names).
This commit is contained in:
agra
2026-06-02 09:23:50 +03:00
parent 634cf9bc7f
commit bdd0e96d78
265 changed files with 1070 additions and 761 deletions

View File

@@ -1,5 +1,5 @@
#import "modules/std.sx";
main :: () -> s32 {
if false then 40 else 42;
if false then 40 else 42
}

View File

@@ -10,6 +10,7 @@ main :: () -> s32 {
print("scoped x: {}\n", x); //expect 6
}
print("main x: {}\n", x); //expect 42
0
}
// ** stdout **

View File

@@ -1,7 +1,7 @@
std :: #import "modules/std.sx";
vec3 :: (x:f32, y:f32, z:f32) -> std.Vector(3, f32) {
.[x,y,z];
.[x,y,z]
}
main :: () {

View File

@@ -7,7 +7,7 @@ sumOf10 :: () -> s32 {
s+=i;
i+=1;
}
s;
s
}
someSum :: #run sumOf10();

View File

@@ -14,7 +14,7 @@ quick_sort :: (items: []$T) {
}
i += 1;
items[i], items[hi] = items[hi], items[i];
i;
i
}
sort :: (items: []T, lo: s64, hi: s64) {

View File

@@ -19,12 +19,12 @@ Vec2 :: struct {
x: f32;
y: f32;
create :: (x: f32, y: f32) -> Vec2 { Vec2.{ x = x, y = y }; }
zero :: () -> Vec2 { Vec2.{ x = 0.0, y = 0.0 }; }
unit_x :: () -> Vec2 { Vec2.{ x = 1.0, y = 0.0 }; }
add :: (a: Vec2, b: Vec2) -> Vec2 { Vec2.{ x = a.x + b.x, y = a.y + b.y }; }
scale :: (v: Vec2, s: f32) -> Vec2 { Vec2.{ x = v.x * s, y = v.y * s }; }
len :: (v: Vec2) -> s32 { xx (v.x + v.y); }
create :: (x: f32, y: f32) -> Vec2 { Vec2.{ x = x, y = y } }
zero :: () -> Vec2 { Vec2.{ x = 0.0, y = 0.0 } }
unit_x :: () -> Vec2 { Vec2.{ x = 1.0, y = 0.0 } }
add :: (a: Vec2, b: Vec2) -> Vec2 { Vec2.{ x = a.x + b.x, y = a.y + b.y } }
scale :: (v: Vec2, s: f32) -> Vec2 { Vec2.{ x = v.x * s, y = v.y * s } }
len :: (v: Vec2) -> s32 { xx (v.x + v.y) }
}
EdgeInsets :: struct {
@@ -33,9 +33,9 @@ EdgeInsets :: struct {
bottom: f32;
left: f32;
all :: (v: f32) -> EdgeInsets { EdgeInsets.{ top = v, right = v, bottom = v, left = v }; }
symmetric :: (h: f32, v: f32) -> EdgeInsets { EdgeInsets.{ top = v, right = h, bottom = v, left = h }; }
horizontal :: (h: f32) -> EdgeInsets { EdgeInsets.{ top = 0.0, right = h, bottom = 0.0, left = h }; }
all :: (v: f32) -> EdgeInsets { EdgeInsets.{ top = v, right = v, bottom = v, left = v } }
symmetric :: (h: f32, v: f32) -> EdgeInsets { EdgeInsets.{ top = v, right = h, bottom = v, left = h } }
horizontal :: (h: f32) -> EdgeInsets { EdgeInsets.{ top = 0.0, right = h, bottom = 0.0, left = h } }
}
Trio :: struct {
@@ -43,8 +43,8 @@ Trio :: struct {
b: s32;
c: s32;
make :: (a: s32, b: s32, c: s32) -> Trio { Trio.{ a = a, b = b, c = c }; }
sum :: (t: Trio) -> s32 { t.a + t.b + t.c; }
make :: (a: s32, b: s32, c: s32) -> Trio { Trio.{ a = a, b = b, c = c } }
sum :: (t: Trio) -> s32 { t.a + t.b + t.c }
}
Result :: enum {
@@ -99,7 +99,7 @@ main :: () {
// T6: Return .variant(payload) from function
{
make_shape :: (r: f32) -> Shape { .circle(r); }
make_shape :: (r: f32) -> Shape { .circle(r) }
sh := make_shape(4.2);
print("T6: {}\n", sh.circle);
}
@@ -126,7 +126,7 @@ main :: () {
case .circle: 10;
case .rect: 20;
case .none: 30;
};
}
}
print("T8a: {}\n", describe(.circle(7.0)));
print("T8b: {}\n", describe(.rect(.{ 3.0, 4.0 })));
@@ -137,8 +137,8 @@ main :: () {
{
r : Result = .ok(42);
ms := if r == {
case .ok: (v) { v; }
case .err: (e) { -1; }
case .ok: (v) { v }
case .err: (e) { -1 }
};
print("T9: {}\n", ms);
}
@@ -150,7 +150,7 @@ main :: () {
case 0: .none;
case 1: .circle(1.0);
else: .rect(.{ 9.0, 9.0 });
};
}
}
print("T10a: {}\n", if select(0) == { case .none: 1; else: 0; });
print("T10b: {}\n", select(1).circle);
@@ -176,7 +176,7 @@ main :: () {
// S3: Return .method(args) from function with return type
{
make_vec :: () -> Vec2 { .create(7.0, 8.0); }
make_vec :: () -> Vec2 { .create(7.0, 8.0) }
v := make_vec();
print("S3: {} {}\n", v.x, v.y);
}
@@ -253,7 +253,7 @@ main :: () {
// E3: Bare .variant (no parens) as function arg
{
check_none :: (sh: Shape) -> s32 {
if sh == { case .none: 1; else: 0; };
if sh == { case .none: 1; else: 0; }
}
print("E3: {}\n", check_none(.none));
}

View File

@@ -8,9 +8,9 @@
do_it :: () -> bool {
inline if OS != .ios { return false; }
true;
true
}
main :: () -> s32 {
if do_it() then 0 else 1;
if do_it() then 0 else 1
}

View File

@@ -32,5 +32,5 @@ main :: () -> s32 {
print("total: {}\n", p.total());
print("scaled: {}\n", p.scaled(3));
0;
0
}

View File

@@ -35,5 +35,5 @@ main :: () -> s32 {
// Inline unroll over a heterogeneous pack.
each(A.{ x = 1 }, B.{ s = "hi" }, A.{ x = 3 });
0;
0
}

View File

@@ -21,5 +21,5 @@ main :: () -> s32 {
case .none: { print("none\n"); }
}
}
0;
0
}

View File

@@ -5,13 +5,13 @@
Box :: struct {
v: s64;
boxed :: (self: Box) -> s64 { self.v; } // value receiver
boxed :: (self: Box) -> s64 { self.v } // value receiver
}
sum_ptr :: (xs: *List(s64)) -> s64 {
total : s64 = 0;
for xs: (n) { total = total + n; } // iterate through a *List
total;
total
}
main :: () -> s32 {
@@ -36,5 +36,5 @@ main :: () -> s32 {
bt : s64 = 0;
for bs: (*b) { bt = bt + b.boxed(); } // *Box receiver, value-self method
print("boxes {}\n", bt); // 7
0;
0
}

View File

@@ -4,18 +4,18 @@
#import "modules/test.sx";
pkg :: #import "modules/testpkg";
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (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;
self.base(msg) + 1
}
double_wrap :: (msg: string) -> s32 {
self.wrap(msg) + self.wrap(msg);
self.wrap(msg) + self.wrap(msg)
}
}

View File

@@ -48,7 +48,7 @@ main :: () {
}
// If block as expression
ibe := 10 + if true { 5; } else { 0; };
ibe := 10 + if true { 5 } else { 0 };
print("if-block-expr: {}\n", ibe);
// While basic

View File

@@ -4,24 +4,24 @@
#import "modules/test.sx";
pkg :: #import "modules/testpkg";
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (a: s32, b: s32) -> s32 { a * b; }
mul :: (a: s32, b: s32) -> s32 { a * b }
identity :: (x: $T) -> T { x; }
identity :: (x: $T) -> T { x }
pair_add :: (a: $T, b: $U) -> s64 {
cast(s64) a + cast(s64) b;
cast(s64) a + cast(s64) b
}
typed_sum :: (..args: []s32) -> s32 {
result := 0;
for args: (it) { result = result + it; }
result;
result
}
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
f(x, y);
f(x, y)
}
void_return :: () {
@@ -29,12 +29,12 @@ void_return :: () {
}
implicit_return :: (x: s32) -> s32 {
x * 2;
x * 2
}
early_return :: (x: s32) -> s32 {
if x > 10 { return 99; }
x;
x
}
main :: () {
@@ -84,7 +84,7 @@ main :: () {
print("lambda-ret: {}\n", halve(10.0));
// Local function (non-lambda)
local_add :: (a: s32, b: s32) -> s32 { a + b; }
local_add :: (a: s32, b: s32) -> s32 { a + b }
print("local-fn: {}\n", local_add(3, 4));
// Nested function calls

View File

@@ -19,11 +19,11 @@ main :: () {
// ========================================================
print("=== 19. Local Fn Return ===\n");
{
local_pt :: () -> Point { Point.{42, 99}; }
local_pt :: () -> Point { Point.{42, 99} }
lp := local_pt();
print("local-struct: {} {}\n", lp.x, lp.y);
local_sh :: () -> Shape { .circle(2.5); }
local_sh :: () -> Shape { .circle(2.5) }
ls := local_sh();
print("local-enum: {}\n", ls);
}

View File

@@ -6,7 +6,7 @@ pkg :: #import "modules/testpkg";
Point :: struct { x, y: s32; }
point_sum :: (p: Point) -> s32 { p.x + p.y; }
point_sum :: (p: Point) -> s32 { p.x + p.y }
// #run compile-time constants

View File

@@ -14,9 +14,9 @@ main :: () {
print("=== 22. If-Struct ===\n");
{
flag := true;
p := if flag { Point.{10, 20}; } else { Point.{30, 40}; };
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}; };
q := if !flag { Point.{10, 20} } else { Point.{30, 40} };
print("else-struct: {} {}\n", q.x, q.y);
}
}

View File

@@ -10,7 +10,7 @@ main :: () {
{
print("=== UFCS Aliases ===\n");
num_sum :: (a: s64, b: s64) -> s64 { a + b; }
num_sum :: (a: s64, b: s64) -> s64 { a + b }
sum :: ufcs num_sum;
print("{}\n", num_sum(40, 2)); // 42 — direct call
@@ -20,7 +20,7 @@ main :: () {
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; }
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)
@@ -28,14 +28,14 @@ main :: () {
print("{}\n", 1 |> calc(2, 3, 4)); // same = 3 — pipe UFCS
// Tuple return type
swap :: (a: s64, b: s64) -> (s64, s64) { (b, a); }
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,); }
wrap :: (x: s64) -> (s64) { (x,) }
t := wrap(99);
print("{}\n", t.0); // 99
}

View File

@@ -4,7 +4,7 @@
#import "modules/test.sx";
pkg :: #import "modules/testpkg";
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
main :: () {

View File

@@ -30,5 +30,5 @@ main :: () -> s32 {
// dead code after a `return` at main's own block level is dropped.
return 0;
print("unreachable\n");
print("unreachable\n")
}

View File

@@ -0,0 +1,46 @@
// Block value rule: a block's value is its last statement ONLY when that
// statement is a trailing expression with NO `;`. A trailing `;` discards the
// value, leaving the block void. This makes value-vs-statement explicit and lets
// the compiler reject "forgot to produce a value".
//
// { … expr } → value is `expr`
// { … expr; } → void (value discarded)
//
// Match arms are exempt: the arm `;` is an arm terminator, so `case .x: expr;`
// still yields `expr` (only an explicit inner braced block follows the rule).
#import "modules/std.sx";
// Implicit return: trailing expression, no `;`.
double :: (n: s32) -> s32 { n * 2 }
// if/else as a value — each branch's last expression has no `;`.
sign :: (n: s32) -> s32 {
if n < 0 { -1 } else if n > 0 { 1 } else { 0 }
}
// A value-producing block bound to a name.
sum3 :: (a: s32, b: s32, c: s32) -> s32 {
t := { x := a + b; x + c }; // block value is `x + c`
t
}
// Match arms keep their `;` (exempt): the arm `;` is an arm terminator, so each
// arm still yields its expression as the match value.
classify :: (n: s32) -> s32 {
if n == {
case 0: 100;
case 1: 10;
else: 7;
}
}
main :: () -> s32 {
total : s32 = 0;
total = total + double(10); // 20
total = total + sign(-7); // -1
total = total + sum3(1, 2, 3); // 6
total = total + classify(1); // 10
print("block-value total: {}\n", total); // 20 - 1 + 6 + 10 = 35
total
}

View File

@@ -0,0 +1,13 @@
// Rejection counterpart to 0040: a value-position block whose last expression's
// value is discarded by a trailing `;` produces no value. A `-> T` function
// whose body ends that way is a compile error (it used to silently return a
// zero default). Drop the `;` to return the value, or use an explicit `return`.
#import "modules/std.sx";
// `n * 2;` discards the value → the function returns nothing.
double :: (n: s32) -> s32 {
n * 2;
}
main :: () -> s32 { double(5) }

View File

@@ -6,11 +6,11 @@
Handle :: u32;
ok :: () -> Handle { 0; }
ok :: () -> Handle { 0 }
g : Handle = 0;
main :: () -> s32 {
g = ok();
if g == 0 then 0 else 1;
if g == 0 then 0 else 1
}

View File

@@ -30,5 +30,5 @@ main :: () -> s32 {
print("size_of(Maybe) = {}\n", size_of(Maybe));
print("size_of(Arr) = {}\n", size_of(Arr));
print("size_of(Cb) = {}\n", size_of(Cb));
0;
0
}

View File

@@ -18,5 +18,5 @@ main :: () -> s32 {
print("align chain: {}\n", align_of(MyChain));
print("size struct-alias: {}\n", size_of(WideAlias));
print("align struct-alias:{}\n", align_of(WideAlias));
0;
0
}

View File

@@ -24,5 +24,5 @@ main :: () -> s32 {
invoke_fn(@b, "hello");
if g_s.len == 0 { print("FAIL: empty\n"); return 1; }
print("got: <{}>\n", g_s);
0;
0
}

View File

@@ -8,8 +8,8 @@
Box :: struct { xs: (s32, s32); }
swap :: (a: s64, b: s64) -> (s64, s64) { (b, a); }
fst :: (t: (s64, s64)) -> s64 { t.0; }
swap :: (a: s64, b: s64) -> (s64, s64) { (b, a) }
fst :: (t: (s64, s64)) -> s64 { t.0 }
main :: () -> s32 {
// Inferred positional tuple + numeric field access.
@@ -51,5 +51,5 @@ main :: () -> s32 {
// typed correctly (s64 prints as a number, string as text).
mixed := (42, "hi");
print("mixed {} {}\n", mixed.0, mixed.1);
0;
0
}

View File

@@ -21,5 +21,5 @@ main :: () -> s32 {
print("p: x={} y={} .0={}\n", p.x, p.y, p.0);
p.0 = 33; // position write reaches the same slot as .x
print("p.x after .0=33: {}\n", p.x);
0;
0
}

View File

@@ -34,12 +34,12 @@ MyFloat :: f64;
Status :: enum u8 { ok; err; timeout; }
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (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];
.[x, y, z]
}
// Global variable for address-of test

View File

@@ -87,7 +87,7 @@ main :: () {
// Destructure from function return
{
dswap :: (a: s64, b: s64) -> (s64, s64) { (b, a); }
dswap :: (a: s64, b: s64) -> (s64, s64) { (b, a) }
dx, dy := dswap(1, 2);
print("fn: {} {}\n", dx, dy);
}

View File

@@ -15,24 +15,24 @@ OptInner :: struct { val: s32; }
OptOuter :: struct { inner: ?OptInner; }
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (a: s32, b: s32) -> s32 { a * b; }
mul :: (a: s32, b: s32) -> s32 { a * b }
identity :: (x: $T) -> T { x; }
identity :: (x: $T) -> T { x }
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
f(x, y);
f(x, y)
}
// P4 edge: Chained default→default calls
Chained :: protocol {
base :: (msg: string) -> s32;
wrap :: (msg: string) -> s32 {
self.base(msg) + 1;
self.base(msg) + 1
}
double_wrap :: (msg: string) -> s32 {
self.wrap(msg) + self.wrap(msg);
self.wrap(msg) + self.wrap(msg)
}
}
@@ -258,8 +258,8 @@ main :: () {
{
check :: (v: ?s32) -> s32 {
return if v == {
case .some: (val) { val; }
case .none: { 0; }
case .some: (val) { val }
case .none: { 0 }
};
}
a: ?s32 = 55;
@@ -909,9 +909,9 @@ main :: () {
p_f5.on_resize(p_f5.title, 800, 600);
// C5.E6: protocol value passed through multiple function calls
step3 :: (a: Allocator) -> *void { a.alloc(8); }
step2 :: (a: Allocator) -> *void { step3(a); }
step1 :: (a: Allocator) -> *void { step2(a); }
step3 :: (a: Allocator) -> *void { a.alloc(8) }
step2 :: (a: Allocator) -> *void { step3(a) }
step1 :: (a: Allocator) -> *void { step2(a) }
gpa_e6 := GPA.init();
a_e6 : Allocator = xx gpa_e6;
ptr_e6 := step1(a_e6);

View File

@@ -6,7 +6,7 @@ pkg :: #import "modules/testpkg";
Point :: struct { x, y: s32; }
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
Counter :: protocol {
inc :: ();
@@ -21,11 +21,11 @@ SimpleCounter :: struct { val: s32; }
impl Counter for SimpleCounter {
inc :: (self: *SimpleCounter) { self.val += 1; }
get :: (self: *SimpleCounter) -> s32 { self.val; }
get :: (self: *SimpleCounter) -> s32 { self.val }
}
impl Summable for Point {
sum :: (self: *Point) -> s32 { self.x + self.y; }
sum :: (self: *Point) -> s32 { self.x + self.y }
}
// Phase 2: #inline protocol for dynamic dispatch
@@ -38,7 +38,7 @@ Pair :: struct ($T: Type) {
impl Summable for Pair($T) {
sum :: (self: *Pair(T)) -> s32 {
xx self.a + xx self.b;
xx self.a + xx self.b
}
}
@@ -104,7 +104,7 @@ main :: () {
// IB5: init block + auto type erasure combined
{
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get() }
result := use_counter(SimpleCounter.{ val = 0 } {
self.val = 50;
});
@@ -123,11 +123,11 @@ main :: () {
h: f32;
create :: (w: f32, h: f32) -> Dims {
Dims.{ w = w, h = h };
Dims.{ w = w, h = h }
}
square :: (size: f32) -> Dims {
Dims.{ w = size, h = size };
Dims.{ w = size, h = size }
}
}
use_dims :: (d: Dims) { print("SM1: {} {}\n", d.w, d.h); }
@@ -142,7 +142,7 @@ main :: () {
b: s64;
make :: (a: s64, b: s64) -> Pair {
Pair.{ a = a, b = b };
Pair.{ a = a, b = b }
}
}
p : Pair = .make(10, 20);

View File

@@ -18,7 +18,7 @@ Complex :: ($T:Type) -> Type {
Vec3 :: Vec(3, f32);
vec3 :: (x:f32, y:f32, z:f32) -> Vector(3,f32) {
.[x, y, z];
.[x, y, z]
}
Foo :: Complex(u32);

View File

@@ -16,7 +16,7 @@ Size :: struct {
impl Lerpable for Size {
lerp :: (self: Size, b: Size, t: f32) -> Size {
Size.{ width = self.width + (b.width - self.width) * t,
height = self.height + (b.height - self.height) * t };
height = self.height + (b.height - self.height) * t }
}
}
@@ -32,7 +32,7 @@ Animated :: struct ($T: Lerpable) {
Animated(T).{
current = value, from = value, to = value,
elapsed = 0.0, duration = 0.0, active = false
};
}
}
set_immediate :: (self: *Animated(T), value: T) {

View File

@@ -10,9 +10,9 @@
Holder :: struct {
n: s64;
plain :: (self: *Holder) -> s64 { self.n; }
sized :: (self: *Holder, $T: Type) -> s64 { size_of(T); }
taking :: (self: *Holder, $T: Type, v: T) -> T { v; }
plain :: (self: *Holder) -> s64 { self.n }
sized :: (self: *Holder, $T: Type) -> s64 { size_of(T) }
taking :: (self: *Holder, $T: Type, v: T) -> T { v }
}
main :: () -> s32 {
@@ -24,5 +24,5 @@ main :: () -> s32 {
print("sized s64: {}\n", h.sized(s64));
print("taking explicit: {}\n", h.taking(s32, 42));
print("taking inferred: {}\n", h.taking(99));
0;
0
}

View File

@@ -33,5 +33,5 @@ main :: () -> s32 {
if g_a != 10 { print("FAIL: g_a={}\n", g_a); return 1; }
if g_b != 20 { print("FAIL: g_b={}\n", g_b); return 1; }
print("generic-into-block ok: a={} b={}\n", g_a, g_b);
0;
0
}

View File

@@ -2,7 +2,7 @@
main :: () {
fx :: (s:s3) -> s3 {
s;
s
}
print("{}\n", fx(133));

View File

@@ -1,10 +1,10 @@
#import "modules/std.sx";
add :: (a: s32, b: s32) -> s32 { a + b; }
mul :: (a: s32, b: s32) -> s32 { a * b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (a: s32, b: s32) -> s32 { a * b }
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
f(x, y);
f(x, y)
}
main :: () {

View File

@@ -9,11 +9,11 @@ MyProtocol :: protocol {
MyImpl :: struct { value: s64; }
impl MyProtocol for MyImpl {
get_value :: (self: *MyImpl) -> s64 { self.value; }
get_value :: (self: *MyImpl) -> s64 { self.value }
}
make_thing :: () -> MyProtocol {
MyImpl.{ value = 42 };
MyImpl.{ value = 42 }
}
main :: () -> void {

View File

@@ -16,5 +16,5 @@ main :: () -> s32 {
}};
c.on(.b);
c.on(.a);
0;
0
}

View File

@@ -17,7 +17,7 @@ Tracer :: struct {
init :: () -> *Tracer {
t : *Tracer = xx libc_malloc(size_of(Tracer));
t.count = 0;
t;
t
}
}
@@ -43,5 +43,5 @@ main :: () -> s32 {
_ = add_capture(1);
}
print("Tracer.count = {}\n", tracer.count);
0;
0
}

View File

@@ -24,5 +24,5 @@ main :: () -> s32 {
// argument-position, 3 params (s64, s64, string).
print("q={}\n", apply3((a, b, c) => a + b + c.len, 1, 2, "xyz")); // 1+2+3 = 6
0;
0
}

View File

@@ -7,11 +7,11 @@ Lerpable :: protocol #inline {
}
impl Lerpable for f32 {
lerp :: (self: f32, b: f32, t: f32) -> f32 { self + (b - self) * t; }
lerp :: (self: f32, b: f32, t: f32) -> f32 { self + (b - self) * t }
}
do_lerp :: (a: Lerpable, b: f32, t: f32) -> f32 {
a.lerp(b, t);
a.lerp(b, t)
}
main :: () -> void {

View File

@@ -10,7 +10,7 @@ Sizable :: protocol {
Widget :: struct { value: s64; }
impl Sizable for Widget {
size :: (self: *Widget) -> s64 { self.value; }
size :: (self: *Widget) -> s64 { self.value }
}
// Wrapper struct with a protocol field (like ViewChild)

View File

@@ -10,7 +10,7 @@ Sizable :: protocol {
Leaf :: struct { value: s64; }
impl Sizable for Leaf {
size :: (self: *Leaf) -> s64 { self.value; }
size :: (self: *Leaf) -> s64 { self.value }
}
add :: (items: *List(Sizable), w: Leaf) {

View File

@@ -10,7 +10,7 @@ Sizable :: protocol {
Leaf :: struct { value: s64; }
impl Sizable for Leaf {
size :: (self: *Leaf) -> s64 { self.value; }
size :: (self: *Leaf) -> s64 { self.value }
}
add :: (items: *List(Sizable), w: Leaf) {

View File

@@ -13,18 +13,18 @@ Drawable :: protocol {
Circle :: struct { radius: s32; }
impl Drawable for Circle {
draw :: (self: *Circle) -> s32 { self.radius; }
name :: (self: *Circle) -> string { "circle"; }
layout :: (self: *Circle, x: s32) -> s32 { x + self.radius; }
handle :: (self: *Circle, event: s32) -> bool { event > 0; }
draw :: (self: *Circle) -> s32 { self.radius }
name :: (self: *Circle) -> string { "circle" }
layout :: (self: *Circle, x: s32) -> s32 { x + self.radius }
handle :: (self: *Circle, event: s32) -> bool { event > 0 }
}
Square :: struct { side: s32; }
impl Drawable for Square {
draw :: (self: *Square) -> s32 { self.side * self.side; }
name :: (self: *Square) -> string { "square"; }
layout :: (self: *Square, x: s32) -> s32 { x + self.side; }
handle :: (self: *Square, event: s32) -> bool { event > 1; }
draw :: (self: *Square) -> s32 { self.side * self.side }
name :: (self: *Square) -> string { "square" }
layout :: (self: *Square, x: s32) -> s32 { x + self.side }
handle :: (self: *Square, event: s32) -> bool { event > 1 }
}
Rect :: struct {
@@ -32,7 +32,7 @@ Rect :: struct {
y: f32;
w: f32;
h: f32;
zero :: () -> Rect { Rect.{ x = 0.0, y = 0.0, w = 0.0, h = 0.0 }; }
zero :: () -> Rect { Rect.{ x = 0.0, y = 0.0, w = 0.0, h = 0.0 } }
}
Container :: struct {

View File

@@ -19,7 +19,7 @@ impl Proto for Impl {
take :: (f: Fmt) -> s64 {
n : s64 = xx f;
n;
n
}
main :: () -> s32 {
@@ -28,5 +28,5 @@ main :: () -> s32 {
p : Proto = xx @Impl.{};
p.take_fmt(.b);
p.take_fmt(.a);
0;
0
}

View File

@@ -16,7 +16,7 @@ Impl :: struct {
impl Proto for Impl {
get :: (self: *Impl) -> *u8 {
@self.val;
@self.val
}
}
@@ -26,5 +26,5 @@ main :: () -> s32 {
raw : *u8 = p.get();
addr_word : u64 = xx raw;
print("got pointer: {}\n", addr_word != 0);
0;
0
}

View File

@@ -10,11 +10,11 @@ MyTag :: struct { value: s64 = 0; }
impl Into(MyTag) for s64 {
convert :: (self: s64) -> MyTag {
.{ value = self };
.{ value = self }
}
}
main :: () -> s32 {
print("ok\n");
0;
0
}

View File

@@ -12,7 +12,7 @@ GPU :: protocol {
Impl :: struct {}
impl GPU for Impl {
ping :: (self: *Impl) -> s64 { 42; }
ping :: (self: *Impl) -> s64 { 42 }
}
main :: () -> s32 {
@@ -30,5 +30,5 @@ main :: () -> s32 {
} else {
print("BAD: g still null after assign\n");
}
0;
0
}

View File

@@ -26,5 +26,5 @@ main :: () -> s32 {
print("alloc_count: {}\n", gpa.alloc_count);
0;
0
}

View File

@@ -5,6 +5,6 @@
impl Into(Wrap) for s64 {
convert :: (self: s64) -> Wrap {
.{ v = self * 10 };
.{ v = self * 10 }
}
}

View File

@@ -6,5 +6,5 @@
run_user :: () -> s32 {
w : Wrap = xx 7;
print("user: w.v = {}\n", w.v);
0;
0
}

View File

@@ -18,4 +18,4 @@
#import "./0410-protocols-impl-visibility-impl.sx";
#import "./0410-protocols-impl-visibility-user.sx";
main :: () -> s32 { run_user(); }
main :: () -> s32 { run_user() }

View File

@@ -4,6 +4,6 @@
impl Into(Wrap) for s64 {
convert :: (self: s64) -> Wrap {
.{ v = self * 10 };
.{ v = self * 10 }
}
}

View File

@@ -4,6 +4,6 @@
impl Into(Wrap) for s64 {
convert :: (self: s64) -> Wrap {
.{ v = self + 100 };
.{ v = self + 100 }
}
}

View File

@@ -19,5 +19,5 @@
main :: () -> s32 {
w : Wrap = xx 7;
print("w.v = {}\n", w.v);
0;
0
}

View File

@@ -9,11 +9,11 @@
MyA :: struct { v: s64 = 0; }
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self }; }
convert :: (self: s64) -> MyA { .{ v = self } }
}
impl Into(MyA) for s64 {
convert :: (self: s64) -> MyA { .{ v = self * 2 }; }
convert :: (self: s64) -> MyA { .{ v = self * 2 } }
}
main :: () -> s32 { 0; }
main :: () -> s32 { 0 }

View File

@@ -18,5 +18,5 @@ main :: () -> s32 {
b : VL(string) = xx StrCell.{ s = "hi" };
print("b.get={}\n", b.get()); // hi (T = string)
0;
0
}

View File

@@ -29,5 +29,5 @@ make :: (..sources: VL) -> VL(s64) {
main :: () -> s32 {
r := make(IntCell.{ v = 1 });
print("{}\n", r.get()); // 99 (dispatch through the erased Combined)
0;
0
}

View File

@@ -49,24 +49,24 @@ WindowFlags :: enum flags u32 { vsync :: 64; resizable :: 4; hidden :: 128; }
// --- Top-level functions ---
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (a: s32, b: s32) -> s32 { a * b; }
mul :: (a: s32, b: s32) -> s32 { a * b }
identity :: (x: $T) -> T { x; }
identity :: (x: $T) -> T { x }
pair_add :: (a: $T, b: $U) -> s64 {
cast(s64) a + cast(s64) b;
cast(s64) a + cast(s64) b
}
typed_sum :: (..args: []s32) -> s32 {
result := 0;
for args: (it) { result = result + it; }
result;
result
}
apply :: (f: (s32, s32) -> s32, x: s32, y: s32) -> s32 {
f(x, y);
f(x, y)
}
void_return :: () {
@@ -74,19 +74,19 @@ void_return :: () {
}
implicit_return :: (x: s32) -> s32 {
x * 2;
x * 2
}
early_return :: (x: s32) -> s32 {
if x > 10 { return 99; }
x;
x
}
vec3 :: (x: f32, y: f32, z: f32) -> Vector(3, f32) {
.[x, y, z];
.[x, y, z]
}
point_sum :: (p: Point) -> s32 { p.x + p.y; }
point_sum :: (p: Point) -> s32 { p.x + p.y }
// #run compile-time constants
@@ -215,11 +215,11 @@ SimpleCounter :: struct { val: s32; }
impl Counter for SimpleCounter {
inc :: (self: *SimpleCounter) { self.val += 1; }
get :: (self: *SimpleCounter) -> s32 { self.val; }
get :: (self: *SimpleCounter) -> s32 { self.val }
}
impl Summable for Point {
sum :: (self: *Point) -> s32 { self.x + self.y; }
sum :: (self: *Point) -> s32 { self.x + self.y }
}
// Phase 2: #inline protocol for dynamic dispatch
@@ -236,14 +236,14 @@ Accumulator :: struct {
impl Adder for Accumulator {
add :: (self: *Accumulator, n: s32) { self.total += n; }
value :: (self: *Accumulator) -> s32 { self.total; }
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; }
value :: (self: *Doubler) -> s32 { self.val }
}
// Phase 4: default methods
@@ -272,10 +272,10 @@ impl Repeater for Printer {
Chained :: protocol {
base :: (msg: string) -> s32;
wrap :: (msg: string) -> s32 {
self.base(msg) + 1;
self.base(msg) + 1
}
double_wrap :: (msg: string) -> s32 {
self.wrap(msg) + self.wrap(msg);
self.wrap(msg) + self.wrap(msg)
}
}
@@ -283,7 +283,7 @@ ChainImpl :: struct { val: s32; }
impl Chained for ChainImpl {
base :: (self: *ChainImpl, msg: string) -> s32 {
self.val += 1;
msg.len;
msg.len
}
}
@@ -296,7 +296,7 @@ Eq :: protocol {
impl Eq for Point {
eq :: (self: *Point, other: Point) -> bool {
self.x == other.x and self.y == other.y;
self.x == other.x and self.y == other.y
}
}
@@ -306,13 +306,13 @@ Cloneable :: protocol {
impl Cloneable for Point {
clone :: (self: *Point) -> Point {
Point.{ x = self.x, y = self.y };
Point.{ x = self.x, y = self.y }
}
}
impl Eq for s64 {
eq :: (self: *s64, other: s64) -> bool {
self.* == other;
self.* == other
}
}
@@ -320,7 +320,7 @@ impl Eq for s64 {
// Phase 6: Generic constraints
are_equal :: ($T: Type/Eq, a: T, b: T) -> bool {
a.eq(b);
a.eq(b)
}
Hashable :: protocol {
@@ -329,20 +329,20 @@ Hashable :: protocol {
impl Hashable for Point {
hash :: (self: *Point) -> s64 {
xx self.x * 31 + xx self.y;
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);
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();
a.sum() + b.sum()
}
// Phase 7: Generic struct impls
@@ -355,7 +355,7 @@ Pair :: struct ($T: Type) {
impl Summable for Pair($T) {
sum :: (self: *Pair(T)) -> s32 {
xx self.a + xx self.b;
xx self.a + xx self.b
}
}
@@ -435,7 +435,7 @@ main :: () {
{
use_adder :: (a: Adder, n: s32) -> s32 {
a.add(n);
a.value();
a.value()
}
acc := Accumulator.{ total = 100 };
result := use_adder(xx @acc, 50);
@@ -470,7 +470,7 @@ main :: () {
use_counter :: (c: Counter) -> s32 {
c.inc();
c.inc();
c.get();
c.get()
}
sc := SimpleCounter.{ val = 10 };
result := use_counter(xx @sc);
@@ -603,14 +603,14 @@ main :: () {
// P2.7: xx on inline struct literal (no intermediate variable)
{
use_adder :: (a: Adder) -> s32 { a.add(10); a.value(); }
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(); }
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get() }
result := use_counter(xx SimpleCounter.{ val = 100 });
print("P3.3: {}\n", result);
}

View File

@@ -6,7 +6,7 @@ pkg :: #import "modules/testpkg";
Point :: struct { x, y: s32; }
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
Counter :: protocol {
inc :: ();
@@ -21,11 +21,11 @@ SimpleCounter :: struct { val: s32; }
impl Counter for SimpleCounter {
inc :: (self: *SimpleCounter) { self.val += 1; }
get :: (self: *SimpleCounter) -> s32 { self.val; }
get :: (self: *SimpleCounter) -> s32 { self.val }
}
impl Summable for Point {
sum :: (self: *Point) -> s32 { self.x + self.y; }
sum :: (self: *Point) -> s32 { self.x + self.y }
}
// Phase 2: #inline protocol for dynamic dispatch
@@ -42,7 +42,7 @@ Accumulator :: struct {
impl Adder for Accumulator {
add :: (self: *Accumulator, n: s32) { self.total += n; }
value :: (self: *Accumulator) -> s32 { self.total; }
value :: (self: *Accumulator) -> s32 { self.total }
}
main :: () {
@@ -52,7 +52,7 @@ main :: () {
// AE1: function argument — concrete passed where protocol expected (no xx)
{
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get() }
sc := SimpleCounter.{ val = 10 };
result := use_counter(sc);
print("AE1: {}\n", result);
@@ -69,14 +69,14 @@ main :: () {
// AE3: struct literal passed directly (no xx)
{
use_counter :: (c: Counter) -> s32 { c.inc(); c.inc(); c.get(); }
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(); }
use_counter :: (c: Counter) -> s32 { c.inc(); c.get() }
result := use_counter(xx SimpleCounter.{ val = 50 });
print("AE4: {}\n", result);
}

View File

@@ -5,7 +5,7 @@ sum :: (..args: []s32) -> s32 {
for args: (it) {
result = result + it;
}
result;
result
}
print_all :: (..args: []s32) {
@@ -31,5 +31,5 @@ main :: () -> s32 {
out(" ");
}
out("\n");
0;
0
}

View File

@@ -29,7 +29,7 @@ print_any :: (..args: []Any) {
}
count :: (..args: []Any) -> s32 {
args.len;
args.len
}
main :: () -> s32 {
@@ -43,5 +43,5 @@ main :: () -> s32 {
out(int_to_string(count(1, 2, 3)));
out("\n");
0;
0
}

View File

@@ -34,7 +34,7 @@ impl Into(Block) for Closure(..$args) -> $R {
descriptor = xx @__sx_block_descriptor,
sx_env = self.env,
sx_fn = self.fn_ptr,
};
}
}
}

View File

@@ -35,5 +35,5 @@ main :: () -> s32 {
print("n0={}\n", howmany()); // empty pack
print("n2={}\n", howmany(a, b)); // two elements
print("n3={}\n", howmany(a, b, c)); // heterogeneous: IntBox, IntBox, StrBox
0;
0
}

View File

@@ -20,5 +20,5 @@ main :: () -> s32 {
a := IntBox.{ v = 1 };
n := Naked.{ x = 2 };
print("{}\n", howmany(a, n)); // `n` does not conform to Show
0;
0
}

View File

@@ -27,5 +27,5 @@ main :: () -> s32 {
print("dog+cat={}\n", pair_sum(d, c)); // 3 + 900 = 903 (heterogeneous)
print("cat+dog={}\n", pair_sum(c, d)); // 900 + 3 = 903 (order swapped)
print("dog+dog={}\n", pair_sum(d, Dog.{ age = 4 })); // 3 + 4 = 7
0;
0
}

View File

@@ -26,5 +26,5 @@ describe :: (..xs: Box) -> void {
main :: () -> s32 {
describe(IntCell.{ v = 11 }, StrCell.{ s = "hi" });
describe(StrCell.{ s = "x" }, IntCell.{ v = 99 });
0;
0
}

View File

@@ -18,5 +18,5 @@ leak :: (..xs: Box) -> s64 {
main :: () -> s32 {
print("{}\n", leak(IntCell.{ v = 5 }));
0;
0
}

View File

@@ -24,5 +24,5 @@ show :: (..xs: Box) -> void {
main :: () -> s32 {
show(IntCell.{ v = 42 }, StrCell.{ s = "hi" });
show(StrCell.{ s = "x" }, IntCell.{ v = 7 }); // order swapped → (string, s64)
0;
0
}

View File

@@ -22,5 +22,5 @@ via3 :: (..xs: Box) -> s64 { return add3(..xs.get); }
main :: () -> s32 {
print("two={}\n", via2(IntCell.{ v = 10 }, Dbl.{ n = 5 })); // 10 + 10 = 20
print("three={}\n", via3(Dbl.{ n = 1 }, IntCell.{ v = 2 }, Dbl.{ n = 3 })); // 2 + 2 + 6 = 10
0;
0
}

View File

@@ -21,5 +21,5 @@ snapshot :: (..xs: Box) -> void {
main :: () -> s32 {
snapshot(IntCell.{ v = 42 }, StrCell.{ s = "hi" });
snapshot(StrCell.{ s = "x" }, IntCell.{ v = 7 }); // order swapped → (string, s64)
0;
0
}

View File

@@ -34,5 +34,5 @@ fold :: (..xs: Box) -> s64 {
main :: () -> s32 {
snap(IntCell.{ v = 42 }, StrCell.{ s = "hi" }); // (s64, string)
print("fold={}\n", fold(IntCell.{ v = 10 }, Dbl.{ n = 5 })); // 10 + 10 = 20
0;
0
}

View File

@@ -27,5 +27,5 @@ each :: (..xs: []Show) -> void {
main :: () -> s32 {
each(A.{ x = 1 }, B.{ s = "hi" }, A.{ x = 3 }); // heterogeneous, erased to Show
each(); // empty is fine (len 0)
0;
0
}

View File

@@ -21,5 +21,5 @@ main :: () -> s32 {
call(A.{});
_ = ret(A.{});
iter(A.{});
0;
0
}

View File

@@ -28,5 +28,5 @@ fwd_show :: (..xs: Show) -> s64 { return show_all(xx xs); }
main :: () -> s32 {
print("any={}\n", fwd_any(1, "hi", 2.5)); // 3
print("show={}\n", fwd_show(A.{}, B.{ s = "x" }, A.{})); // A B A, 3
0;
0
}

View File

@@ -21,5 +21,5 @@ main :: () -> s32 {
b : Box(bool, string, bool) = ---; // Ts=[string, bool], pair: (string, bool)
b.pair = ("x", true);
print("b: 0={} 1={}\n", b.pair.0, b.pair.1);
0;
0
}

View File

@@ -25,5 +25,5 @@ main :: () -> s32 {
c.sources = (xx IntCell.{ v = 10 }, xx StrCell.{ s = "hi" });
c.value = 99;
print("{} {} {}\n", c.sources.0.get(), c.sources.1.get(), c.value); // 10 hi 99
0;
0
}

View File

@@ -23,5 +23,5 @@ make :: (..sources: VL) -> s64 {
main :: () -> s32 {
print("{}\n", make(IntCell.{ v = 7 })); // 7
0;
0
}

View File

@@ -24,5 +24,5 @@ build :: (..sources: VL) -> void {
main :: () -> s32 {
build(IntCell.{ v = 10 }, StrCell.{ s = "hi" }); // 10 hi
0;
0
}

View File

@@ -14,5 +14,5 @@ apply :: (mapper: Closure(s64, s64) -> s64, ..sources: VL) -> s64 {
main :: () -> s32 {
print("{}\n", apply((a, b) => a + b, IntCell.{ v = 40 }, IntCell.{ v = 2 })); // 42
0;
0
}

View File

@@ -32,5 +32,5 @@ map :: (mapper: Closure(..sources.T) -> $R, ..sources: VL) -> VL($R) {
main :: () -> s32 {
r := map((a, b) => a + b, IntCell.{ v = 40 }, IntCell.{ v = 2 });
print("{}\n", r.get()); // 42
0;
0
}

View File

@@ -2,7 +2,7 @@
#import "modules/math";
test :: () -> s32 {
0;
0
}
Vec4 :: Vector(4,f32);

View File

@@ -15,12 +15,12 @@ R :: struct { x: s32; }
bug :: (cmd: [:0]u8) -> ?R {
f := popen(cmd, "r");
if cast(s64) f == 0 { return null; }
R.{ x = 1 };
R.{ x = 1 }
}
post_link :: () -> bool {
if r := bug("echo hi") { puts("ok"); } else { puts("null"); }
true;
true
}
configure :: () {

View File

@@ -17,7 +17,7 @@ cb :: () -> bool {
puts("2-arg ok");
c := format("{} {} {}", "x", "y", "z");
puts("3-arg ok");
true;
true
}
configure :: () {

View File

@@ -35,7 +35,7 @@ sum_bytes :: (buf: [*]u8) -> s64 {
s : s64 = 0;
i : s64 = 0;
while i < BUF_SIZE { s += xx buf[i]; i += 1; }
s;
s
}
run_u8 :: () -> s64 {
@@ -45,7 +45,7 @@ run_u8 :: () -> s64 {
p.* = 0x42;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_u16 :: () -> s64 {
@@ -55,7 +55,7 @@ run_u16 :: () -> s64 {
p.* = 0x0102;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_u32 :: () -> s64 {
@@ -65,7 +65,7 @@ run_u32 :: () -> s64 {
p.* = 0x01020304;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_u64 :: () -> s64 {
@@ -75,7 +75,7 @@ run_u64 :: () -> s64 {
p.* = 0x0102030405060708;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_s8 :: () -> s64 {
@@ -85,7 +85,7 @@ run_s8 :: () -> s64 {
p.* = 0x42;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_s16 :: () -> s64 {
@@ -95,7 +95,7 @@ run_s16 :: () -> s64 {
p.* = 0x0102;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_s32 :: () -> s64 {
@@ -105,7 +105,7 @@ run_s32 :: () -> s64 {
p.* = 0x01020304;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_s64 :: () -> s64 {
@@ -115,7 +115,7 @@ run_s64 :: () -> s64 {
p.* = 0x0102030405060708;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_bool :: () -> s64 {
@@ -125,7 +125,7 @@ run_bool :: () -> s64 {
p.* = true;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_f32 :: () -> s64 {
@@ -135,7 +135,7 @@ run_f32 :: () -> s64 {
p.* = 1.0;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
run_f64 :: () -> s64 {
@@ -145,7 +145,7 @@ run_f64 :: () -> s64 {
p.* = 1.0;
s := sum_bytes(buf);
free(xx buf);
s;
s
}
// ── comptime-baked expected checksums ───────────────────────────────
@@ -169,7 +169,7 @@ EXP_F64 :: #run run_f64();
check :: (label: string, got: s64, want: s64) -> bool {
if got == want { return true; }
print("FAIL {}: comptime={} runtime={}\n", label, want, got);
false;
false
}
main :: () -> s32 {

View File

@@ -4,9 +4,9 @@
#import "modules/test.sx";
pkg :: #import "modules/testpkg";
add :: (a: s32, b: s32) -> s32 { a + b; }
add :: (a: s32, b: s32) -> s32 { a + b }
mul :: (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);

View File

@@ -13,4 +13,5 @@ main :: () -> s32 {
v:= std.Vector(3,f32).[1,2,3];
std.print("\n{}\n", v);
0
}

View File

@@ -10,5 +10,5 @@ main :: () -> s32 {
b := multiply(5, 6);
print("add_numbers(10, 20) = {}\n", a);
print("multiply(5, 6) = {}\n", b);
0;
0
}

View File

@@ -6,5 +6,5 @@ main :: () -> s32 {
b := tc.multiply(5, 6);
print("tc.add_numbers(10, 20) = {}\n", a);
print("tc.multiply(5, 6) = {}\n", b);
0;
0
}

View File

@@ -7,6 +7,6 @@ Wrap :: struct { v: s64 = 0; }
impl Into(Wrap) for s64 {
convert :: (self: s64) -> Wrap {
.{ v = self * 10 };
.{ v = self * 10 }
}
}

View File

@@ -9,5 +9,5 @@
main :: () -> s32 {
w : Wrap = xx 3;
print("w.v = {}\n", w.v);
0;
0
}

View File

@@ -14,5 +14,5 @@ main :: () -> s32 {
print("b_only_fn: {}\n", b_only_fn());
print("c_only_fn direct: {}\n", c_only_fn());
print("c_only_const direct: {}\n", c_only_const);
0;
0
}

View File

@@ -1,5 +1,5 @@
#import "c.sx";
b_only_fn :: () -> s32 {
c_only_fn() + c_only_const;
c_only_fn() + c_only_const
}

View File

@@ -1,2 +1,2 @@
c_only_fn :: () -> s32 { 42; }
c_only_fn :: () -> s32 { 42 }
c_only_const :: 7;

View File

@@ -25,5 +25,5 @@ main :: () -> s32 {
case .a: { print("a\n"); }
case .b: (v) { print("b={}\n", v); }
}
0;
0
}

View File

@@ -16,5 +16,5 @@ build :: (n: s32) -> string {
result = concat(result, line);
i = i + 1;
}
result;
result
}

View File

@@ -15,5 +15,5 @@
main :: () -> s32 {
w : Wrapped = xx 7;
print("{}\n", w.v);
0;
0
}

Some files were not shown because too many files have changed in this diff Show More