用自身语言 编译自身
自研的静态类型、表达式导向、编译型系统编程语言。 编译器用 JHYY 写 JHYY —— 从 v1 编到 v5,五份中间表示字节完全相同, 并且这件事在第 10 代仍然成立。
JHYV 4.0.6 (self-hosted)
GEN 1 jhyy_v1.exe --compile--> main.jhyy
GEN 2 jhyy_v2.exe --compile--> main.jhyy byte-equal
GEN 3 jhyy_v3.exe --compile--> main.jhyy byte-equal
GEN 4 jhyy_v4.exe --compile--> main.jhyy byte-equal
GEN 5 jhyy_v5.exe --compile--> main.jhyy byte-equal
IL 1,378 MB sha256 v2/v3/v4/v5 IDENTICAL
N >=10 fixed point HELD
>> 不动点是吸引子,不是暂态。CLOSED.
type Point = struct { x: i32, y: i32 } fn dist_sq(a: Point, b: Point) -> i32 { let dx = a.x - b.x; let dy = b.y - a.y; dx * dx + dy * dy // 无分号,末行即返回值 } fn classify(n: i32) -> *u8 { match n { // 带穷尽性检查 0 => "zero", 1..10 => "single digit", 10 | 20 => "round number", _ => "other", } } extern fn printf(fmt: *u8, val: i32) -> i32; // FFI 到 C fn main_jhyy() -> i32 { let p = Point { x: 3, y: 4 }; printf("d² = %d\n", dist_sq(p, Point { x: 0, y: 0 })); let s = "机会翼游"; // UTF-8 原生字面量 0 }
$ cat compiler/tests/examples/hello.jhyy fn main_jhyy() -> i32 { 42 } $ jhyy build hello.jhyy # 第 2 代自举编译器 dbgfile "hello.jhyy" export function w $main_jhyy() { @start0 dbgloc 1 dbgloc 2 %t1 =w copy 42 ret %t1 } $ ./hello.exe ; echo $? 42
$ python regress.py --all W-097 multi-field access emit ..... 22 skipped 1 exit code semantics ...... ok 2 struct pass-by-value ...... ok 3 float cast / fmod / signed zero ...... ok 4 arena alloc + reset ...... ok 5 match exhaustiveness ...... ok ... 158 passed, 22 skipped, 0 failed $ jhyy_selfhost_check all_byte_equal = true
自举闭环 / SELF-HOST
BOOT第 1 代编译器编出第 2 代,第 2 代编出第 3 代……一直编下去。 关键是:从第 2 代起,产物字节完全相同。它落在了一个不动点上。
没有 fix-up 后处理。编译器对自己说的话,和它对别人说的话,是同一句。
C 端 src/*.c 与 JHYY 端 src0/*.jhyy 共存,互相校验。
语言 / THE LANGUAGE
SPECi8 i16 i32 i64/u8 u16 u32 u64f32 f64/bool/*T[T; N]定长数组 /[*]T切片struct/enumas显式转换,含*T ↔ i64
if/else,本身是表达式while/for i in a..bbreak/continuematch:字面量 / 区间 / 或模式 / 通配- 分支穷尽性检查,漏一条编译期报错
extern fn直接调 C 函数import+ 多文件编译mod::fn()命名空间const NAME: [T; N]编译期进.data- Arena 分配器经 FFI 接入
- inline asm
#[naked]/volatile#[link_section]/ 内存屏障#[no_std]免标准库&mut+ lifetime
src0/std/标准库也是 JHYY 写的 —— 这是自举必须吞掉的那块最硬的骨头。
命令行 / COMMAND LINE
CLI$ jhyy --help
jhyy [--target=<triple>] [--help] <command> [args]
commands:
compile <file.jhyy> [-o output] compile to .obj
build <file.jhyy> [-o output] compile + link to .exe
run <file.jhyy> compile + link + execute
dump <file.jhyy> print AST / typed IR
flags:
--target=<triple> default amd64_win
--no-link compile to .s only
--help show this message
入口函数叫 main_jhyy 而不是 main —— 名字里带着这门语言,
免得和 C 的运行时抢。
工具链 / TOOLCHAIN
TOOLS编译器自带一个 Claude Code MCP 服务,把「跑回归、看 IL、验自举」变成一句话。
VS Code 扩展:语法高亮、文件图标、原生 Ctrl+F5 编译并运行。
仓库自带 .vscode/tasks.json,打开就配好终端 PATH。
- One-shot 安装器
.exe:编译器 + 文件关联 + 扩展 + PATH 一步到位 - MSI
~995 KB:企业 / SCCM 无人值守分发 - VSIX
~13 KB:编辑器扩展 - MIT 协议 · Windows x64 为当前主目标
版本轴 / RELEASE AXES
HISTORY.il 闭环.jhyynb工程账本 / WORKAROUND LEDGER
LEDGER每个已知缺陷编一个号(W-NNN),修不好就写进账本、写清状态、留证据。 修错了就回滚,把回滚也记下来。下面这段是账本上的真实一页。
| #1 | REVERTED | bitmap 方案错方向 |
| #2 | REVERTED | alloc pool disjoint 假设错 |
| #3 | REVERTED | 深审计 checklist 后仍是错的 |
| #4 | REVERTED | plan 方向被审计推翻 |
| #5–6 | REVERTED | 改对了方向,写错了参数个数 |
| #7 | SUCCESS | gdb 一轮 RCA 拿到冒烟枪:少传了 state 指针 |
第七次成功的原因不是更聪明,是不再猜:先用 gdb 抓到
rcx=NULL 的那一行,再回头改。三行调用点改成三参数形式,歧义消失。
大多数项目的 bug 列表读起来像功能缺陷清单。这个项目的账本读起来像 推理失败记录:哪一次假设错了、为什么错、拿什么证据推翻的。 对一个宣称自举的编译器来说,这比任何一处代码都更能说明它是不是真的。
- W-097 —— 25 处多字段访问 emit 待真修(跨 10 个模块)
- W-072 —— 多字段访问 emit
- 规则:正式版发布前,活跃与延期项必须清零。
上手 / GET STARTED
START$ git clone https://github.com/JiHuiYiYou/JiHuiYiYou-compiler.git $ cd JiHuiYiYou-compiler $ make # -Wall -Wextra,0 warning $ ./compiler/build/bin/jhyy.exe run hello.jhyy
前置:MSYS2 + ucrt64 工具链(GCC / binutils)。别用 Git Bash 自带的 MinGW,链不上 PE。
fn main_jhyy() -> i32 { 42 }
$ jhyy build hello.jhyy $ ./hello.exe $ echo $? 42