mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
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:
parent
1dc976bd8f
commit
c7ddd4d8b6
8 changed files with 3153 additions and 1 deletions
|
|
@ -8,7 +8,7 @@ namespace finch {
|
|||
|
||||
bool Codegen::isBuiltin(const std::string &n) {
|
||||
static const std::set<std::string> names = {"print", "addr", "input", "new", "free", "read_file", "write_file",
|
||||
"file_exists", "exit"};
|
||||
"file_exists", "exit", "shell"};
|
||||
FType t;
|
||||
return names.count(n) || typeFromName(n, t);
|
||||
}
|
||||
|
|
@ -91,6 +91,7 @@ Function *Codegen::rt(const std::string &name) {
|
|||
{"finch_file_exists", {I32, {P}}},
|
||||
{"finch_read_file", {V, {P, P, P, I}}},
|
||||
{"finch_write_file", {I32, {P, P}}},
|
||||
{"finch_shell", {I, {P}}},
|
||||
};
|
||||
auto it = sigs.find(name);
|
||||
if (it == sigs.end()) {
|
||||
|
|
@ -229,6 +230,15 @@ Value_ Codegen::call(const CallExpr &c) {
|
|||
release(path);
|
||||
return res;
|
||||
}
|
||||
if (n == "shell") {
|
||||
Value_ cmd = coerce(expr(one("command")), FType::Str, c.args[0]->pos, "the command");
|
||||
Value *ss = tmpOf(ty(FType::Str));
|
||||
b.CreateCall(rt("finch_str_copy"), {ss, tmp(cmd.v)}); // a heap copy is always NUL-terminated
|
||||
Value *r = b.CreateCall(rt("finch_shell"), {ss});
|
||||
dropAt(ss, FType::Str);
|
||||
release(cmd);
|
||||
return {r, FType::I64};
|
||||
}
|
||||
if (n == "write_file") {
|
||||
checkArgs(c.args, c.argNames, 2, p, n);
|
||||
Value_ path = coerce(expr(*c.args[0]), FType::Str, c.args[0]->pos, "the file name");
|
||||
|
|
|
|||
Loading…
Reference in a new issue