finch.toml, threads and atomics, finch fmt, C++ files, struct #defines, a struct variable given for its ptr

- finch.toml: name, entry, paths, include, links, libdirs, cflags, ldflags, and [target.windows] etc.;
  finch run / build / test with no file use its entry
- import thread: spawn, join, mutex, cpus; atomic_add/sub/load/store/swap/cas built in
- finch fmt [--check]: indentation by { }, trailing spaces, empty lines; also as LSP formatting
- link "x.cpp" (or in finch.toml): built with the C++ compiler, which then links (FINCH_CXX)
- #define RAYWHITE (Color){ 245, 245, 245, 255 } imports as a Color
- push(body) where push takes ptr[Body]: the same as push(addr(body))
- --target android (NDK clang from ANDROID_NDK_HOME, -llog)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016GzNP6r8dg6WDxUVZy8wjL
This commit is contained in:
Nexoniarz 2026-10-29 11:17:10 +01:00
commit d428498efd
40 changed files with 1398 additions and 18 deletions

23
tests/new/auto_addr.fch Normal file
View file

@ -0,0 +1,23 @@
struct Body {
float x
float y
}
fn push(ptr[Body] b, float dx) {
b.x += dx
}
fn Body.moved(float dx) -> Body {
return Body(x: self.x + dx, y: self.y)
}
fn main() {
b := Body(x: 1.0, y: 2.0)
push(b, 0.5) // the same as push(addr(b), 0.5)
push(addr(b), 0.5)
print(b.x)
p := addr(b)
push(p, 1.0) // already a ptr: as it is
print(b.x)
print(b.moved(1.0).x)
}

3
tests/new/auto_addr.out Normal file
View file

@ -0,0 +1,3 @@
2
3
4

View file

@ -24,4 +24,6 @@ fn main() {
t.as.f = 0.5
print(t.as.f)
print(abs(-2.5), abs(-3), min(EV_KEY, 7)) // Finch's abs, not C's int-only one
bg := RAYWHITE // #define RAYWHITE (Color){ 245, 245, 245, 255 }
print(bg.r, bg.a, DARK.g, DARK.a, HALF_UP.x, HALF_UP.y)
}

View file

@ -5,3 +5,4 @@ true 32
32 2
0.5
2.5 3 7
245 255 20 0 0.5 -1

View file

@ -22,6 +22,14 @@ typedef struct { int kind; union { int i; float f; } as; } Tagged;
#define LONG_NAME "a" "b"
#define NOT_A_CONSTANT do { } while (0)
typedef struct { unsigned char r, g, b, a; } Color;
typedef struct { float x, y; } Vec2;
#define CLITERAL(type) (type)
#define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 }
#define DARK (Color){ 20, 20, 20 }
#define HALF_UP (Vec2){ 0.5f, -1 }
#define NOT_A_STRUCT_CONST (Color){ 1, 2, (unsigned char)(long)&poll_event, 4 }
static inline int fill_key(Event *e, int key) {
e->key.type = EV_KEY;
e->key.key = key;

View file

@ -0,0 +1,13 @@
// expect: argument 'b' must be ptr[Body], but this is Body
struct Body {
float x
}
fn push(ptr[Body] b) {
b.x += 1.0
}
fn make() -> Body {
return Body(x: 1.0)
}
fn main() {
push(make())
}

View file

@ -0,0 +1,21 @@
// "\(x)" in text
struct P {
int x
float y
}
fn main() {
name := "Ada"
hp := 7
p := P(x: 3, y: 0.25)
print("hi \(name), hp \(hp), next \(hp + 1)")
print("p = (\(p.x), \(p.y, 2)) \("nested \(name)")")
map[str]int m
m["k"] = 5
print("\(m["k"]) \(str(1.0 / 3.0, 3))")
print("no code here: \\(x) and \t tab")
long := """
speed \(p.y * 4.0)
"""
print(long)
}

View file

@ -0,0 +1,5 @@
hi Ada, hp 7, next 8
p = (3, 0.25) nested Ada
5 0.333
no code here: \(x) and tab
speed 1

55
tests/new/threads.fch Normal file
View file

@ -0,0 +1,55 @@
import thread
struct Shared {
[]int seen
}
struct Job {
ptr[int] counter
int adds
ptr[thread.Mutex] lock
ptr[Shared] common
int id
}
fn work(ptr arg) {
ptr[Job] job = arg
for i in 0..job.adds {
atomic_add(job.counter, 1)
}
job.lock.lock()
job.common.seen.push(job.id)
job.lock.unlock()
}
fn main() {
count := 0
m := thread.mutex()
defer m.close()
both := Shared()
[]Job jobs
for i in 0..4 {
jobs.push(Job(counter: addr(count), adds: 100000, lock: addr(m), common: addr(both), id: i))
}
[]thread.Thread ts
for i in 0..4 {
ts.push(thread.spawn(addr(work), addr(jobs[i])) or {
print("can't start")
exit(1)
})
}
for i in 0..4 {
ts[i].join()
}
print(atomic_load(addr(count)))
print(both.seen.len)
print(thread.cpus() > 0)
u32 flags = 5
print(atomic_swap(addr(flags), 9))
print(atomic_cas(addr(flags), 9, 1))
print(atomic_cas(addr(flags), 9, 2))
atomic_store(addr(flags), 7)
print(atomic_sub(addr(flags), 2))
print(flags)
}

8
tests/new/threads.out Normal file
View file

@ -0,0 +1,8 @@
400000
4
true
5
true
false
7
5