so... jai :D
This commit is contained in:
5
examples/01-basic.sx
Normal file
5
examples/01-basic.sx
Normal file
@@ -0,0 +1,5 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
if false then 40 else 42;
|
||||
}
|
||||
4
examples/02-stdout.sx
Normal file
4
examples/02-stdout.sx
Normal file
@@ -0,0 +1,4 @@
|
||||
#import "modules/std.sx";
|
||||
main :: () {
|
||||
print("Hello\n");
|
||||
}
|
||||
22
examples/03-structs.sx
Normal file
22
examples/03-structs.sx
Normal file
@@ -0,0 +1,22 @@
|
||||
#import "modules/std.sx";
|
||||
Vec4 :: struct {
|
||||
x, y, z, w: f32;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
v1 : Vec4 = .{ 1, 2, 3, 0};
|
||||
v2 := Vec4.{ 4, 1, 1, 3};
|
||||
v3 := Vec4.{ w=0, x=2, y=3, z=4};
|
||||
z := 5.0; // z is f32
|
||||
w := 6.0; // w is f32
|
||||
v4 := Vec4.{ y=3, x=9, w, z};
|
||||
|
||||
v4.y = 0;
|
||||
print("v1: {}\nv2: {}\nv3: {}\nv4: {}\n", v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
// ** stdout **
|
||||
//v1: Vec4{x:1.0, y:2.0, z:3.0, w:0.0}
|
||||
//v2: Vec4{x:4.0, y:1.0, z:1.0, w:3.0}
|
||||
//v3: Vec4{x:2.0, y:3.0, z:4.0, w:0.0}
|
||||
//v4: Vec4{x:9.0, y:3.0, z:5.0, w:6.0}
|
||||
20
examples/04-shadow.sx
Normal file
20
examples/04-shadow.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
#import "modules/std.sx";
|
||||
main :: () -> s32 {
|
||||
x := 42;
|
||||
{
|
||||
print("scope opened\n");
|
||||
defer print("scope closed\n");
|
||||
|
||||
// define a inner variable x shadowing the one define in the outer scope(s)
|
||||
x:= 6;
|
||||
print("scoped x: {}\n", x); //expect 6
|
||||
}
|
||||
print("main x: {}\n", x); //expect 42
|
||||
}
|
||||
|
||||
// ** stdout **
|
||||
// scope opened
|
||||
// scoped x: 6
|
||||
// scope closed
|
||||
// main x: 42
|
||||
//
|
||||
20
examples/05-run.sx
Normal file
20
examples/05-run.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
#import "modules/std.sx";
|
||||
// this will bake x to be 7 as a global constant
|
||||
x :: #run compute(5);
|
||||
|
||||
compute :: (v: s32) -> s32 => v + 2;
|
||||
|
||||
main :: () {
|
||||
//test
|
||||
y :: #run compute(7);
|
||||
c :: 2;
|
||||
print("hello {}\n", x + y * c);
|
||||
}
|
||||
|
||||
#run main();
|
||||
|
||||
// ** stdout after build **
|
||||
// hello 25
|
||||
|
||||
// ** stdout after run **
|
||||
// hello 25
|
||||
17
examples/06-generic.sx
Normal file
17
examples/06-generic.sx
Normal file
@@ -0,0 +1,17 @@
|
||||
#import "modules/std.sx";
|
||||
sum :: (a:$T, b:T) -> T {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
x:=sum(2,3);
|
||||
|
||||
print("sum: {}\n", x);
|
||||
print("sum: {}\n", sum(40,2));
|
||||
print("sum: {}\n", sum(40,2.5));
|
||||
}
|
||||
|
||||
// ** stdout **
|
||||
// sum: 42
|
||||
// sum: 42.500000
|
||||
//
|
||||
11
examples/07-defer.sx
Normal file
11
examples/07-defer.sx
Normal file
@@ -0,0 +1,11 @@
|
||||
#import "modules/std.sx";
|
||||
main :: () -> s32 {
|
||||
defer print("still here\n");
|
||||
return 42;
|
||||
}
|
||||
|
||||
// ** exit code **
|
||||
// 42
|
||||
// ** stdout **
|
||||
// still here
|
||||
//
|
||||
43
examples/08-types.sx
Normal file
43
examples/08-types.sx
Normal file
@@ -0,0 +1,43 @@
|
||||
#import "modules/std.sx";
|
||||
SPECIAL_VALUE :u8: 42;
|
||||
|
||||
resolve :: (x: u8) -> s32 {
|
||||
return 12 + x;
|
||||
}
|
||||
|
||||
Foo :: struct {
|
||||
a : u2; // this will have 0 as default
|
||||
b : u8 = SPECIAL_VALUE;
|
||||
c : u8 = ---; // default for c is undefined
|
||||
d : u8 = #run xx resolve(5); // converts s32 to u8
|
||||
}
|
||||
|
||||
main :: () {
|
||||
a : Foo; // default value of 0
|
||||
print("a 0 : {}\n", a);
|
||||
a.a = 1;
|
||||
// a.c is still undefined at this point
|
||||
a.c = 8;
|
||||
print("a 1 : {}\n", a);
|
||||
|
||||
large: f64 = 5989.5;
|
||||
b : Foo = ---; // undefined
|
||||
b.a = 1;
|
||||
b.c = xx large; // converts f64 to u8
|
||||
// expect stdout : "b: Foo{a:1, b: 42, c: 7, d: 12}"
|
||||
print("b: {}", b);
|
||||
print("\n");
|
||||
|
||||
f := Pack.{1,0,3,5,9,100,3.5};
|
||||
print("{}\n", f);
|
||||
}
|
||||
|
||||
Pack :: struct {
|
||||
a: u1;
|
||||
b: u2;
|
||||
c: u8;
|
||||
d: u32;
|
||||
f: u64;
|
||||
v: s32;
|
||||
x: f32;
|
||||
}
|
||||
16
examples/09-import.sx
Normal file
16
examples/09-import.sx
Normal file
@@ -0,0 +1,16 @@
|
||||
std :: #import "modules/std.sx";
|
||||
|
||||
//flat
|
||||
#import "modules/math.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
{
|
||||
defer std.print("after hello");
|
||||
//expect stdout : hello there
|
||||
std.print("hello there");
|
||||
}
|
||||
|
||||
v:= std.Vector(3,f32).[1,2,3];
|
||||
|
||||
std.print("\n{}\n", v);
|
||||
}
|
||||
91
examples/10-generic-struct.sx
Normal file
91
examples/10-generic-struct.sx
Normal file
@@ -0,0 +1,91 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Vec :: struct($N: u32, $T:Type) {
|
||||
// <N x T> (LLVM Vector)
|
||||
// Vector is a Builtin Type
|
||||
data: Vector(N,T);
|
||||
}
|
||||
|
||||
Complex :: ($T:Type) -> Type {
|
||||
return struct {
|
||||
value: T;
|
||||
//..inject
|
||||
count: u32;
|
||||
};
|
||||
}
|
||||
|
||||
Vec3 :: Vec(3, f32);
|
||||
|
||||
vec3 :: (x:f32, y:f32, z:f32) -> Vector(3,f32) {
|
||||
.[x, y, z];
|
||||
}
|
||||
|
||||
Foo :: Complex(u32);
|
||||
|
||||
main :: () {
|
||||
v1 := Vec3.{data = .[1,3,2]};
|
||||
print("v1: {}\n", v1);
|
||||
//stdout: Vec(3,f32){data: [1.0, 3.0, 2.0]}
|
||||
//
|
||||
|
||||
v2 := vec3(1,3,2);
|
||||
print("v2: {}\n", v2);
|
||||
//stdout: [1.0, 3.0, 2.0]
|
||||
//
|
||||
|
||||
// [N x T] (LLVM Array)
|
||||
buffer : [5]f32 = .[0, 2, 3.5, 4, 0];
|
||||
print("buff: {}\n", buffer);
|
||||
//stdout: [0.0, 2.0, 3.5, 4.0, 0.0]
|
||||
//
|
||||
|
||||
comp : Foo = .{value = 42, count = 1};
|
||||
print("comp: {}\n", comp);
|
||||
//stdout: Foo{value: 42, count: 1}
|
||||
//
|
||||
|
||||
// Vector arithmetic
|
||||
v3 := vec3(3,2,1);
|
||||
add := v2 + v3;
|
||||
print("add: {}\n", add);
|
||||
|
||||
// Element access
|
||||
v2x := v2.x;
|
||||
print("v2.x: {}\n", v2x);
|
||||
|
||||
// Index access
|
||||
v2i := v2[1];
|
||||
print("v2[1]: {}\n", v2i);
|
||||
|
||||
// Scalar broadcast
|
||||
scaled := v2 * 2.0;
|
||||
print("scaled: {}\n", scaled);
|
||||
|
||||
// Negation
|
||||
neg := -v2;
|
||||
print("neg: {}\n", neg);
|
||||
|
||||
// sqrt
|
||||
s := sqrt(9.0);
|
||||
print("sqrt(9): {}\n", s);
|
||||
|
||||
// inline generic type
|
||||
Sx :: (user: $T) -> Type {
|
||||
return union {
|
||||
counter: s32;
|
||||
user: T;
|
||||
};
|
||||
}
|
||||
|
||||
sx := Sx(f32).user(0.5);
|
||||
print("{}\n", sx);
|
||||
|
||||
print("{}\n", size_of(f32));
|
||||
print("{}\n", size_of(Sx(f32)));
|
||||
print("{}\n", size_of(Foo));
|
||||
print("{}\n", size_of(Complex));
|
||||
|
||||
|
||||
size:= size_of(Sx);
|
||||
print("{}\n", size);
|
||||
}
|
||||
28
examples/11-vector-math.sx
Normal file
28
examples/11-vector-math.sx
Normal file
@@ -0,0 +1,28 @@
|
||||
#import "modules/std.sx";
|
||||
math :: #import "modules/std/math.sx";
|
||||
|
||||
vec3 :: (x:f32, y:f32, z:f32) -> Vector(3,f32) {
|
||||
.[x, y, z];
|
||||
}
|
||||
|
||||
main :: () {
|
||||
a := vec3(1, 0, 0);
|
||||
b := vec3(0, 1, 0);
|
||||
|
||||
// dot product
|
||||
d := math.dot(a, b);
|
||||
print("dot: {}\n", d);
|
||||
|
||||
// cross product
|
||||
cr := math.cross(a, b);
|
||||
print("cross: {}\n", cr);
|
||||
|
||||
// length
|
||||
v := vec3(3, 4, 0);
|
||||
len := math.length(v);
|
||||
print("length: {}\n", len);
|
||||
|
||||
// normalize
|
||||
n := math.normalize(v);
|
||||
print("norm: {}\n", n);
|
||||
}
|
||||
12
examples/12-meta.sx
Normal file
12
examples/12-meta.sx
Normal file
@@ -0,0 +1,12 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math.sx";
|
||||
|
||||
main :: () {
|
||||
x:Type = f64;
|
||||
v:f64 = 3.2;
|
||||
print("{}\n", x);
|
||||
print("{}\n", v);
|
||||
|
||||
x= Vec4;
|
||||
print("{}\n", x);
|
||||
}
|
||||
9
examples/13-code.sx
Normal file
9
examples/13-code.sx
Normal file
@@ -0,0 +1,9 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
generate::() -> string {
|
||||
return "print(\"hello from the other side\n\");";
|
||||
}
|
||||
|
||||
main :: () {
|
||||
#insert #run generate();
|
||||
}
|
||||
15
examples/14-demo.sx
Normal file
15
examples/14-demo.sx
Normal file
@@ -0,0 +1,15 @@
|
||||
std :: #import "modules/std.sx";
|
||||
|
||||
vec3 :: (x:f32, y:f32, z:f32) -> std.Vector(3, f32) {
|
||||
.[x,y,z];
|
||||
}
|
||||
|
||||
main :: () {
|
||||
v1 := vec3(1,0,0);
|
||||
v2 := vec3(0,0,1);
|
||||
s := 0.5;
|
||||
|
||||
sum := (v1 - v2);// math.cross(v1, v2);
|
||||
|
||||
std.print("{}\n", sum);
|
||||
}
|
||||
50
examples/15-while.sx
Normal file
50
examples/15-while.sx
Normal file
@@ -0,0 +1,50 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
sumOf10 :: () -> s32 {
|
||||
i:= 1;
|
||||
s:=0;
|
||||
while i <= 10 {
|
||||
s+=i;
|
||||
i+=1;
|
||||
}
|
||||
s;
|
||||
}
|
||||
|
||||
someSum :: #run sumOf10();
|
||||
|
||||
main :: {
|
||||
// Basic while loop: count to 5
|
||||
i := 0;
|
||||
while i < 5 {
|
||||
i += 1;
|
||||
}
|
||||
print("count: {}\n", i);
|
||||
|
||||
// While with break
|
||||
x := 1;
|
||||
while x < 100 {
|
||||
if x == 12 {
|
||||
break;
|
||||
}
|
||||
x += 1;
|
||||
}
|
||||
print("break at: {}\n", x);
|
||||
|
||||
// While with continue: sum odd numbers 1-9
|
||||
sum := 0;
|
||||
j := 0;
|
||||
while j < 10 {
|
||||
j += 1;
|
||||
// Skip even numbers
|
||||
if j == 2 { continue; }
|
||||
if j == 4 { continue; }
|
||||
if j == 6 { continue; }
|
||||
if j == 8 { continue; }
|
||||
if j == 10 { continue; }
|
||||
sum += j;
|
||||
}
|
||||
print("sum of odd 1-9: {}\n", sum);
|
||||
|
||||
print("sum {}", someSum);
|
||||
|
||||
}
|
||||
48
examples/16-union.sx
Normal file
48
examples/16-union.sx
Normal file
@@ -0,0 +1,48 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Shape :: union {
|
||||
circle: f32;
|
||||
rect: s32;
|
||||
none;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
// Construction with .variant(payload)
|
||||
s :Shape = .circle(3.14);
|
||||
print("circle: {}\n", s);
|
||||
|
||||
// Payload access
|
||||
r := s.circle;
|
||||
print("radius: {}\n", r);
|
||||
|
||||
// Void variant via enum literal
|
||||
s = .none;
|
||||
print("none: {}\n", s);
|
||||
|
||||
// Reassign with payload
|
||||
s = .rect(42);
|
||||
print("rect: {}\n", s);
|
||||
|
||||
// Explicit prefix construction
|
||||
sh :Shape = Shape.circle(2.71);
|
||||
print("sh: {}\n", sh);
|
||||
|
||||
// Field access on second union variable
|
||||
sh2 :Shape = .rect(10);
|
||||
val := sh2.rect;
|
||||
print("rect val: {}\n", val);
|
||||
|
||||
// Match on union
|
||||
if sh2 == {
|
||||
case .circle: print("matched circle\n");
|
||||
case .rect: print("matched rect\n");
|
||||
case .none: print("matched none\n");
|
||||
}
|
||||
|
||||
cs := if sh2 == {
|
||||
case .circle: 1;
|
||||
case .rect: 2;
|
||||
case .none: 3;
|
||||
}
|
||||
print("case : {}", cs);
|
||||
}
|
||||
9
examples/17-lambda.sx
Normal file
9
examples/17-lambda.sx
Normal file
@@ -0,0 +1,9 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: () {
|
||||
fx :: (s:s3) -> s3 {
|
||||
s;
|
||||
}
|
||||
|
||||
print("{}\n", fx(133));
|
||||
}
|
||||
23
examples/18-conditions.sx
Normal file
23
examples/18-conditions.sx
Normal file
@@ -0,0 +1,23 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: () {
|
||||
x:= 32;
|
||||
y:= 40;
|
||||
|
||||
if 0 <= x <= 100 and 0 <= y <= 100 {
|
||||
print("contained");
|
||||
}
|
||||
|
||||
if 0 <= x <= 100 and 0 <= y <= 100 {
|
||||
print("contained");
|
||||
}
|
||||
|
||||
|
||||
if 1000 > x > -100 and 0 <= y <= 100 {
|
||||
print("contained");
|
||||
}
|
||||
|
||||
if 1000 > x >= -100 and 0 <= y <= 100 {
|
||||
print("contained");
|
||||
}
|
||||
}
|
||||
35
examples/19-varargs.sx
Normal file
35
examples/19-varargs.sx
Normal file
@@ -0,0 +1,35 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
sum :: (args: ..s32) -> s32 {
|
||||
result := 0;
|
||||
for args {
|
||||
result = result + it;
|
||||
}
|
||||
result;
|
||||
}
|
||||
|
||||
print_all :: (args: ..s32) {
|
||||
for args {
|
||||
write(int_to_string(it));
|
||||
write(" ");
|
||||
}
|
||||
write("\n");
|
||||
}
|
||||
|
||||
main :: () -> s32 {
|
||||
write(int_to_string(sum(10, 20, 30)));
|
||||
write("\n");
|
||||
|
||||
print_all(1, 2, 3, 4, 5);
|
||||
|
||||
arr : [3]s32 = .[10, 20, 30];
|
||||
write(int_to_string(sum(..arr)));
|
||||
write("\n");
|
||||
|
||||
for arr {
|
||||
write(int_to_string(it));
|
||||
write(" ");
|
||||
}
|
||||
write("\n");
|
||||
0;
|
||||
}
|
||||
47
examples/20-any-varargs.sx
Normal file
47
examples/20-any-varargs.sx
Normal file
@@ -0,0 +1,47 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Point :: struct {
|
||||
x: s32;
|
||||
y: s32;
|
||||
}
|
||||
|
||||
// Print all arguments — accepts any type, dispatches via type-switch
|
||||
print_any :: (args: ..Any) {
|
||||
for args {
|
||||
type := type_of(it);
|
||||
if type == {
|
||||
case int: write(int_to_string(cast(s32) it));
|
||||
case string: write(cast(string) it);
|
||||
case bool: write(bool_to_string(cast(bool) it));
|
||||
case float: write(float_to_string(cast(f64) it));
|
||||
case Point: {
|
||||
p := cast(Point) it;
|
||||
write("(");
|
||||
write(int_to_string(p.x));
|
||||
write(",");
|
||||
write(int_to_string(p.y));
|
||||
write(")");
|
||||
}
|
||||
}
|
||||
write(" ");
|
||||
}
|
||||
write("\n");
|
||||
}
|
||||
|
||||
count :: (args: ..Any) -> s32 {
|
||||
args.len;
|
||||
}
|
||||
|
||||
main :: () -> s32 {
|
||||
print_any(42, "hello", true, 3.14);
|
||||
|
||||
// Test with struct
|
||||
p := Point.{ x=10, y=20 };
|
||||
print_any("point:", p, 99);
|
||||
|
||||
// Test count
|
||||
write(int_to_string(count(1, 2, 3)));
|
||||
write("\n");
|
||||
|
||||
0;
|
||||
}
|
||||
19
examples/21-categories.sx
Normal file
19
examples/21-categories.sx
Normal file
@@ -0,0 +1,19 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
Point :: struct {
|
||||
x, y: s32;
|
||||
}
|
||||
|
||||
Color :: struct {
|
||||
r, g, b: s32;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
p := Point.{10, 20};
|
||||
c := Color.{255, 128, 0};
|
||||
print("p: {}\n", p);
|
||||
print("c: {}\n", c);
|
||||
print("n: {}\n", 42);
|
||||
print("s: {}\n", "hello");
|
||||
print("b: {}\n", true);
|
||||
}
|
||||
11
examples/22-anytype.sx
Normal file
11
examples/22-anytype.sx
Normal file
@@ -0,0 +1,11 @@
|
||||
#import "modules/std.sx";
|
||||
|
||||
main :: {
|
||||
i := 0;
|
||||
while i < 10 {
|
||||
i+=1;
|
||||
if i == 2 then continue;
|
||||
if i == 5 then break;
|
||||
}
|
||||
print("{}\n", i);
|
||||
}
|
||||
17
examples/modules/math.sx
Normal file
17
examples/modules/math.sx
Normal file
@@ -0,0 +1,17 @@
|
||||
#import "std.sx";
|
||||
|
||||
dot :: (a: Vector(3,f32), b: Vector(3,f32)) -> f32 {
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
cross :: (a: Vector(3,f32), b: Vector(3,f32)) -> Vector(3,f32) {
|
||||
.[a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x];
|
||||
}
|
||||
|
||||
length :: (v: Vector(3,f32)) -> f32 {
|
||||
return sqrt(dot(v, v));
|
||||
}
|
||||
|
||||
normalize :: (v: Vector(3,f32)) -> Vector(3,f32) {
|
||||
return v / length(v);
|
||||
}
|
||||
220
examples/modules/std.sx
Normal file
220
examples/modules/std.sx
Normal file
@@ -0,0 +1,220 @@
|
||||
Vector :: ($N: int, $T: Type) -> Type #builtin;
|
||||
write :: (str: string) -> void #builtin;
|
||||
sqrt :: (x: $T) -> T #builtin;
|
||||
size_of :: ($T: Type) -> s32 #builtin;
|
||||
alloc :: (size: s32) -> string #builtin;
|
||||
type_of :: (val: $T) -> Type #builtin;
|
||||
type_name :: ($T: Type) -> string #builtin;
|
||||
field_count :: ($T: Type) -> s32 #builtin;
|
||||
field_name :: ($T: Type, idx: s32) -> string #builtin;
|
||||
field_value :: (s: $T, idx: s32) -> Any #builtin;
|
||||
|
||||
int_to_string :: (n: s32) -> string {
|
||||
if n == 0 { return "0"; }
|
||||
neg := n < 0;
|
||||
v := if neg then 0 - n else n;
|
||||
tmp := v;
|
||||
len := 0;
|
||||
while tmp > 0 { len += 1; tmp = tmp / 10; }
|
||||
total := if neg then len + 1 else len;
|
||||
buf := alloc(total);
|
||||
i := total - 1;
|
||||
while v > 0 {
|
||||
buf[i] = (v % 10) + 48;
|
||||
v = v / 10;
|
||||
i -= 1;
|
||||
}
|
||||
if neg { buf[0] = 45; }
|
||||
buf;
|
||||
}
|
||||
|
||||
bool_to_string :: (b: bool) -> string {
|
||||
if b then "true" else "false";
|
||||
}
|
||||
|
||||
float_to_string :: (f: f64) -> string {
|
||||
neg := f < 0.0;
|
||||
v := if neg then 0.0 - f else f;
|
||||
int_part := cast(s32) v;
|
||||
frac := cast(s32) ((v - cast(f64) int_part) * 1000000.0);
|
||||
if frac < 0 { frac = 0 - frac; }
|
||||
istr := int_to_string(int_part);
|
||||
fstr := int_to_string(frac);
|
||||
il := istr.len;
|
||||
fl := fstr.len;
|
||||
prefix := if neg then 1 else 0;
|
||||
total := prefix + il + 1 + 6;
|
||||
buf := alloc(total);
|
||||
pos := 0;
|
||||
if neg { buf[0] = 45; pos = 1; }
|
||||
i := 0;
|
||||
while i < il { buf[pos] = istr[i]; pos += 1; i += 1; }
|
||||
buf[pos] = 46;
|
||||
pos += 1;
|
||||
pad := 6 - fl;
|
||||
j := 0;
|
||||
while j < pad { buf[pos] = 48; pos += 1; j += 1; }
|
||||
k := 0;
|
||||
while k < fl { buf[pos] = fstr[k]; pos += 1; k += 1; }
|
||||
buf;
|
||||
}
|
||||
|
||||
concat :: (a: string, b: string) -> string {
|
||||
al := a.len;
|
||||
bl := b.len;
|
||||
buf := alloc(al + bl);
|
||||
i := 0;
|
||||
while i < al { buf[i] = a[i]; i += 1; }
|
||||
j := 0;
|
||||
while j < bl { buf[al + j] = b[j]; j += 1; }
|
||||
buf;
|
||||
}
|
||||
|
||||
substr :: (s: string, start: s32, len: s32) -> string {
|
||||
buf := alloc(len);
|
||||
i := 0;
|
||||
while i < len {
|
||||
buf[i] = s[start + i];
|
||||
i += 1;
|
||||
}
|
||||
buf;
|
||||
}
|
||||
|
||||
struct_to_string :: (s: $T) -> string {
|
||||
result := concat(type_name(T), "{");
|
||||
i := 0;
|
||||
while i < field_count(T) {
|
||||
if i > 0 { result = concat(result, ", "); }
|
||||
result = concat(result, field_name(T, i));
|
||||
result = concat(result, ": ");
|
||||
result = concat(result, any_to_string(field_value(s, i)));
|
||||
i += 1;
|
||||
}
|
||||
concat(result, "}");
|
||||
}
|
||||
|
||||
enum_to_string :: (e: $T) -> string {
|
||||
concat(".", field_name(T, cast(s32) e));
|
||||
}
|
||||
|
||||
vector_to_string :: (v: $T) -> string {
|
||||
result := "[";
|
||||
i := 0;
|
||||
while i < field_count(T) {
|
||||
if i > 0 { result = concat(result, ", "); }
|
||||
result = concat(result, any_to_string(field_value(v, i)));
|
||||
i += 1;
|
||||
}
|
||||
concat(result, "]");
|
||||
}
|
||||
|
||||
array_to_string :: (a: $T) -> string {
|
||||
result := "[";
|
||||
i := 0;
|
||||
while i < field_count(T) {
|
||||
if i > 0 { result = concat(result, ", "); }
|
||||
result = concat(result, any_to_string(field_value(a, i)));
|
||||
i += 1;
|
||||
}
|
||||
concat(result, "]");
|
||||
}
|
||||
|
||||
union_to_string :: (u: $T) -> string {
|
||||
tag := cast(s32) u;
|
||||
result := concat(".", field_name(T, tag));
|
||||
payload := field_value(u, tag);
|
||||
pstr := any_to_string(payload);
|
||||
if pstr.len > 0 {
|
||||
result = concat(result, concat("(", concat(pstr, ")")));
|
||||
}
|
||||
result;
|
||||
}
|
||||
|
||||
any_to_string :: (val: Any) -> string {
|
||||
result := "<?>";
|
||||
type := type_of(val);
|
||||
if type == {
|
||||
case void: result = "";
|
||||
case int: result = int_to_string(xx val);
|
||||
case string: { s : string = xx val; result = s; }
|
||||
case bool: result = bool_to_string(xx val);
|
||||
case float: result = float_to_string(xx val);
|
||||
case struct: result = struct_to_string(cast(type) val);
|
||||
case enum: result = enum_to_string(cast(type) val);
|
||||
case vector: result = vector_to_string(cast(type) val);
|
||||
case array: result = array_to_string(cast(type) val);
|
||||
case union: result = union_to_string(cast(type) val);
|
||||
}
|
||||
result;
|
||||
}
|
||||
|
||||
build_print :: (fmt: string) -> string {
|
||||
code := "result := \"\"; ";
|
||||
seg_start := 0;
|
||||
i := 0;
|
||||
arg_idx := 0;
|
||||
while i < fmt.len {
|
||||
if fmt[i] == 123 {
|
||||
if i + 1 < fmt.len {
|
||||
if fmt[i + 1] == 125 {
|
||||
if i > seg_start {
|
||||
code = concat(code, "result = concat(result, substr(fmt, ");
|
||||
code = concat(code, int_to_string(seg_start));
|
||||
code = concat(code, ", ");
|
||||
code = concat(code, int_to_string(i - seg_start));
|
||||
code = concat(code, ")); ");
|
||||
}
|
||||
code = concat(code, "result = concat(result, any_to_string(args[");
|
||||
code = concat(code, int_to_string(arg_idx));
|
||||
code = concat(code, "])); ");
|
||||
arg_idx += 1;
|
||||
i += 2;
|
||||
seg_start = i;
|
||||
} else if fmt[i + 1] == 123 {
|
||||
code = concat(code, "result = concat(result, substr(fmt, ");
|
||||
code = concat(code, int_to_string(seg_start));
|
||||
code = concat(code, ", ");
|
||||
code = concat(code, int_to_string(i - seg_start + 1));
|
||||
code = concat(code, ")); ");
|
||||
i += 2;
|
||||
seg_start = i;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
} else if fmt[i] == 125 {
|
||||
if i + 1 < fmt.len {
|
||||
if fmt[i + 1] == 125 {
|
||||
code = concat(code, "result = concat(result, substr(fmt, ");
|
||||
code = concat(code, int_to_string(seg_start));
|
||||
code = concat(code, ", ");
|
||||
code = concat(code, int_to_string(i - seg_start + 1));
|
||||
code = concat(code, ")); ");
|
||||
i += 2;
|
||||
seg_start = i;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
if seg_start < fmt.len {
|
||||
code = concat(code, "result = concat(result, substr(fmt, ");
|
||||
code = concat(code, int_to_string(seg_start));
|
||||
code = concat(code, ", ");
|
||||
code = concat(code, int_to_string(fmt.len - seg_start));
|
||||
code = concat(code, ")); ");
|
||||
}
|
||||
code = concat(code, "write(result);");
|
||||
code;
|
||||
}
|
||||
|
||||
print :: ($fmt: string, args: ..Any) {
|
||||
#insert build_print(fmt);
|
||||
}
|
||||
98
examples/vision.sx
Normal file
98
examples/vision.sx
Normal file
@@ -0,0 +1,98 @@
|
||||
main :: {
|
||||
// imagine a game loop
|
||||
while(running) {
|
||||
render_ui(build_menu);
|
||||
}
|
||||
}
|
||||
|
||||
build_menu :: (ctx: ViewContext) -> View {
|
||||
// use ctx to allocate some state at the for Menu ViewContext
|
||||
state : MenuState = ctx.state(MenuState);
|
||||
|
||||
// named args
|
||||
HStack(ctx,
|
||||
children = .[
|
||||
Button(ctx,
|
||||
label = "Up",
|
||||
onTap = ctx.callback(goUp, state),
|
||||
),
|
||||
ScrollView(ctx,
|
||||
LazyVStack(ctx,
|
||||
builder = ctx.callback(build_menu_entry, state),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
build_menu_entry :: (ctx: *ViewContext, index: s32, state: *MenuState) -> View {
|
||||
entry := state.entries[index];
|
||||
is_selected := index == state.selected_index;
|
||||
icon := if entry.is_dir then "[D]" else " ";
|
||||
Button(ctx,
|
||||
label = concat(icon, " ", entry.name),
|
||||
on_tap = ctx.callback(menu_go, state, index),
|
||||
);
|
||||
}
|
||||
|
||||
ViewContext :: struct {
|
||||
//TBD
|
||||
}
|
||||
|
||||
MenuState :: struct {
|
||||
current_path: string;
|
||||
entries: List(MenuEntry);
|
||||
error_message: string;
|
||||
}
|
||||
|
||||
MenuEntry :: struct {
|
||||
name: string;
|
||||
is_dir: bool;
|
||||
}
|
||||
|
||||
menu_go_up :: (state: *MenuState) {
|
||||
parent := fs.path.dirname(state.current_path) else return;
|
||||
// this frees the current path & copies parent to be owned by MenuState
|
||||
state.current_path = parent;
|
||||
menu_refresh(state);
|
||||
}
|
||||
|
||||
menu_go :: (state: *MenuState, s32 index) {
|
||||
entry := state.entries[index] else return;
|
||||
state.current_path := concat(state.current_path, "/", entry.name);
|
||||
menu_refresh(state);
|
||||
}
|
||||
|
||||
menu_refresh :: (state: *MenuState) {
|
||||
// this could retain the capacity
|
||||
state.entries.clear();
|
||||
// this would basically create a copy of the empty string :(
|
||||
state.error_message = "";
|
||||
|
||||
// ... multi return params vs Generic Result to deal with exceptions
|
||||
// ... nullable
|
||||
dir := io.Dir.open(state.current_path);
|
||||
if !dir {
|
||||
state.error_message = "failed to open";
|
||||
return;
|
||||
};
|
||||
defer dir.close();
|
||||
|
||||
for iter.iterate() {
|
||||
entries.append(.{it.name, it.kind == .Directory});
|
||||
}
|
||||
}
|
||||
|
||||
HStackState :: struct {
|
||||
spacing: f32 = 8;
|
||||
alignment: VerticalAlignment = .center;
|
||||
padding: f32 = 0;
|
||||
background: ?Color;
|
||||
corner_radius: f32 = 0,
|
||||
}
|
||||
|
||||
HStack :: (ctx: ViewContext, children: []View) -> View {
|
||||
data := ctx.alloc(HStackState);
|
||||
data.* = .{};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user