Finch/src/host.fch
Nexoniarz d428498efd 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
2026-10-29 11:17:10 +01:00

98 lines
2.3 KiB
Text

// What differs between the systems the compiler itself runs on: how a command line is quoted and run,
// where temporary files go, making and removing files. This one is for Linux and macOS (name_windows.fch has
// the Windows one).
import "stdlib.h"
import "unistd.h"
import "clang-c/Index.h"
// libclang's description of a file that isn't on disk: its Length is C's `unsigned long`, which is 64 bits here
fn unsavedFile(str name, str contents) -> CXUnsavedFile {
return CXUnsavedFile(Filename: name.ptr, Contents: contents.ptr, Length: u64(contents.len))
}
fn quote(str a) -> str {
return "'" + a.replace("'", "'\\''") + "'"
}
// run a command line through the shell; its exit code
fn run(str cmd) -> int {
return shell(cmd)
}
fn nullDevice() -> str {
return "/dev/null"
}
// the folder for temporary files
fn tempDir() -> str {
t := getenv("TMPDIR")
if t.len > 0 {
if t.ends_with("/") {
return t.sub(0, t.len - 1)
}
return t
}
return "/tmp"
}
fn pathSeparator() -> str {
return ":"
}
fn pid() -> int {
return int(getpid())
}
// the folder the compiler was started in
fn cwd() -> str {
return getenv("PWD")
}
// where files that are made once and kept go
fn cacheDir() -> str {
x := getenv("XDG_CACHE_HOME")
if x.len > 0 {
return x + "/finch"
}
h := getenv("HOME")
if h.len > 0 {
return h + "/.cache/finch"
}
return tempDir() + "/finch-cache"
}
// the editor protocol is bytes, not text lines
fn binaryStdio() {
}
fn makeDirs(str path) {
shell("mkdir -p " + quote(path))
}
fn remove(str path) {
delete_file(path)
}
fn removeTree(str path) {
shell("rm -rf " + quote(path))
}
// move a file over another
fn move(str from, str to) {
shell("mv " + quote(from) + " " + quote(to))
}
// the files under dir (and its folders) whose names end with ext, like ".fch"
fn listFiles(str dir, str ext) -> []str {
tmp := tempDir() + "/finch_files_" + str(pid()) + ".txt"
run("find " + quote(dir) + " -type f -name " + quote("*" + ext) + " > " + quote(tmp) + " 2> " + nullDevice())
text := read_file(tmp) or ""
remove(tmp)
[]str out
for line in text.replace("\r", "").split("\n") {
if line.ends_with(ext) {
out.push(line)
}
}
return out
}