mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
export fn and finch build --shared, in the compiler written in Finch; FINCH_PATH, FINCH_RT, FINCH_CC
export fn name(...) is a C function of a library; build --shared makes lib<name>.so with no main and a finch_module_on_fatal(handler) the host can take runtime errors over with. Ported from the embed work (the runtime, its test and the docs are that work's; the compiler side is new). The driver reads FINCH_PATH (more module folders), FINCH_RT (the runtime's file) and FINCH_CC (the clang). tests/boot.sh also runs tests/shared.sh with the compiler under test. 41 passed.
This commit is contained in:
parent
94e41484dd
commit
dd9cbe7611
13 changed files with 212 additions and 13 deletions
|
|
@ -60,5 +60,13 @@ for f in tests/new/fail/*.fch; do
|
|||
echo "$got" | head -3
|
||||
fi
|
||||
done
|
||||
# a library a C program loads (finch build --shared), with the compiler under test
|
||||
if FINCH_RT="$PWD/runtime/finch_rt.c" FINCH="$boot" tests/shared.sh > "$tmp/shared.out" 2>&1; then
|
||||
pass=$((pass + 1))
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
echo "FAIL tests/shared.sh"
|
||||
head -5 "$tmp/shared.out"
|
||||
fi
|
||||
echo "self-hosted compiler: $pass passed, $failed failed, $skipped skipped (features it doesn't have)"
|
||||
[ $failed -eq 0 ]
|
||||
|
|
|
|||
17
tests/shared.sh
Executable file
17
tests/shared.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
# finch build --shared: a library a C program loads, calls by name, and that hands runtime
|
||||
# errors to the host instead of exiting.
|
||||
set -e
|
||||
cd "$(dirname "$0")/shared"
|
||||
FINCH=${FINCH:-../../build/finch}
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
"$FINCH" build mod.fch --shared -o "$tmp/libmod.so"
|
||||
${CC:-cc} host.c -rdynamic -o "$tmp/host" -ldl
|
||||
out=$("$tmp/host" "$tmp/libmod.so")
|
||||
expected='add 42
|
||||
even 1 0
|
||||
host_print: hello Rakya
|
||||
caught: mod.fch:17: runtime error: index 7 is out of range (the length is 3)
|
||||
still alive'
|
||||
if [ "$out" = "$expected" ]; then echo "shared library: passed"; else printf 'shared library: FAILED\n%s\n' "$out"; exit 1; fi
|
||||
17
tests/shared/host.c
Normal file
17
tests/shared/host.c
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include <dlfcn.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
static jmp_buf jb;
|
||||
void host_print(const char *s) { printf("host_print: %s\n", s); }
|
||||
static void onFatal(const char *m) { printf("caught: %s\n", m); longjmp(jb, 1); }
|
||||
int main(int argc, char **argv) {
|
||||
void *h = dlopen(argc > 1 ? argv[1] : "./libmod.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!h) { printf("%s\n", dlerror()); return 1; }
|
||||
((void (*)(void (*)(const char *)))dlsym(h, "finch_module_on_fatal"))(onFatal);
|
||||
printf("add %ld\n", ((long (*)(long, long))dlsym(h, "add"))(2, 40));
|
||||
printf("even %d %d\n", ((_Bool (*)(long))dlsym(h, "is_even"))(4), ((_Bool (*)(long))dlsym(h, "is_even"))(5));
|
||||
((void (*)(const char *))dlsym(h, "hello"))("Rakya");
|
||||
if (!setjmp(jb)) ((long (*)(long))dlsym(h, "crash"))(7);
|
||||
printf("still alive\n");
|
||||
return 0;
|
||||
}
|
||||
1
tests/shared/host.h
Normal file
1
tests/shared/host.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void host_print(const char *s);
|
||||
22
tests/shared/mod.fch
Normal file
22
tests/shared/mod.fch
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import "host.h"
|
||||
|
||||
fn greet(str who) -> str {
|
||||
return "hello " + who
|
||||
}
|
||||
|
||||
export fn add(int a, int b) -> int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
export fn hello(ptr[char] name) {
|
||||
host_print(greet(str(name)))
|
||||
}
|
||||
|
||||
export fn crash(int i) -> int {
|
||||
xs := [1, 2, 3]
|
||||
return xs[i]
|
||||
}
|
||||
|
||||
export fn is_even(int n) -> bool {
|
||||
return n % 2 == 0
|
||||
}
|
||||
Loading…
Reference in a new issue