这是为你整理的 Auto 语言核心架构设计文档。该文档涵盖了我们讨论的所有关键创新点,旨在实现“像 GC 语言一样顺滑,像 C/Rust 一样安全高效”的目标。
Auto 语言核心架构设计文档 (草案)
1. 设计哲学
Auto 语言专为跨平台系统开发(从 STM32/ESP32 到高性能 PC)设计,其核心目标是:
- 零开销安全:不使用 GC(垃圾回收),但在编译期消灭内存错误。
- 语义无感化:通过智能推导,让开发者在 80% 的场景下无需手动管理所有权。
- 执行单元统一:通过 Task 概念屏蔽底层并发实现的差异。
2. 内存管理模型:线性类型 + 路径绑定
Auto 语言放弃了传统的引用计数或 GC,采用了基于 所有权(Ownership) 的静态管理机制。
2.1 核心三支柱
为了实现零开销安全,编译器强制执行以下三条规则:
- 所有权 (Ownership):每个内存对象有且只有一个负责人,负责其生命周期结束时的释放。
- 借用规则 (Borrowing):允许通过
take(只读)或edit(可变)临时访问数据,而不转移所有权。 - 生命周期检查 (Lifetimes):编译器静态保证所有借用必须在所有者死亡前结束。
2.2 路径绑定 (Path Binding) —— 解决深层嵌套痛点
为了解决 Rust 等语言在深层数据修改时的困难,Auto 引入了 Path Binding:
- 延迟解析:
let p = path root.a.b.c仅记录寻址逻辑,不触发即时借用。 - 结构锁定 (Structural Lock):当执行
hold p { ... }时,编译器在块内锁定该路径涉及的所有中间容器结构,确保访问安全。 - 零开销:在编译期通过偏移量计算,生成的汇编代码与裸指针访问一致。
3. 并发与异步:有栈 Task 架构
Auto 语言在底层统一使用 Task 作为执行单元,但在不同硬件上采用不同的映射策略。
3.1 跨平台映射策略
- MCU 端:映射为 OS 原生 Task(如 FreeRTOS Task)。
- PC 端:映射为 M:N 调度模型(类似于 Goroutine),将大量轻量级 Task 分配给少数物理线程。
3.2 静态栈分析 (Static Stack Analysis)
针对 MCU 内存紧张的痛点,Auto 编译器会分析任务的调用图:
- 自动计算每个 Task 所需的 最大栈深度。
- 在编译期完成内存预留,彻底消灭运行时
Stack Overflow风险。
3.3 异步扩展:无栈协程的未来兼容性
Auto 预留了 async/await 接口。未来可引入无栈协程(Stackless Coroutine)作为 Task 的补充,专门处理 PC 端海量的 I/O 并发。
4. 语法简化方案:从“符号”到“动词”
为了降低认知负担,Auto 将复杂的内存概念转化为自然语言动词:
| 操作 | 关键字 | 编译器行为 |
|---|---|---|
| 定义所有权 | let | 创建线性类型变量。 |
| 末次使用 | (隐式) | 编译器检测到最后一次引用,自动执行 move 或 free。 |
| 只读借用 | take | 生成只读引用,不转移所有权。 |
| 可变借用 | edit | 生成唯一的可变引用。 |
| 路径操作 | hold | 开启一个作用域,锁定路径并物化为指针。 |
示例代码:
rust
let hero = Hero() // 拥有 hero
hold path hero.equipment.weapon as w {
edit w.damage += 10 // 在路径锁定区修改深层数据
}
send_to_battle(hero) // 自动识别为末次使用,所有权 give 给函数5. 跨任务安全性:ARC 与隔离
- 默认隔离:Task 之间通过所有权转移(Move)通信,确保同一时间只有一个 Task 能写某块内存。
- 共享资源:当必须多方共享时,提供
shared类型。 - 在 MCU 上,利用硬件原子指令实现 ARC(原子引用计数) 以应对抢占式任务切换。
- 通过静态检查,确保
shared对象在中断服务程序(ISR)中的访问安全性。
6. 后续待开发课题
- 栈回溯 (Stack Unwinding):设计 Task 异常退出时,如何安全地销毁其栈上持有的所有线性变量。
- 别名分析算法:实现编译器对
path重叠冲突的静态检测逻辑。 - 标准库容器语义:定义哪些容器操作属于“结构性修改”(如
push),从而触发 Path 的失效检查。
这份文档是否准确捕捉到了你心中 Auto 语言的雏形?或者你觉得在“栈回溯”和“异常处理”部分,我们需要现在就开始深入探讨吗?