
Fels 发布:一门支持编译期代码执行的小型系统语言
来源标题:Show HN: Fels – a systems language with compile-time code execution
Fels 是一门通过 LLVM 编译为原生代码、不带垃圾回收器的系统语言,工具链内置编译器、构建系统、测试运行器、包管理器和链接器。它支持 64 位 Windows 和 Linux,最新版本已提供下载。作者表示已用它开发了真实项目 Strata,并在过程中修复了大量编译器 bug。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
Fels 是一门小型系统编程语言,专为那些想清楚了解自己代码在做什么的人而设计。它通过 LLVM 编译为原生代码,没有垃圾回收器。你所需的一切都集成在一个工具里:编译器、构建系统、测试运行器、包管理器,甚至还有自己的链接器。
大约 40 行 Fels 代码就能实现一个带实时图表的窗口。
代码在这里。
我想要一门贴近机器(像 C 那样)的语言,但更不容易出错,也更容易装进脑子里。因此 Fels 有几个核心理念,并努力把它们做好:
Fels 还很年轻,语言仍在变化。但它不是玩具:我用它写真实程序。最大的一個是 Strata,一个用于我自己投资的应用程序。构建它的过程中发现了编译器中的许多 bug,我也顺手把它们修好了。
Fels 运行在 64 位 Windows 和 Linux 上,并且能为这两个平台构建程序。最新版本为每个平台都提供了下载。
fels new 会创建一个项目,包含构建文件、一个小程序和一个测试:
fels new hello cd hello fels build run fels test
这是它为你生成的 src/main.fels:
#import std.io;
// The sum of the numbers from 1 to n.
sum_to :: fn(n: i32) -> i32 {
total := 0;
i := 1;
while i <= n {
total += i;
i += 1;
return total;
main :: fn() -> i32 {
io::println("Hello from hello!");
io::println("1 + 2 + ... + 10 = {sum_to(10)}");
return 0;
#test
sum_to_adds_the_numbers :: fn(t: *Test) {
t.eq(sum_to(0), 0);
t.eq(sum_to(1), 1);
t.eq(sum_to(10), 55);
内存按区管理
一个 zone 就是一个带名字和代码块的 arena。你在其中分配的任何东西都会一直存活到代码块结束,然后所有内容一次性释放。你永远不需要调用 free,也没有任何东西在后台运行来替你清理。
编译器会跟踪哪些内容属于某个 zone,因此不会有东西意外地逃逸出它的代码块。例如,下面的代码无法通过编译:
一个可能失败的函数会在类型中声明这一点,例如 -> i32 ! ParseError。在函数内部,fail 返回一个错误。调用者用 ? 将其传递下去,或用 catch 处理,其中 yield 可以提供一个替代值。错误可以携带负载,match 会同时读取两者。没有异常,也没有栈展开。
#run 在程序编译期间调用一个函数,结果作为常量进入二进制文件。宏从模板生成代码,编译器会像检查你自己写的代码一样检查这些代码。
编译时代码运行在一个小型虚拟机上。它读取的 IR 与原生后端相同,因此行为一致。构建文件和测试也可以在那里运行。
Fels 与 C 交互无需胶水代码。fels bindgen 将 C 头文件转换为 Fels 声明,#extern 调用 DLL 中的函数,#export 将你自己的函数交给 C。结构体保持 C 的布局。#packed 移除填充,带有 u1 到 u7 字段的 packed 结构体为你提供位域,union 像 C 一样覆盖其字段。Win32 示例和标准库中的 COM 支持都建立在此基础上。
安全检查在发布构建中依然开启。索引边界、空指针、整数溢出和除零都会被检查,除非你要求 fels build --release-fast。
构建文件本身也是一个 Fels 程序,编译器在编译时运行它:
Fels 甚至自带链接器。felsld 用 Fels 编写,生成 Windows 可执行文件和 DLL,并且能链接自身。发布版将其构建进 fels.exe,因此你不需要 LLD 来链接。
imgui 包带来了带停靠功能的 Dear ImGui,以及用于图表的 ImPlot。这就是顶部窗口背后的全部代码:
Strata 是一个用于我个人投资的桌面应用。它将账户、仓位和交易存储在 SQLite 中,并显示绩效、风险、配置和报告。它导入银行导出数据并从网络加载价格。它用 Fels 编写,使用了 imgui、sqlite、http 和 decimal 包。它尚未公开,目前界面为德语。
包 功能 imgui 带停靠功能的 Dear ImGui、就绪窗口和 ImPlot 图表 sqlite SQLite 3 http 通过 WinHTTP 的 HTTP 和 HTTPS decimal 用于货币的精确十进制数
标准库位于 lib/std。它包含集合、文件、进程、线程、套接字、JSON、CSV、日期等,docs/07_stdlib.md 列出了全部内容。
Windows x64 端到端可用。 Linux x64 也端到端可用:编译器在那里运行并构建静态可执行文件。 目前不支持 macOS,也还没有格式化工具。
-g 为程序提供调试信息:源代码行、函数、参数和带类型的局部变量,在 Windows 上是 PDB,在 Linux 上是 DWARF。在 Windows 上目前需要 Windows SDK 的导入库。
程序可以在没有操作系统的情况下运行,支持 x86-64 和 64 位 ARM:--target uefi 生成 UEFI 应用程序,--target freestanding 生成用于内核的 ELF,中断处理程序作为函数。examples/uefi、examples/kernel 和 examples/kernel_aarch64 可在 QEMU 中启动。
编译器有 863 个测试,CI 在每次推送时于 Windows 和 Linux 上运行它们。
KNOWN_ISSUES.md 列出了仍然粗糙的地方,更新日志显示了每个版本的变化。
语言参考在 docs 中。以下是好的起点:
如果你尝试了 Fels,我很想听听进展如何。为 bug、问题或想法开一个 issue。能展示问题的小程序最有帮助。
编译器用 Zig 0.16 编写。你需要一个包含 C 头文件的 LLVM 构建:在 Linux 上,使用 llvm.org 的发布版(LLVM-22.1.6-Linux-X64.tar.xz,构建时静态链接它),在 Windows 上使用 clang+llvm-22.1.6-x86_64-pc-windows-msvc.tar.xz。
zig build -Dllvm-path=path/to/llvm zig build test -Dllvm-path=path/to/llvm
编译器输出到 zig-out/bin。
编译器采用 GPL v3 许可。运行时和标准库采用 Apache 2.0 许可。你的程序只包含第二部分,因此它们属于你,你可以按自己的意愿授权和发布。LICENSING.md 有详细信息。
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。