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:
@@ -1,5 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
if false then 40 else 42;
|
||||
if false then 40 else 42
|
||||
}
|
||||
@@ -10,6 +10,7 @@ main :: () -> s32 {
|
||||
print("scoped x: {}\n", x); //expect 6
|
||||
}
|
||||
print("main x: {}\n", x); //expect 42
|
||||
0
|
||||
}
|
||||
|
||||
// ** stdout **
|
||||
|
||||
@@ -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 :: () {
|
||||
|
||||
@@ -7,7 +7,7 @@ sumOf10 :: () -> s32 {
|
||||
s+=i;
|
||||
i+=1;
|
||||
}
|
||||
s;
|
||||
s
|
||||
}
|
||||
|
||||
someSum :: #run sumOf10();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -32,5 +32,5 @@ main :: () -> s32 {
|
||||
print("total: {}\n", p.total());
|
||||
print("scaled: {}\n", p.scaled(3));
|
||||
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ main :: () -> s32 {
|
||||
|
||||
// Inline unroll over a heterogeneous pack.
|
||||
each(A.{ x = 1 }, B.{ s = "hi" }, A.{ x = 3 });
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -21,5 +21,5 @@ main :: () -> s32 {
|
||||
case .none: { print("none\n"); }
|
||||
}
|
||||
}
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 :: () {
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
46
examples/0040-basic-block-value.sx
Normal file
46
examples/0040-basic-block-value.sx
Normal 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
|
||||
}
|
||||
13
examples/0041-basic-block-value-reject.sx
Normal file
13
examples/0041-basic-block-value-reject.sx
Normal 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) }
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
main :: () {
|
||||
fx :: (s:s3) -> s3 {
|
||||
s;
|
||||
s
|
||||
}
|
||||
|
||||
print("{}\n", fx(133));
|
||||
|
||||
@@ -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 :: () {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -16,5 +16,5 @@ main :: () -> s32 {
|
||||
}};
|
||||
c.on(.b);
|
||||
c.on(.a);
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -26,5 +26,5 @@ main :: () -> s32 {
|
||||
|
||||
print("alloc_count: {}\n", gpa.alloc_count);
|
||||
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
impl Into(Wrap) for s64 {
|
||||
convert :: (self: s64) -> Wrap {
|
||||
.{ v = self * 10 };
|
||||
.{ v = self * 10 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
run_user :: () -> s32 {
|
||||
w : Wrap = xx 7;
|
||||
print("user: w.v = {}\n", w.v);
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
|
||||
impl Into(Wrap) for s64 {
|
||||
convert :: (self: s64) -> Wrap {
|
||||
.{ v = self * 10 };
|
||||
.{ v = self * 10 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
|
||||
impl Into(Wrap) for s64 {
|
||||
convert :: (self: s64) -> Wrap {
|
||||
.{ v = self + 100 };
|
||||
.{ v = self + 100 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
main :: () -> s32 {
|
||||
w : Wrap = xx 7;
|
||||
print("w.v = {}\n", w.v);
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -18,5 +18,5 @@ main :: () -> s32 {
|
||||
|
||||
b : VL(string) = xx StrCell.{ s = "hi" };
|
||||
print("b.get={}\n", b.get()); // hi (T = string)
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -18,5 +18,5 @@ leak :: (..xs: Box) -> s64 {
|
||||
|
||||
main :: () -> s32 {
|
||||
print("{}\n", leak(IntCell.{ v = 5 }));
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -21,5 +21,5 @@ main :: () -> s32 {
|
||||
call(A.{});
|
||||
_ = ret(A.{});
|
||||
iter(A.{});
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -23,5 +23,5 @@ make :: (..sources: VL) -> s64 {
|
||||
|
||||
main :: () -> s32 {
|
||||
print("{}\n", make(IntCell.{ v = 7 })); // 7
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ build :: (..sources: VL) -> void {
|
||||
|
||||
main :: () -> s32 {
|
||||
build(IntCell.{ v = 10 }, StrCell.{ s = "hi" }); // 10 hi
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#import "modules/math";
|
||||
|
||||
test :: () -> s32 {
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
Vec4 :: Vector(4,f32);
|
||||
|
||||
@@ -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 :: () {
|
||||
|
||||
@@ -17,7 +17,7 @@ cb :: () -> bool {
|
||||
puts("2-arg ok");
|
||||
c := format("{} {} {}", "x", "y", "z");
|
||||
puts("3-arg ok");
|
||||
true;
|
||||
true
|
||||
}
|
||||
|
||||
configure :: () {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,4 +13,5 @@ main :: () -> s32 {
|
||||
v:= std.Vector(3,f32).[1,2,3];
|
||||
|
||||
std.print("\n{}\n", v);
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ Wrap :: struct { v: s64 = 0; }
|
||||
|
||||
impl Into(Wrap) for s64 {
|
||||
convert :: (self: s64) -> Wrap {
|
||||
.{ v = self * 10 };
|
||||
.{ v = self * 10 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
main :: () -> s32 {
|
||||
w : Wrap = xx 3;
|
||||
print("w.v = {}\n", w.v);
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "c.sx";
|
||||
|
||||
b_only_fn :: () -> s32 {
|
||||
c_only_fn() + c_only_const;
|
||||
c_only_fn() + c_only_const
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
c_only_fn :: () -> s32 { 42; }
|
||||
c_only_fn :: () -> s32 { 42 }
|
||||
c_only_const :: 7;
|
||||
|
||||
@@ -25,5 +25,5 @@ main :: () -> s32 {
|
||||
case .a: { print("a\n"); }
|
||||
case .b: (v) { print("b={}\n", v); }
|
||||
}
|
||||
0;
|
||||
0
|
||||
}
|
||||
|
||||
@@ -16,5 +16,5 @@ build :: (n: s32) -> string {
|
||||
result = concat(result, line);
|
||||
i = i + 1;
|
||||
}
|
||||
result;
|
||||
result
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user