The cursor now costs nothing for a byte inside an escape sequence and one cell fewer for a plain glyph: the grid is the truth, so the old cursor cell is repainted after the byte, and not at all when a glyph has just been drawn over it. __fortify_panic says "r8169: rtl_open.cold+0x..." through ldlsd's module list, so a photograph of the screen is enough, and exits instead of spinning on a core and holding /dev/netdev. docs/plan/finch.md: only integrating Finch is later; finishing it is not. The self-hosting gap measured against Finch's own bootstrap test. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015f73FesGZGYPkmDvUcj6QX
4.8 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
-O2pipeline 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"pluslink "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 insrc/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 insrc/, language server included) that builds itself to a byte-identical result —tests/boot.sh.
What SchOS would need to do
- A
schostarget.finchpicks 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 existingx86_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. - 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.
boot/as the SchOS-hosted compiler. The C++ compiler needs LLVM's C++ libraries; the one inboot/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.- Bindings for SchOS's own interfaces (
/dev/pci,/dev/netdev, schinit's job protocol, the framebuffer) — generated by the C importer from the headers ininclude/uapi/, so they are not hand-written and cannot drift from the kernel.
The self-hosting gap
"Rewrite it in Finch itself" is mostly done: boot/ compiles itself. What it
does not yet do is stated by its own test, tests/boot.sh, which skips
every test that uses a feature boot/ lacks. Counting mentions in the two
sources confirms it (boot/ vs src/):
| Feature | boot/ |
src/ |
Needed for |
|---|---|---|---|
| maps | 0 | 185 | codegen_map.cpp (242 lines) to port |
errors as values (or, try) |
few | hundreds | most real programs |
| methods on user types | 17 | 87 | partial |
defer |
2 | 31 | partial |
sized numbers (u8..u64, i8..i32, f32, f64) |
none | throughout | kernel-facing code |
| enums | 0 | 14 | |
C import (import "x.h", link) |
none | cimport.cpp, 373 lines on libclang |
the way into every C library, SchOS's included |
| target and ABI layer (AArch64, macOS, Windows) | 0 | target.cpp, abi.cpp |
non-Linux-x86 targets |
| language server | 0 | lsp.cpp, 580 lines |
editors |
So "finishing" has a concrete order: errors as values and maps first (they
are what the rest uses), then sized numbers and defer, then C import — which
needs libclang bindings, so it needs C import's own simpler form first — and
the target layer last. tests/boot.sh is the measure: the list of skipped
tests shrinks to nothing.
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.