Kylix v3.0.0-alpha 深度解析:架构突破——LLVM原生后端、WASI、包注册中心与标准库全面自举

Kylix 连续观察 · 第二十五篇

项目地址:https://github.com/astra-zhao/kylix

版本聚焦:v3.0.0-alpha

关键词:LLVM 原生后端、WASI、包注册中心、stdlib Phase 4、jsonutil/regex/datetime 纯 Kylix 实现、external 函数声明、HTTP 客户端


开篇:第二十五篇,Kylix 跨过了一条真正的分水岭

上一篇第二十四篇,我们分析的是 Kylix v2.5.0。当时的判断是:v2.5.0 是一次"工具链深化",把 LSP 重构、文档示例提取、bench 内存报告、iter 模块和类外方法定义补齐,让工具链从"能用"走向"顺手"。

第二十四篇结尾写的是:

下一步,如果 ROADMAP 按原计划推进,v2.6.0 将进入性能与优化阶段。

而 v2.6.0 确实如期而至------并行编译、死代码消除(DCE)、LSP 大文件性能基准三项任务落地,给 v2.x 系列画上了一个漂亮的句号。

但真正的大新闻,不是 v2.6.0。

是在 v2.6.0 发布仅仅一天之后,39cef28 号提交标记了一个所有人都在等的版本:

v3.0.0-alpha --- Architecture breakthrough

一次提交,93 个文件变更,9850 行新增,370 行删除

这不是增量迭代。这是架构跃迁。

如果说 v1.2.0 的自举(Kylix 编译 Kylix)回答了"这门语言能不能编译自己",v2.0.0 回答了"它能不能成为一个完整工具链",v2.1~v2.6 回答了"它能不能被开发者舒服地使用",那么 v3.0.0-alpha 回答的是一个更根本的问题:

Kylix 能不能不依赖 Go 运行时,直接生成原生代码?

答案是:能。

而且不止于此。本次 v3.0.0-alpha 同时落地了四大架构级特性:

    1. LLVM 原生后端(Milestone 1) ------kylix build --backend=llvm,Kylix → LLVM IR → 原生 ARM64/x86_64 二进制,Hello World 只有 33KB ,对比 Go 后端约 2MB,体积缩小约 60 倍
    1. WASI 支持 ------kylix build --wasi,编译到 WebAssembly System Interface,可以跑在 Wasmtime、Node.js、Cloudflare Workers 上
    1. 包注册中心服务端 ------registry/ 子模块,完整的包发布/搜索/下载 REST API + htmx Web 前端,配套 kylix publish CLI 命令
    1. stdlib Phase 4 ------纯 Kylix 重写 jsonutil(390 行,支持嵌套 JSON)、regex(387 行,覆盖常见验证场景)、datetime(260 行,日期运算与格式化),标准库纯 Kylix 函数达到 90+ ,Kylix 级测试达到 117 个

此外,还顺手修复了 external 函数声明解析这个长期 Bug,新增了 HTTP 客户端标准库,补了 23 个完整教程示例,以及中英文 Getting Started 文档。

一句话概括 v3.0.0-alpha:

Kylix 正式从"编译到 Go 的 Pascal"进化为"多后端架构的现代语言",自举叙事从编译器扩展到整个生态。

这篇文章,我们就来把这次架构突破掰开揉碎了讲。


一、版本总览:从 v2.6.0 到 v3.0.0-alpha,9850 行新增了什么

从第二十四篇(v2.5.0)完成到现在,远端主线推进了两个版本:

  • v2.6.00077caf):并行编译、死代码消除、LSP 性能基准------8 个测试,性能与优化主题

  • v3.0.0-alpha39cef28fbf3141):LLVM + WASI + Registry + stdlib Phase 4------9850 行,架构突破

让我们先从统计数据感受一下这次变更的规模:

指标 v2.6.0 v3.0.0-alpha 变化
Go 测试包 13 15 +2(llvmgen、wasi)
Go 级测试 ~258 ~310+ +52
Kylix 级 stdlib 测试 48 117 +69
纯 Kylix stdlib 模块 7 10 +3(datetime、jsonutil、regex + wasi、httpclient)
纯 Kylix stdlib 函数 54 90+ +36+
CLI 命令 17 19 +2(publish、--backend=llvm、--wasi)
构建后端 1(Go) 3 (Go、LLVM、WASI) +2
代码生成 Go AST → .go 新增 LLVM IR → .ll → .o → binary 全新路径
二进制大小(Hello World) ~2MB 33KB ~60× 缩小

v3.0.0-alpha 的 CHANGELOG 结构也变了。之前版本按"Task 1/2/3"分任务,这次直接按四大架构里程碑展开:

模块 内容 核心文件
LLVM 原生后端 SSA 寄存器分配、标量/控制流/函数/类 codegen、llc+clang 链路 pkg/llvmgen/ (5 个 .go 文件,~1430 行)
WASI 支持 --wasi 编译、系统调用层、纯 Kylix 高层包装 pkg/wasi/ (4 文件)、stdlib/src/wasi.klx
包注册中心 SQLite 后端、Bearer 认证、REST API、htmx 前端、publish CLI registry/ (独立 Go module,~1300 行)
stdlib Phase 4 jsonutil、regex、datetime 纯 Kylix 实现 stdlib/src/{jsonutil,regex,datetime}.klx (1037 行)
编译器修复 function Foo(); external; 正确解析 ast/ast.goparser/parser_decl.gogenerator/generator_types.go
HTTP 客户端 THttpClient、Get/Post/JSON、状态码判断 stdlib/http_client.gostdlib/src/httpclient.klx
文档与教程 中英文 Getting Started、23 个完整教程示例 docs/GETTING_STARTED{,_CN}.mdexamples/complete-tutorial/

这是自 v1.2.0 自举以来,单次版本变更最大的一次。


二、LLVM 原生后端:33KB 原生二进制是怎么来的

这是 v3.0.0-alpha 最重要的特性,也是为什么版本号直接跳到了 3.0。

2.1 设计思路:文本 IR + SSA + libc 调用链

Kylix 的 LLVM 后端选择了一个非常务实的实现路径:

    1. 输出文本格式 LLVM IR.ll 文件),不依赖 LLVM C++ API 或 Go 的 LLVM 绑定,避免了庞大的 CGO 依赖
    1. 使用 alloca/load/store 模型简化 SSA(Static Single Assignment)------每个局部变量分配一个 stack slot,读写通过 load/store 指令,而不是追求更激进的 SSA 寄存器优化
    1. 运行时最小化 :不引入垃圾回收器或复杂 runtime,直接调用 libc 的 printf/puts/malloc/strlen/snprintf
    1. 后端工具链 :调用系统安装的 llc(LLVM Static Compiler)将 .ll 编译为 .o 目标文件,再调用 clang 链接为可执行文件

整个管道是:

复制代码
Kylix AST → LLVM IR Text (.ll) → llc → Native Object (.o) → clang → Native Binary

2.2 已实现的能力(Milestone 1)

根据源码和测试验证,Milestone 1 已支持:

特性 实现状态 测试验证
模块头与目标三元组 TestIR_ModuleHeader
整数/布尔/字符串常量 TestIR_IntegerLiteralTestIR_BooleanLiteralTestIR_StringConstant
算术/比较/逻辑运算 TestIR_IntegerArithmeticTestIR_IntegerComparisonTestIR_BooleanNot
WriteLn 整数/字符串/布尔 TestIR_WriteLnInteger 、端到端 Hello World 验证
IntToStr 整数转字符串 TestIR_IntToStr 、端到端求和验证
if/if-else 控制流 TestIR_IfStatementTestIR_IfElseStatement
while/for 循环 TestIR_WhileLoopTestIR_ForLoop
repeat-until 循环 stmt.go 中已实现
函数定义与调用 TestIR_FunctionDecl
external 函数声明跳过 TestIR_ExternalFunctionSkipped
类 Struct 类型 TestIR_ClassStructType
类 vtable 与方法 TestIR_ClassWithMethodTestIR_ClassVtable
类多字段 GEP 访问 TestIR_ClassMultipleFields

端到端实测结果(本机 macOS ARM64):

复制代码
program LLVMComplete;

function Sum(n: Integer): Integer;
var
  i: Integer;
  total: Integer;
begin
  total := 0;
  i := 1;
  while i <= n do
  begin
    total := total + i;
    i := i + 1;
  end;
  result := total;
end;

var
  i: Integer;
begin
  WriteLn('=== Kylix v3.0.0 LLVM Backend Demo ===');
  i := 1;
  while i <= 5 do
  begin
    WriteLn(IntToStr(Sum(i)));
    i := i + 1;
  end;
  WriteLn('Sum(100) =');
  WriteLn(IntToStr(Sum(100)));
  WriteLn('Compiled to native ARM64 via LLVM!');
end.

编译运行:

复制代码
$ kylix build --backend=llvm llvm_complete.klx
✓ Built llvm_complete.klx → llvm_complete [llvm]
  IR:  llvm_complete.ll
  Obj: llvm_complete.o
$ ./llvm_complete
=== Kylix v3.0.0 LLVM Backend Demo ===

1
3
6
10
15

Sum(100) =
5050

Compiled to native ARM64 via LLVM!
$ ls -lh llvm_complete
-rwx------  33K  llvm_complete

33KB 原生 ARM64 二进制。作为对比,用 Go 后端编译同样功能的程序大约是 2MB------差距约 60 倍。这是因为 Go 后端携带了整个 Go runtime(GC、调度器、net/http 等),而 LLVM 后端只链接需要的 libc 函数。

2.3 已知限制(Milestone 1)

ROADMAP 非常诚实地列出了当前的限制:

  • • 不支持接口(vtable fat pointer)------ Milestone 2

  • • 不支持泛型单态化------ Milestone 2

  • • 不支持 LLVM 优化 Pass(当前是 -O0)------ Milestone 2

  • • 不支持异常(try/except)------ Milestone 3

  • • 不支持数组、record 类型------ Milestone 2

  • • WriteLn 当前只支持单参数,多参数串联输出需要使用 IntToStr 转换后逐行输出

  • • 类的 GEP 字段访问对复杂 lvalue(如 box.Value := 42)支持尚在完善中

这些限制说明 Milestone 1 的定位非常准确:先跑通端到端管道,再逐步补全语言特性。这是正确的工程策略------先让最小子集工作,再迭代扩展。

2.4 架构意义:为什么 LLVM 后端是 v3.0 而不是 v2.7

很多项目会把新后端作为次要版本发布,但 Kylix 把它作为 3.0 的核心特性,这是有道理的:

Go 后端是编译器的拐杖,LLVM 后端是编译器的成年礼。

在 Go 后端时代,Kylix 本质上是一个"Pascal → Go 转译器"。它巧妙地借助 Go 的成熟生态(GC、调度器、标准库、交叉编译)快速完成了语言自举和工具链建设。但代价是:

    1. 二进制携带 Go runtime,体积不可能小
    1. 无法摆脱 Go 的语言语义限制(如 goroutine 调度模型)
    1. 无法做细粒度的编译优化(逃逸分析、内联、向量化)
    1. 无法直接生成不依赖 Go 运行时的裸机/嵌入式代码

LLVM 后端的出现,意味着 Kylix 开始拥有自己独立的代码生成能力。未来它可以:

  • • 生成独立的小体积二进制(CLI 工具、系统工具)

  • • 支持裸机/嵌入式/WASM 等多目标

  • • 做独立于 Go 的编译优化

  • • 甚至可能自举 Kylix 编译器到 LLVM,彻底脱离 Go

这不是一个功能,这是一条新的生命线。


三、WASI 支持:Kylix 跑进服务端 WebAssembly

v2.3.0 已经有了 --wasm 支持(Go 的 GOOS=js GOARCH=wasm),但那个目标依赖 JavaScript 宿主环境(浏览器),无法做系统调用。

v3.0.0-alpha 新增的 WASI(WebAssembly System Interface)是另一个东西:它是 WebAssembly 的系统调用标准,可以在非浏览器环境中访问文件、环境变量、时钟、命令行参数等。

3.1 实现方式

复制代码
kylix build --wasi main.klx

底层使用 Go 1.21+ 内置的 GOOS=wasip1 GOARCH=wasm 交叉编译目标。同时支持 --tinygo 选项以 TinyGo 编译更小的二进制。

代码层面,pkg/wasi/ 采用了 Go build tag 分离:

  • wasi_wasip1.go------WASI 原生实现,调用 wasi-libc 系统调用

  • wasi_stub.go------非 WASI 环境的 stub 实现(所有函数返回"not available"),确保本地测试可编译

这是一个很干净的设计:WASI 相关代码不会污染正常构建,通过 build tag 实现零开销条件编译。

3.2 WASI 模块提供的能力

Kylix 的 WASI 标准库模块(stdlib/src/wasi.klx)封装了高层 API:

类别 函数
标准 I/O WriteLnReadLineStdoutStderrStdin
环境变量 GetenvHasEnvEnviron
命令行参数 ArgsArgCountArg
时钟 ClockMonotonicClockWalltimeElapsedMs
文件 I/O ReadFileWriteFile
退出 WasiExit

示例 examples/wasi-hello/main.klx

复制代码
program WasiHello;
uses wasi;
begin
  WriteLn('Hello from WASI!');
  WriteLn('Kylix on WebAssembly System Interface');
end.

编译后生成 .wasm 文件,可以用 Wasmtime 或支持 WASI 的 Node.js 运行。同时还提供了 examples/cloudflare-worker/worker.klx------一个 Cloudflare Workers HTTP handler 示例,说明 Kylix 的 WASI 目标可以直接部署到边缘计算平台。

3.3 为什么 WASI 重要

WASI 让 Kylix 代码可以跑在:

  • 边缘计算:Cloudflare Workers、Fastly Compute、Vercel Edge Functions

  • 容器化微服务:Wasm 微服务比 Docker 容器启动更快、体积更小、隔离性更强

  • 插件系统:作为宿主应用的脚本扩展

  • 跨平台 CLI:一个 .wasm 文件到处运行

结合 LLVM 后端的原生代码生成,Kylix 在 v3.0.0 后拥有了三种部署模式:

    1. Go 后端(默认):快速编译、完整标准库、依赖 Go runtime
    1. LLVM 后端:小体积原生二进制、最佳性能、不依赖 Go
    1. WASI 后端:WebAssembly 沙箱、跨平台、边缘计算

四、包注册中心:生态闭环的最后一块拼图

一门语言要真正形成生态,只有编译器和标准库是不够的。它还需要一个包分发机制

v2.4.0 已经有了本地包管理器(kylix add/remove、嵌套依赖、kylix.lock),v3.0.0-alpha 把它升级成了完整的客户端-服务端架构。

4.1 服务端:registry/ 模块

registry/ 是一个独立的 Go module(有自己的 go.mod),包含:

  • SQLite 数据库层internal/db/sqlite.go,318 行)------ Store 接口设计,可切换 PostgreSQL

  • REST API

  • internal/api/handler.go

  • ,281 行)------ 四个核心端点:

    • GET /api/v1/packages------搜索包(支持 ?q= 关键词查询)

    • POST /api/v1/packages------发布包(需要 Bearer token 认证)

    • GET /api/v1/packages/:name/versions------查询版本列表

    • GET /api/v1/packages/:name/:ver/dl------下载 tarball(重定向)

  • 认证中间件internal/auth/auth.go,66 行)------ Bearer token 验证

  • Web 前端------ htmx + Tailwind CSS,首页实时搜索 + 包详情页

  • 数据模型internal/models/models.go,48 行)------ Package、Version 等结构

4.2 客户端:kylix publish

CLI 新增 kylix publish 命令:

复制代码
kylix publish --version=1.0.0 --registry=https://kylix.top/packages --token=xxx

支持通过 KYLIX_TOKEN 环境变量传递认证 token,避免在命令行中明文输入。pkg/pkgmgr/http.go(44 行)处理 HTTP 上传。

4.3 意义

包注册中心的落地,意味着 Kylix 的生态系统叙事完整了:

复制代码
开发者写代码 → kylix build/run 编译 → kylix test 测试 → kylix doc 生成文档
→ kylix publish 发布到注册中心 → 其他开发者 kylix add 安装使用

这是一个从源码到分发的完整闭环。在此之前,Kylix 的包管理器只能安装 Git URL,缺乏中心化索引和搜索能力。注册中心补上了这个缺口。

当前注册中心还没有部署到公网(ROADMAP 标记为 v3.1 的待办项),但代码已经全部就绪,包括 7 个端到端集成测试(publish → list → search → download)。


五、stdlib Phase 4:jsonutil、regex、datetime 的纯 Kylix 实现

这是 v3.0.0-alpha 最让我兴奋的部分。

因为标准库的 Kylix 化,不是简单的"用自己的语言重写"------它意味着Kylix 已经足够强大,可以实现有实际复杂度的库

5.1 统计回顾

从 v2.1.0 的 stdlib Phase 1 开始,Kylix 就在持续用 Kylix 写自己的标准库:

模块 版本 行数 函数数 测试数
strutil v2.1.0 - 8 8
mathutil v2.1.0 - 12 10
arrayutil v2.2.0 - 8 8
collections v2.2.0 - 6 5
stringbuilder v2.4.0 - 5 4
resulttype v2.4.0 - 6 4
iter v2.5.0 - 9 9
jsonutil v3.0.0-alpha 390 - 29
regex v3.0.0-alpha 387 - 19
datetime v3.0.0-alpha 260 - 21
wasi v3.0.0-alpha 119 - -
httpclient v3.0.0-alpha 58 - -

Phase 4 三个模块合计 1037 行纯 Kylix 代码,69 个测试

纯 Kylix 标准库函数累计达到 90+ ,测试 117 个

5.2 jsonutil:390 行手写递归下降 JSON 解析器

ROADMAP 的已知问题中一直写着:

jsonutil 仅支持扁平 JSON ------ v3.0

v3.0.0-alpha 解决了这个问题。

stdlib/src/jsonutil.klx 实现了一个完整的 JSON 解析器:

  • TJsonLexer------词法分析器,支持字符串、数字、布尔、null、对象、数组的 tokenization

  • TJsonParser------递归下降解析器,支持任意深度嵌套的对象和数组

  • • 修复了此前仅支持单层扁平 JSON 的限制

这意味着 JSON 解析这个在多数语言里由运行时库提供的基础能力,Kylix 已经用自己写出来了。

特别值得注意的是:JsonEncode/JsonEncodePretty 保留为 external(Go 实现),因为编码需要 Go 的 reflect 支持来处理任意类型。这种"性能关键/需要外部能力的部分用 external 声明保留 Go 实现,解析逻辑用纯 Kylix 实现"的策略非常务实。

5.3 regex:387 行字符级验证函数库

这里的 regex 模块不是一个正则表达式引擎(NFA/DFA),而是一组常见格式验证函数

  • • 字符分类:IsDigitIsLowerIsUpperIsLetterIsAlphanumeric

  • • 格式验证:IsNumericIsAlphaIsEmailIsURLIsIPv4IsPhoneIsDate

没有 NFA 开销,全部是纯字符遍历的精确判断。

这是一个聪明的定位:Kylix 目前不需要完整的正则引擎(那是个大工程),但开发者最常用正则做的事情就是验证邮箱、URL、IP、手机号------这些直接写专用函数更快更准确。

5.4 datetime:260 行日期时间运算

ROADMAP 的另一个已知问题:

TDateTime 运算符 (+, -) 未实现 ------ v2.5

v3.0.0-alpha 解决了这个问题,提供了:

  • FormatPattern------yyyy/MM/dd/HH/mm/ss 格式化模式

  • DateAdd/DateSub------日期加减运算

  • IsLeapYearDaysInMonthIsWeekendIsWeekdayWeekNumber------日历计算

  • MonthNameDayName------月份和星期名称

这三个模块加起来,标志着 Kylix 的标准库自举从"简单工具函数"阶段进入了"实现有实质复杂度的库"阶段。写一个 JSON 解析器和写一个字符串反转函数完全不是一个量级的事情。


六、其他改进:external 函数、HTTP 客户端、文档体系

6.1 external 函数声明修复

Kylix 一直支持 function Foo(); external; 语法来声明在 Go 端实现的外部函数(如标准库函数),但此前解析器对文件末尾或某些位置的 external 声明处理有误。

v3.0.0-alpha 修复了这个问题:

  • ast/ast.go 新增 FunctionDecl.IsExternal 字段

  • parser/parser_decl.go 正确识别 EXTERNAL 修饰词

  • generator/generator_types.goIsExternal=true 的函数跳过函数体生成

  • • 新增 8 个测试(3 个 parser + 5 个 generator)

这个修复对于 standard library 作者非常重要,因为它确保了 external 声明可以放在文件任意位置,不再受位置限制。

6.2 HTTP 客户端标准库

新增 stdlib/http_client.go------THttpClient 类,支持:

  • Get(url)Post(url, body)StatusCode()SetHeader(key, value)

  • • 便捷函数:NewHttpClient()HttpGet(url)HttpPost(url, body)HttpGetJSON(url)

配套 stdlib/src/httpclient.klx------纯 Kylix 包装层:

  • BuildQueryString(params)------构建 URL 查询字符串

  • IsOK(code)IsRedirect(code)IsClientError(code)IsServerError(code)------状态码判断

加上已有的 web 模块(HTTP 服务端),Kylix 在 HTTP 层面同时具备了服务端和客户端能力。

6.3 文档体系大升级

v3.0.0-alpha 在文档方面做了两项重要补充:

    1. 中英文 Getting Started 指南docs/GETTING_STARTED.mddocs/GETTING_STARTED_CN.md,各 278 行)------面向新手的完整入门教程
  1. 23 个完整教程示例

  2. examples/complete-tutorial/

  3. )------按类别组织:

    • 01_basics/:Hello World、变量、常量、类型推断、运算符、注释(6 个)

    • 02_control_flow/:if/else、while、for、repeat、case(5 个)

    • 03_functions/:函数与过程、递归、多返回值(3 个)

    • 05_generics/:泛型类(1 个)

    • 06_advanced_types/:record、数组、Map(3 个)

    • 07_stdlib_core/:基础函数(1 个)

    • 10_exceptions/:try/except、try/finally(2 个)

    • 11_modules/:unit 定义与 uses(2 个)

其中 20 个完全可运行(87%),3 个有运行时问题(泛型类和模块引用)已在 INDEX.md 中标注。附带 test_all.sh 自动化测试脚本。

对于一个编程语言项目来说,文档质量直接决定了新用户的第一道门槛。23 个经过测试的示例 + 中英文 Getting Started,说明 Kylix 开始认真对待"如何让新用户 5 分钟上手"这件事。


七、与 v2.x 系列的对比:从工具链打磨到架构革命

让我们把 v2.1 到 v3.0.0-alpha 的演进放在一张表里看:

版本 主题 核心价值 本质
v2.1.0 增强类型系统 + stdlib Phase 1 多参数泛型约束、接口签名验证、strutil/mathutil 语言内核增强
v2.2.0 工程质量 + stdlib Phase 2 CI/CD、跨文件类型检查、增量编译、arrayutil/collections 生产可用性
v2.3.0 开发者体验 LSP 增量同步、REPL 增强、Delve 调试、WASM 现代化 DX
v2.4.0 完善与生态 i18n 全接入、真实类型推导、SetLength、包管理器 lockfile 生态闭环
v2.5.0 工具链深化 LSP rename/codeAction、doc 示例、bench --mem、iter 模块 开发手感
v2.6.0 性能与优化 并行编译、死代码消除、LSP 性能基准 编译性能
v3.0.0-alpha 架构突破 LLVM 原生后端、WASI、包注册中心、stdlib Phase 4 多后端架构

这条路线有一个非常清晰的递进逻辑:

  • • v2.1-v2.2:把语言做对(类型系统、工程质量)

  • • v2.3-v2.5:把工具做好(IDE、REPL、调试、文档、benchmark)

  • • v2.6:把性能做快(并行编译、DCE)

  • • v3.0:把架构做大(多后端、生态、标准库自主化)

v2.x 回答的是"Kylix 能不能做好";v3.0 回答的是"Kylix 能走多远"。


八、开发示例:v3.0.0 新特性亲手体验

以下所有示例均已在 Kylix v3.0.0-alpha 上实际编译运行通过。

示例 1:LLVM 原生后端编译------从 Pascal 到 33KB 原生二进制

复制代码
program LLVMDemo;

function Sum(n: Integer): Integer;
var
  i: Integer;
  total: Integer;
begin
  total := 0;
  i := 1;
  while i <= n do
  begin
    total := total + i;
    i := i + 1;
  end;
  result := total;
end;

var
  i: Integer;
begin
  WriteLn('=== Kylix LLVM Backend (v3.0.0) ===');
  i := 1;
  while i <= 6 do
  begin
    WriteLn(IntToStr(Sum(i)));
    i := i + 1;
  end;
  WriteLn('Sum(100) =');
  WriteLn(IntToStr(Sum(100)));
end.

编译运行:

复制代码
$ kylix build --backend=llvm llvm_demo.klx
✓ Built llvm_demo.klx → llvm_demo [llvm]
  IR:  llvm_demo.ll
  Obj: llvm_demo.o

$ ./llvm_demo
=== Kylix LLVM Backend (v3.0.0) ===
1
3
6
10
15
21
Sum(100) =
5050

$ ls -lh llvm_demo
-rwx------  33K  llvm_demo

对比 Go 后端同样功能程序约 2MB 的体积,LLVM 后端的优势一目了然。

注意 :使用 LLVM 后端需要系统安装 LLVM 工具链(llcclang)。macOS 上通过 brew install llvm 安装,Linux 上通过 apt install llvm clang

示例 2:WASI 编译------Pascal 跑在 WebAssembly 上

复制代码
program WasiDemo;
begin
  WriteLn('Hello from WASI!');
  WriteLn('Kylix compiles to WebAssembly System Interface');
  WriteLn('Run with: wasmtime wasi_demo.wasm');
end.

$ kylix build --wasi wasi_demo.klx
✓ Built wasi_demo.klx → wasi_demo.wasm [wasi via Go]

$ ls -lh wasi_demo.wasm
-rwx------  2.5M  wasi_demo.wasm

生成的 .wasm 文件可以在任何支持 WASI 的运行时中执行:

复制代码
# 使用 Wasmtime
wasmtime wasi_demo.wasm

# 或使用 Node.js(需要 --experimental-wasi-unstable-preview1)
node --experimental-wasi-unstable-preview1 -e "
const { WASI } = require('wasi');
const wasi = new WASI({ version: 'preview1' });
const fs = require('fs');
const wasm = WebAssembly.compile(fs.readFileSync('wasi_demo.wasm'));
wasi.start(wasm.instance);
"

示例 3:v3.0.0 综合特性展示------Go 后端(最稳定,功能最全)

复制代码
program V3Showcase;

function Factorial(n: Integer): Integer;
begin
  if n <= 1 then
    result := 1
  else
    result := n * Factorial(n - 1);
end;

function IsPrime(n: Integer): Boolean;
var
  i: Integer;
begin
  if n < 2 then
  begin
    result := false;
    Exit;
  end;
  i := 2;
  while i * i <= n do
  begin
    if n mod i = 0 then
    begin
      result := false;
      Exit;
    end;
    i := i + 1;
  end;
  result := true;
end;

var
  i: Integer;
  count: Integer;
begin
  WriteLn('========================================');
  WriteLn('  Kylix v3.0.0-alpha Feature Showcase');
  WriteLn('========================================');
  WriteLn('');
  
  // 类型推断
  var version := '3.0.0-alpha';
  var codename := 'Architecture Breakthrough';
  WriteLn('Version: ', version);
  WriteLn('Codename: ', codename);
  WriteLn('');
  
  // 递归 + Exit 提前返回
  WriteLn('--- Factorials 1-10 ---');
  for i := 1 to 10 do
  begin
    WriteLn(i, '! = ', Factorial(i));
  end;
  
  // 循环 + 判断
  WriteLn('');
  WriteLn('--- Primes under 30 ---');
  count := 0;
  for i := 2 to 29 do
  begin
    if IsPrime(i) then
    begin
      Write(i, ' ');
      count := count + 1;
    end;
  end;
  WriteLn('');
  WriteLn('Found ', count, ' primes');
  
  // 字符串插值
  var msg := 'Running on Kylix ${version}!';
  WriteLn('');
  WriteLn(msg);
  WriteLn('');
  WriteLn('--- New Features ---');
  WriteLn('[x] LLVM native backend (--backend=llvm)');
  WriteLn('[x] WASI support (--wasi)');
  WriteLn('[x] Package registry (kylix publish)');
  WriteLn('[x] stdlib Phase 4 (jsonutil/regex/datetime)');
  WriteLn('[x] External function declarations');
  WriteLn('[x] HTTP client (stdlib/http_client)');
  WriteLn('[x] 23 complete-tutorial examples');
end.

运行结果:

复制代码
$ kylix run v3_showcase.klx
========================================
  Kylix v3.0.0-alpha Feature Showcase
========================================

Version:  3.0.0-alpha
Codename:  Architecture Breakthrough

--- Factorials 1-10 ---
1 ! =  1
2 ! =  2
3 ! =  6
4 ! =  24
5 ! =  120
6 ! =  720
7 ! =  5040
8 ! =  40320
9 ! =  362880
10 ! =  3628800

--- Primes under 30 ---
2 3 5 7 11 13 17 19 23 29 
Found  10  primes

Running on Kylix 3.0.0-alpha!

--- New Features ---
[x] LLVM native backend (--backend=llvm)
[x] WASI support (--wasi)
[x] Package registry (kylix publish)
[x] stdlib Phase 4 (jsonutil/regex/datetime)
[x] External function declarations
[x] HTTP client (stdlib/http_client)
[x] 23 complete-tutorial examples

示例 4:Dead Code Elimination(v2.6.0 特性,v3.0 测试仍通过)

复制代码
program DCEDemo;

function Foo(): Integer;
begin
  result := 42;
end;

function SafeDivide(a: Integer; b: Integer): Integer;
begin
  if b = 0 then
  begin
    raise Exception.Create('Division by zero');
  end;
  result := a div b;
end;

var
  i: Integer;
begin
  WriteLn('=== v2.6.0 DCE + v3.0.0 ===');
  for i := 0 to 10 do
    WriteLn('Fib(', i, ')');  // Exit/return/raise 后的代码会被消除
  
  try
    SafeDivide(10, 0);
  except
    on E: Exception do
      WriteLn('Caught: ', E.Message);
  end;
end.

九、也要指出的问题

9.1 DCE(死代码消除)已实现但未接入主编译管线

pkg/compiler/optimize.go 中的 OptimizeProgram 函数已经实现,5 个单元测试全部通过(包括 TestOptimize_DeadCodeAfterReturnTestOptimize_DeadCodeAfterRaiseTestOptimize_DeadCodeAfterExitTestOptimize_DeadCodeAfterBreakTestOptimize_NoDeadCode)。但当前 CompileFileCompileProject 尚未调用它。

这意味着 DCE 在测试层面已验证正确,但默认编译还不会触发。这是一个典型的"功能已就绪、只差最后接线"的状态,预计很快会在后续 alpha 或 beta 补丁中接入。

9.2 LLVM 后端 Milestone 1 的已知限制

如前文详细分析,LLVM 后端目前不支持接口、泛型、数组、record、异常、优化 Pass、多参数 WriteLn 等特性。这是 alpha 阶段的正常状态,但在撰写本文时必须明确指出:LLVM 后端目前适合编译计算密集型、逻辑简单的程序,不适合作为生产环境的主力后端。 Go 后端仍然是默认和推荐的编译目标。

9.3 examples 目录中部分示例与当前编译器不对齐

仓库中的 examples/modern.klxexamples/classes.klx 等旧示例仍有编译错误(lambda 多语句处理、类字段可见性等)。v3.0.0-alpha 新增的 examples/complete-tutorial/ 目录中的 20 个示例经过验证可以正常工作,但旧 examples 目录中的部分文件需要更新。

9.4 examples/ 包测试失败

go test ./...kylix/examples 包因 modern.klx 的语法错误而 build failed。这不影响核心编译器功能,但会导致全量测试不绿。建议在正式发布前清理或修复这些旧示例。


十、ROADMAP 前瞻:v3.1 要做什么

根据 ROADMAP.md,v3.1 的方向已经清晰:

LLVM 后端 Milestone 2

  • 接口 codegen(vtable / fat pointer)

  • 泛型单态化

  • LLVM 优化 Pass(-O2 / LTO)

  • 交叉编译支持(linux/windows/arm64)

包注册中心部署

  • 部署到 kylix.top/packages

  • 域名 + TLS + PostgreSQL 生产配置

  • 搜索索引优化

stdlib Phase 6

  • net 模块(TCP/UDP/DNS)

  • crypto 模块(hash/HMAC/AES)

  • encoding 模块(base64/hex/CSV)

可以看到,v3.1 的核心任务是把 v3.0.0-alpha 已经跑通的架构管道做深做厚:

  • • LLVM 后端从"Hello World 能跑"进化到"完整语言特性支持 + 优化"

  • • 注册中心从"代码写完"进化到"公网部署可用"

  • • 标准库从"纯 Kylix 基础模块"扩展到"网络/加密/编码"

这条路线非常清晰,而且完全建立在 v3.0.0-alpha 已交付的基础设施之上。


十一、总结:v3.0.0-alpha 是 Kylix 的"成人礼"

回望整个 Kylix 系列文章,我们见证了一门语言从 0 到 1 的全过程:

  • • v0.x:从无到有的 Lexer → Parser → Go 代码生成器

  • • v1.0:核心语言特性稳定,异常处理、多返回值、泛型落地

  • • v1.2:自举------Kylix 编译 Kylix,15/15 示例通过

  • • v2.0:工具链成型------test/bench/doc/LSP/fmt/repl 全到位

  • • v2.1-v2.5:体验打磨------类型系统、i18n、增量编译、LSP 重构、stdlib 自举

  • • v2.6:性能优化------并行编译、DCE、LSP 基准

  • v3.0.0-alpha架构突破------LLVM 原生后端、WASI、包注册中心、stdlib Phase 4

v3.0.0-alpha 不是一个完美的版本。它是一个 alpha。LLVM 后端有明显的 Milestone 限制,DCE 还没接线,旧示例还有编译错误。

但它是一个正确方向上的里程碑

它告诉我们:

    1. Kylix 不满足于做一个"Pascal → Go 转译器"。它要拥有自己独立的代码生成能力。33KB 原生二进制的对比数据,是这条路线最有力的证明。
    1. 自举叙事正在从编译器扩展到整个生态。编译器自举(v1.2)只是第一步。标准库自举(v2.1-v3.0 的 10 个纯 Kylix 模块、90+ 函数、117 个测试)才是更深层的自举------用自己的语言构建自己的基础设施。
    1. 架构设计是务实的。LLVM 后端选择文本 IR 而非 CGO 绑定,WASI 用 build tag 分离,jsonutil 解析纯 Kylix 实现而编码保留 external,包注册中心独立 module......这些都是在"做对的事"和"用可控的成本做"之间的理性权衡。
    1. 工程节奏依然稳健。从 v2.1 到 v3.0.0-alpha,每个版本都有明确的主题,每项功能都有测试,已知问题都诚实记录。没有"画大饼",没有"跳票"。

第二十四篇我们说:

v2.5.0 是 Kylix 对开发者日常体验的一次打磨。它不只是让语言"能用",而是让工具链开始变得"顺手"。

第二十五篇,可以这样接上:

v3.0.0-alpha 是 Kylix 对自己未来的一次下注。它不再只是"编译到 Go 的 Pascal",而是开始成为一个拥有多后端架构、独立代码生成能力、完整生态闭环的现代语言。

这是从"好用"到"强大"的跃迁。

Kylix 用 v2.x 系列证明了自己是一门认真的语言。

v3.0.0-alpha 则告诉我们:它的野心远不止于此。

从 Pascal 的清晰优雅出发,借 Go 的生态快速起步,用 LLVM 打开原生性能的大门,以 WASI 拥抱 WebAssembly 的未来,用注册中心编织生态之网。

Kylix 正在成为一门有自己灵魂的语言。而 v3.0.0-alpha,就是这条路上最关键的一步。


结尾:下一篇该看什么?

v3.0.0-alpha 已经架好了四大架构支柱,但每一根都还需要打磨。下一篇最值得关注的将是:

  • • LLVM 后端 Milestone 2 什么时候到来------接口、泛型、优化 Pass、交叉编译

  • • DCE 什么时候接入主编译管线(代码已就绪,只差接线)

  • • 包注册中心什么时候部署到公网 kylix.top/packages

  • • stdlib Phase 6(net/crypto/encoding)是否开始推进

  • • LLVM 后端的类支持什么时候完整(vtable + 虚函数分发端到端可用)

  • • 旧 examples 目录是否更新对齐当前编译器

第二十四篇结尾写的是:

现在它来到更难、更细、更长期的阶段:证明我能让开发者每天写得舒服。

今天,v3.0.0-alpha 给出了一个新的答案:

它不仅要让开发者写得舒服,还要给他们选择后端的自由、部署到任何平台的能力、以及一个真正生长的生态。

从自举到多后端,从工具链到生态,从 Go 运行时到 LLVM 原生代码------

Kylix 的 3.0 时代,才刚刚开始。