mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
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:
commit
0591cd20f3
73 changed files with 8066 additions and 0 deletions
23
examples/c_import.fn
Normal file
23
examples/c_import.fn
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Use any C library: import its header and call it.
|
||||
import "stdio.h"
|
||||
import "math.h"
|
||||
import "stdlib.h"
|
||||
import "string.h"
|
||||
|
||||
fn main() {
|
||||
printf("printf works: %d + %d = %d\n", 2, 3, 2 + 3)
|
||||
puts("so does puts")
|
||||
|
||||
print("sqrt(2) =", sqrt(2))
|
||||
print("pi from math.h:", M_PI)
|
||||
print("strlen(\"finch\") =", strlen("finch"))
|
||||
print("RAND_MAX =", RAND_MAX, "EOF =", EOF)
|
||||
|
||||
// memory from C: malloc gives a ptr, free gives it back
|
||||
ptr[i32] n = malloc(4)
|
||||
n.value = 7
|
||||
print("from the heap:", n.value)
|
||||
free(n)
|
||||
|
||||
fprintf(stderr, "this goes to stderr\n")
|
||||
}
|
||||
3
examples/hello.fn
Normal file
3
examples/hello.fn
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
print("Hello, Finch!")
|
||||
}
|
||||
18
examples/llvm.fn
Normal file
18
examples/llvm.fn
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Finch driving LLVM itself through the LLVM-C API: the first step toward
|
||||
// a compiler written in Finch. Builds a module with `answer() -> 42` and prints its IR.
|
||||
import "llvm-c/Core.h"
|
||||
link "LLVM"
|
||||
|
||||
fn main() {
|
||||
mod := LLVMModuleCreateWithName("from_finch")
|
||||
i64t := LLVMInt64Type()
|
||||
fnType := LLVMFunctionType(i64t, null, 0, 0)
|
||||
f := LLVMAddFunction(mod, "answer", fnType)
|
||||
entry := LLVMAppendBasicBlock(f, "entry")
|
||||
b := LLVMCreateBuilder()
|
||||
LLVMPositionBuilderAtEnd(b, entry)
|
||||
LLVMBuildRet(b, LLVMConstInt(i64t, 42, 0))
|
||||
LLVMDumpModule(mod)
|
||||
LLVMDisposeBuilder(b)
|
||||
LLVMDisposeModule(mod)
|
||||
}
|
||||
62
examples/tour.fn
Normal file
62
examples/tour.fn
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// A quick tour of Finch.
|
||||
|
||||
fn add(int a, int b) -> int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
fn fib(int n) -> int {
|
||||
if n < 2 {
|
||||
return n
|
||||
}
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
|
||||
fn isEven(int n) -> bool {
|
||||
return n % 2 == 0
|
||||
}
|
||||
|
||||
fn greet(str name) {
|
||||
if name == "Finch" {
|
||||
print("Hi, it's me!")
|
||||
} else {
|
||||
print("Hi,", name)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// two ways to make a variable
|
||||
int age = 10
|
||||
name := "Ola" // type is guessed: str
|
||||
pi := 3.14 // float
|
||||
letter := 'F' // char
|
||||
|
||||
print(name, "is", age, "years old")
|
||||
print("2 + 3 =", add(2, 3))
|
||||
print("pi * 2 =", pi * 2)
|
||||
print("first letter:", letter)
|
||||
print("10 is even?", isEven(10))
|
||||
|
||||
greet("Finch")
|
||||
greet(name)
|
||||
|
||||
// loops
|
||||
for i in 0..10 {
|
||||
if i == 3 {
|
||||
continue
|
||||
}
|
||||
if i == 7 {
|
||||
break
|
||||
}
|
||||
print("i =", i)
|
||||
}
|
||||
|
||||
count := 3
|
||||
while count > 0 {
|
||||
print("countdown", count)
|
||||
count -= 1
|
||||
}
|
||||
|
||||
print("fib(30) =", fib(30))
|
||||
print("7 / 2 =", 7 / 2, "and as float:", float(7) / 2)
|
||||
print("int(9.99) =", int(9.99))
|
||||
}
|
||||
31
examples/types.fn
Normal file
31
examples/types.fn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Sized numbers and pointers.
|
||||
|
||||
fn double(ptr[int] p) {
|
||||
p.value = p.value * 2
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// everyday: int and float. For bytes and hardware: exact sizes.
|
||||
u8 small = 255
|
||||
i32 points = -1000
|
||||
big := u64(0xFFFF_FFFF)
|
||||
f32 half = 0.5
|
||||
|
||||
small += 1 // u8 wraps around, like real hardware
|
||||
print("u8 255 + 1 =", small)
|
||||
print("points:", points, "big:", big, "half:", half)
|
||||
|
||||
i64 wide = points // a smaller type fits into a bigger one by itself
|
||||
print("wide:", wide)
|
||||
|
||||
// pointers: addr(x) gives you where x lives, p.value is what is there
|
||||
int x = 21
|
||||
p := addr(x)
|
||||
double(p)
|
||||
print("x is now", x)
|
||||
|
||||
ptr[int] nothing = null
|
||||
if nothing == null {
|
||||
print("nothing points nowhere")
|
||||
}
|
||||
}
|
||||
34
examples/window.fn
Normal file
34
examples/window.fn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// A window that slowly changes color. Needs GLFW and OpenGL
|
||||
// (on Nix they are in shell.nix: run this inside nix-shell).
|
||||
import "GLFW/glfw3.h"
|
||||
import "GL/gl.h"
|
||||
import "math.h"
|
||||
link "glfw"
|
||||
link "GL"
|
||||
|
||||
fn main() {
|
||||
if glfwInit() == 0 {
|
||||
print("could not start GLFW")
|
||||
return
|
||||
}
|
||||
|
||||
window := glfwCreateWindow(800, 600, "Finch", null, null)
|
||||
if window == null {
|
||||
print("could not open a window")
|
||||
glfwTerminate()
|
||||
return
|
||||
}
|
||||
glfwMakeContextCurrent(window)
|
||||
|
||||
while glfwWindowShouldClose(window) == 0 {
|
||||
t := glfwGetTime()
|
||||
glClearColor(f32(sin(t) * 0.5 + 0.5), 0.3, 0.6, 1.0)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
|
||||
glfwSwapBuffers(window)
|
||||
glfwPollEvents()
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window)
|
||||
glfwTerminate()
|
||||
}
|
||||
Loading…
Reference in a new issue