Bootstrap: the Finch compiler written in Finch

boot/ is a second Finch compiler written in Finch (lexer, parser, type checker and
an LLVM IR text generator, ~3k lines). Built by the C++ compiler it compiles itself;
stage 2 and stage 3 produce byte-identical IR. It covers the core language: functions,
structs, arrays, str, pointers, loops and modules (no C imports, sized numbers or defer),
copies values like the main compiler and leaves freeing memory to the operating system.

tests/boot.sh checks the fixpoint and runs the test programs it supports.
Also: shell(cmd) built-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-10-08 19:07:49 +02:00
commit c7ddd4d8b6
8 changed files with 3153 additions and 1 deletions

94
boot/ast.fn Normal file
View file

@ -0,0 +1,94 @@
// The syntax tree of the self-hosted compiler.
// A type as written or resolved.
// kind: "void" "int" "bool" "char" "float" "str" "null" "ptr" "array" "named" "struct"
// elem: the element of an array or the target of a ptr (zero or one entry)
// name, module: structs ("" module = the main file)
struct Type {
str kind
[]Type elem
str name
str module
}
fn simple(str kind) -> Type {
return Type(kind: kind)
}
fn arrayOf(Type t) -> Type {
out := Type(kind: "array")
out.elem.push(t)
return out
}
fn ptrTo(Type t) -> Type {
out := Type(kind: "ptr")
out.elem.push(t)
return out
}
fn same(Type a, Type b) -> bool {
if a.kind != b.kind {
return false
}
if a.kind == "struct" || a.kind == "named" {
return a.name == b.name && a.module == b.module
}
if a.kind == "array" || a.kind == "ptr" {
if a.elem.len != b.elem.len {
return false
}
if a.elem.len == 0 {
return true
}
return same(a.elem[0], b.elem[0])
}
return true
}
fn show(Type t) -> str {
if t.kind == "array" {
return "[]" + show(t.elem[0])
}
if t.kind == "ptr" {
if t.elem.len == 0 {
return "ptr"
}
return "ptr[" + show(t.elem[0]) + "]"
}
if t.kind == "struct" || t.kind == "named" {
if t.module.len > 0 {
return t.module + "." + t.name
}
return t.name
}
if t.kind == "void" {
return "nothing"
}
return t.kind
}
// One node of the tree, for expressions, statements, functions and structs alike.
// expressions: int float str char bool null var unary binary call member index array method
// statements: decl assign expr if while for each return break continue block
// top level: fn param struct field
struct Node {
str kind
str name // identifier, operator, callee, field or method name
str text // literal text
Type ty // declared type (decl, param, field, fn result)
bool flag // decl: has a type; fn: has a body
[]Node kids
[]str names // named arguments: Point(x: 1)
int line
int col
int file
}
struct Program {
str module
str path
[]str imports // Finch modules
[]Node structs
[]Node fns
}