大家好,我是何三,独立开发者

不知道你听没听过这个事——有人用 Zig 写了个编程语言解释器,整个项目打包下来不到 1MB,Star 数快破万了。

说实话,我第一次看到这个数字的时候,第一反应是:这玩意儿真的能跑?

Ink 解释器与传统解释器对比

我印象里写个编程语言,那不得 C 或者 C++ 起步,几万行代码打底?什么词法分析、语法分析、AST、虚拟机……光听着就头大。结果这个叫 Ink 的项目,用一门很多人连名字都没听过的语言,几千行代码就搞定了。

一下子就给我整不会了。


这年头,怎么都在用 Zig 写奇怪的东西

先说说 Zig 这语言吧。

如果你没用过,我简单形容一下:它就是 C 语言的现代版,但比 C 好用一百倍。

没有隐式内存分配、没有隐藏的控制流、编译期就能执行代码……而且最骚的是,Zig 编译出来的二进制文件小得离谱,不依赖任何运行时。你写个 Hello World,编出来可能就几十 KB。

最近圈子里有好几个项目都在用 Zig 写,比如那个火得一塌糊涂的终端模拟器 Ghostty,再比如这个 Ink 解释器。感觉 Zig 圈的人有一个共同爱好——用最小的体积做最硬核的事。

没懂为什么大家都这么追求体积小?原因其实很简单:

大白话翻译:越小越快,越快越省,越省越能往嵌入式设备上塞。

你想想,一个解释器如果在树莓派 Pico 上都能跑,那场景不就一下子打开了?

那 Ink 到底是怎么个"小"法?

看项目介绍,Ink 是一门语法极简的动态类型语言,内置了垃圾回收,语法风格有点像 Lua 和 Python 的混合体。

举个例子,写个 Hello World 就一行:

print("Hello, Ink!");

定义函数也很简单:

fn fib(n) {
    if n <= 1 {
        return n;
    }
    return fib(n - 1) + fib(n - 2);
}

print(fib(10));

Ink 代码运行演示

看着好像平平无奇对吧?但背后的东西才是重点。

Ink 的解释器是用 Zig 从头写的,整个项目包括了: - 词法分析器(Lexer)——把代码拆成单词 - 语法分析器(Parser)——把单词拼成语法树 - AST 解释器——直接跑语法树,不用编译成字节码

三个模块加一起,才几千行 Zig 代码。 编出来的二进制文件,不到 1MB。

为什么这么小的体积能做到别的项目几万行代码做的事?因为 Zig 本身的特性:

第一,Zig 没有隐式控制流。 你不会在调用一个函数时莫名其妙被分配了内存,所有行为都是显式的。写解释器的时候,每一行代码干了什么,清清楚楚。

第二,Zig 的编译期执行。 有些在运行时才能确定的逻辑,可以在编译期就算好,直接嵌入到二进制里。解释器跑起来的时候,少了一堆 runtime 判断。

第三,手写递归下降解析器。 Ink 没有用 yacc 或 bison 那种解析器生成器,而是手写了解析器——这在 Zig 里写起来意外地顺手。

说实话,这块我也没完全搞懂——为什么手写解析器在 Zig 里比在 C 里顺手这么多?可能是 Zig 的错误处理机制(就是那个 tryerror union)让代码写起来更像高级语言吧。

有懂 Zig 的大佬欢迎指正。😅

话说回来,看到 Ink 这个项目的时候,我突然想到了另一件事。

我记得之前看过一个用 Rust 写的解释器,叫 Rlox,也是教你怎么写编程语言的。那项目文档写得好,但体积嘛……Rust 编译出来的东西,你懂的。

对比一下,Ink 的 Zig 版解释器体积大概是 Rlox 的 1/10 不到——不是 Rust 不好,是 Zig 在"造轮子"这件事上真的太变态了。

怎么上手?直接两分钟跑起来

项目 README 里写得很清楚,克隆下来直接用 Zig 编译就行。

如果你还没装 Zig,去 ziglang.org 下载一个,或者用包管理器:

# macOS
brew install zig

# Linux
snap install zig --classic

然后跑 Ink:

git clone https://github.com/ink-lang/ink
cd ink
zig build run

你就能进入 Ink 的 REPL 了,跟 Python 的交互式环境一样,写一行跑一行。

如果想直接跑一个 .ink 文件:

zig build run -- examples/fib.ink

整个体验怎么说呢——快得有点不真实。 启动几乎没有延迟,不像某些解释器(我说的是谁你心里有数)还要等一两秒才出提示符。

如果你对"用 Zig 写解释器"这个话题感兴趣,还有两个项目值得一看:

1. Zigler——一个用 Zig 写的 Lua 解释器,思路和 Ink 类似,但目标是兼容 Lua 5.4 的语法。如果你对 Lua 更熟,可以从这个入手。

2. Ghostty——我之前在公众号里提过的 Zig 终端模拟器,启动 < 20ms,GPU 加速渲染。这个项目让我第一次意识到 Zig 的潜力有多大。

项目地址: 👉 https://github.com/ink-lang/ink

怎么说呢,Ink 这个项目让我重新理解了什么叫"小而美"。

不是功能多才叫强,不是代码多才叫牛。用最少的代码,做最硬核的事,这才是真功夫。

你要是对编程语言设计感兴趣,或者只是想看看 Zig 到底有多强,花两小时翻翻这个项目的源码,你会有收获的。

本文使用 MGO 编辑并发布

关注"何三笔记",回复"mgo" 免费下载使用