Finch 1.0.0

A small, fast programming language on LLVM with C-like syntax.

- Lexer, recursive-descent parser, single-pass type checker + LLVM IR codegen, O2 pipeline
- Types: int/float/bool/char/str, sized i8..u64/f32/f64, pointers ptr[T] with addr()/.value/null
- Functions (fn ... -> T), if/else, while, for..in, break/continue, Go-style operator precedence
- Implicit conversions only when lossless; literals adapt to their target type
- Runtime checks for division by zero, MIN/-1 and null .value
- C interop: import "header.h" via libclang, link "lib" with pkg-config, link-error advice
- Human-readable errors with source excerpts
- Test suite (34 tests), examples, docs for beginners/technicians/engineers in English and Polish

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-10-08 17:10:45 +02:00
commit 0591cd20f3
73 changed files with 8066 additions and 0 deletions

View file

@ -0,0 +1,3 @@
// expect: write just the library's name
link "libm.so"
fn main() {}

View file

@ -0,0 +1,4 @@
// expect: for true/false use '&&'
fn main() {
print(true & false)
}

View file

@ -0,0 +1,5 @@
// expect: a condition must be bool
fn main() {
if 1 {
}
}

View file

@ -0,0 +1,4 @@
// expect: division by zero
fn main() {
print(1 / 0)
}

View file

@ -0,0 +1,5 @@
// expect: 4: runtime error: division by zero
fn main() {
zero := 0
print(10 / zero)
}

View file

@ -0,0 +1,5 @@
// expect: cuts off the fraction
fn main() {
float f = 2.5
int n = f
}

View file

@ -0,0 +1,4 @@
// expect: import "math.h"
fn main() {
print(sqrt(2))
}

5
tests/fail/lib_hint.fn Normal file
View file

@ -0,0 +1,5 @@
// expect: link "lib_hint"
import "lib_hint.h"
fn main() {
print(finch_test_missing(1))
}

1
tests/fail/lib_hint.h Normal file
View file

@ -0,0 +1 @@
int finch_test_missing(int x);

View file

@ -0,0 +1,4 @@
// expect: doesn't fit in u8
fn main() {
u8 b = 300
}

View file

@ -0,0 +1,6 @@
// expect: can't be changed
fn main() {
for i in 0..3 {
i = 5
}
}

View file

@ -0,0 +1,3 @@
// expect: can't find the C header
import "nope_not_here.h"
fn main() {}

View file

@ -0,0 +1,3 @@
// expect: the library 'definitely_not_a_lib' wasn't found
link "definitely_not_a_lib"
fn main() {}

View file

@ -0,0 +1,5 @@
// expect: can reach its end without returning int
fn f() -> int {
print(1)
}
fn main() {}

View file

@ -0,0 +1,6 @@
// expect: can't use '+' on i32 and u32
fn main() {
i32 a = 1
u32 b = 2
print(a + b)
}

2
tests/fail/no_main.fn Normal file
View file

@ -0,0 +1,2 @@
// expect: there is no main function
fn helper() {}

View file

@ -0,0 +1,4 @@
// expect: unexpected character 'ż' (names use only
fn main() {
żółw := 1
}

5
tests/fail/null_value.fn Normal file
View file

@ -0,0 +1,5 @@
// expect: 4: runtime error: used .value on a null pointer
fn main() {
ptr[int] p = null
print(p.value)
}

View file

@ -0,0 +1,4 @@
// expect: functions start with 'fn'
int add(int a) {
return a
}

5
tests/fail/redeclare.fn Normal file
View file

@ -0,0 +1,5 @@
// expect: already exists
fn main() {
x := 1
x := 2
}

View file

@ -0,0 +1,4 @@
// expect: put each statement on its own line
fn main() {
x := 1 print(x)
}

View file

@ -0,0 +1,4 @@
// expect: 'x' must be int, but this is str
fn main() {
int x = "hi"
}

View file

@ -0,0 +1,3 @@
// expect: never closed
fn main() {
print(1)

View file

@ -0,0 +1,4 @@
// expect: there is no variable named 'y'
fn main() {
print(y)
}

View file

@ -0,0 +1,5 @@
// expect: this code can never run
fn main() {
return
print(1)
}

View file

@ -0,0 +1,4 @@
// expect: null needs a type
fn main() {
p := null
}

View file

@ -0,0 +1,6 @@
// expect: this ptr has no type
import "stdlib.h"
fn main() {
p := malloc(8)
print(p.value)
}