SchOS/docs/plan/finch.md
Nexoniarz afb2e084af docs: Finch's self-hosting gap, as it stands
Sized numbers, methods, defer, errors as values and maps are now in the
self-hosted compiler; C import is the one piece left.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015f73FesGZGYPkmDvUcj6QX
2026-10-25 18:55:31 +01:00

5.1 KiB

Finch, for SchOS's own programs

Two things, and only one of them is later.

  • Bringing Finch into SchOS (below) is later — behind 1.0.md's freeze like everything else here that is not named there.
  • Finishing Finch itself, and making it fully self-hosting, is work on the Finch repository and does not touch this tree. It can proceed now; see the gap.

Finch is the author's own language: https://pandor.pl/git/nexoniarz/Finch (GitHub mirror: Nexoniarz/Finch). The plan is to write SchOS's own applications and tools in it, in place of C, and so leave behind what C does badly: silent narrowing, signed/unsigned mixing, undefined behaviour on an out-of-range index, a forgotten free.

What it is today (version 2.4.0)

Measured from the repository, not from its README alone:

  • LLVM front end, C-like syntax, no semicolons, no headers, no preprocessor. It compiles through LLVM's -O2 pipeline to native code; there is no garbage collector.
  • Values, not references: lists, text and structs copy on assignment and are freed at the end of their block. Out-of-range indexes, division by zero and null pointers stop with a runtime error rather than undefined behaviour.
  • Errors as values (int(s) or 0, try read_file(p)), maps, methods, modules.
  • C interop through libclang: import "foo.h" plus link "foo" calls any C library, structs by value and callbacks included. That is the way in to everything SchOS already has — musl, the /dev/* interfaces, Alpine's libraries.
  • Targets: Linux, macOS, Windows, on x86-64 and ARM64 (src/target.cpp; the System V, AAPCS64 and Microsoft x64 ABIs are in src/abi.cpp).
  • Tooling: a language server (finch lsp), VS Code and Kate support, 74 tests.
  • Self-hosting: boot/ is a Finch compiler written in Finch (about 3,100 lines, against about 5,900 for the C++ one in src/, language server included) that builds itself to a byte-identical result — tests/boot.sh.

What SchOS would need to do

  1. A schos target. finch picks a triple, a C compiler and a linker per target. SchOS runs unmodified Alpine binaries and Alpine's musl (see alpine.md), so the first target is the existing x86_64-unknown-linux-musl, and a Finch program built on the host should run on SchOS before anything in Finch is made SchOS-specific. Test that before writing a line of target code.
  2. The compiler on SchOS. Needs LLVM 21 and libclang, both of which Alpine packages. That is a question of apk and memory, not of SchOS.
  3. boot/ as the SchOS-hosted compiler. The C++ compiler needs LLVM's C++ libraries; the one in boot/ is the candidate for being the compiler that ships in the image, once it emits through LLVM's C API or a smaller back end.
  4. Bindings for SchOS's own interfaces (/dev/pci, /dev/netdev, schinit's job protocol, the framebuffer) — generated by the C importer from the headers in include/uapi/, so they are not hand-written and cannot drift from the kernel.

The self-hosting gap

"Rewrite it in Finch itself" was mostly done before this was written: boot/ compiled itself. What it lacked is stated by its own test, tests/boot.sh, which skips every test using a feature boot/ does not have. Measured against that test, on the branch finish-finch of the Finch repository (kept in the author's checkout, Projects/Finch, as a branch on top of embed):

Feature boot/ Notes
sized numbers (i8..u64, f32), conversions done int and float stay the i64 and f64 defaults
methods (fn T.m), mutation analysis done
defer done
errors as values (-> T!, error, try, or) done including fn main() -> !
maps, for k, v in, for i, x in done
str(x) of any value done
C import (import "x.h", link, C structs by value) missing the one that matters for SchOS: libclang through Finch's own C import, then the System V struct ABI
target and ABI layer (AArch64, macOS, Windows) missing after C import
language server missing lsp.cpp, 580 lines

The self-hosted compiler passes 17 of 22 tests and compiles itself to byte-identical output; the five it skips all import C. C import is the next piece, and the last one before the C++ compiler is only a seed. It is a few thousand lines of Finch (cimport.cpp and abi.cpp are 740 in C++), done in two steps so each can be tested: functions, constants, globals and pointers first (cimport, c_pointers), struct layout and the calling convention second (c_structs).

The scratch files note.txt and notatka.txt in the repository are not Finch's and can go.

Rules

  • Inference, not an instruction: the kernel stays in C. Finch is for applications and tools; the user said "our apps or stuff like that".
  • No new capability starts until the register of unfinished work is empty; the SchOS half of this document is a plan, not an exception to that.