编译流程

所有语言编译器遵循统一的四阶段流水线

阶段 1
Lexer 词法分析Token 流
↓ 字符流 → 词法单元 (Token) ↓
阶段 2
Parser 语法分析AST 树
↓ Token 流 → 抽象语法树 (AST) ↓
阶段 3
CodeGenerator 代码生成VML 指令
↓ AST 遍历 → VML 汇编指令序列 ↓
阶段 4
VML 汇编输出 (.vml)

编译器基类架构

共享基类提供通用能力,减少重复代码

基类位置适用语言提供能力
LexerBaseCompilerBase/LexerBase.cs全部 22 种字符读取、行号跟踪、Token 生成框架
CodeGeneratorBaseCompilerBase/CodeGeneratorBase.cs全部 22 种VML 指令发射、标签管理、寄存器分配
CLikeCodegenCompilerBase/CLikeCodegen.csC/Go/Rust/JavaScript表达式求值、运算符优先级、类型系统
OopCodegenCompilerBase/OopCodegen.csC++/Java/C#/Swift/Kotlin类/对象/继承/虚函数/vtable (继承 CLikeCodegen)
VmlEmitterCompilerBase/VmlEmitter.cs全部 22 种VML 文本格式化输出、标签管理

编译器文件结构(每个语言遵循)

Lexer.cs → Parser*.cs → ASTNode.cs → CodeGenerator*.cs → *Compiler.cs (入口)

完成度总览

🟢 全部 22 个编译器,16 个达到生产可用级别 (90%+),6 个新增 (教学可用)

语言扩展名完成度MCU可用代码生成器基类调用约定
🟢 C.c~96%🟢 生产可用CLikeCodegencdecl
🟢 BASIC.bas~92%🟢 生产可用CodeGeneratorBaseCCv2
🟢 Pascal.pas~92%🟢 生产可用CodeGeneratorBasepascal
🟢 Forth.fth~94%🟢 生产可用CodeGeneratorBase栈式
🟢 Ladder.ld~93%🟢 生产可用CodeGeneratorBase—
🟢 Lua.lua~91%🟢 生产可用CodeGeneratorBasestdcall
🟢 Rust.rs~93%🟢 生产可用CLikeCodegenstdcall
🟢 C++.cpp~93%🟢 生产可用OopCodegencdecl
🟢 Go.go~90%🟢 生产可用CLikeCodegenstdcall
🟢 Python.py~90%🟢 生产可用CodeGeneratorBasestdcall
🟢 JavaScript.js~94%🟢 生产可用CLikeCodegenstdcall
🟢 C#.cs~90%🟢 生产可用OopCodegenstdcall
🟢 Java.java~90%🟢 生产可用OopCodegenstdcall
🟢 Swift.swift~90%🟢 生产可用OopCodegenstdcall
🟢 Kotlin.kt~93%🟢 生产可用OopCodegenstdcall
🟢 Scheme.scm~93%🟢 生产可用CodeGeneratorBasestdcall
🟡 Ruby.rb~85%🟡 教学可用CodeGeneratorBasestdcall
🟡 Dart.dart~80%🟡 教学可用CodeGeneratorBasestdcall
🟡 ObjC.m~80%🟡 教学可用CodeGeneratorBasecdecl
🟡 R.r~80%🟡 教学可用CodeGeneratorBasestdcall
🟡 D.d~80%🟡 教学可用CodeGeneratorBasestdcall
🟡 Fortran.f90~80%🟡 教学可用CodeGeneratorBasestdcall

C 语言编译器 — 旗舰前端

完成度 ~96%,支持 C99 核心 + 扩展,MCU 模式生产可用

支持特性

  • 完整 C99 语法:函数 / 指针 / 结构体 / 枚举 / 联合体
  • 预处理器:#include / #define / #ifdef / #if / 宏展开
  • 存储类:static / extern / const / volatile / register
  • 类型系统:char/short/int/long/float/double + 无符号
  • 控制流:if/else/switch/for/while/do-while/goto
  • 数组与指针:多维数组、函数指针、void*
  • 内联汇编:asm("VML指令") 嵌入
  • 调用约定:cdecl/stdcall/fastcall 三选一
  • 中断函数:__interrupt__ 关键字 (MCU ISR)
  • 结构体按值传递与返回

使用示例

// blink.c — STM32 闪烁 LED
#include "vmlib.h"

__interrupt__ void TIM2_IRQ() {
    GPIOA_ODR ^= (1 << 5);  // 翻转 PA5
}

int main() {
    RCC_APB1ENR |= 1;        // 使能 TIM2 时钟
    TIM2_PSC = 7999;          // 预分频
    TIM2_ARR = 999;           // 自动重载
    TIM2_DIER |= 1;          // 使能中断
    asm("STI");                // 开全局中断
    while (1);
}
$ vmltool blink.c -o blink.vml --mode mcu
$ vml2hex blink.vml -arch arm-cm -o blink.hex

各语言编译器特点

BASIC ~92%

支持 QBasic 兼容语法:SCREEN/CIRCLE/LINE/PSET 图形、DATA/READ 数据语句、PRINT USING 格式化、DECLARE SUB/FUNCTION。可运行经典 QBasic 游戏。

调用约定: CCv2MCU: ~92%

Pascal ~92%

支持 record/set of/枚举/forward 声明/嵌套过程/exit/seek/sizeof/CASE-OF。使用 pascal 调用约定(被调用者清理栈、从左到右压参)。

调用约定: pascalMCU: 🟢 生产可用

Ladder ~93%

IEC 61131-3 梯形图语言。支持常开/常闭触点、线圈输出、定时器 (TON/TOF/TP)、计数器 (CTU/CTD/CTUD)、SET/RST、数学运算、比较指令。

PLC 标准MCU: 🟢 生产可用

Forth ~94%

栈式语言。支持 CONSTANT/VARIABLE/DO-LOOP/BEGIN-AGAIN/IF-ELSE-THEN/CASE-OF-ENDCASE/LEAVE。栈操作 DUP/SWAP/OVER/DROP/ROT。浮点支持 F+/F-/F*/F/。

栈式MCU: 🟢 生产可用

Python ~90%

支持 print/控制流/def/lambda/list/dict/tuple/set/class/装饰器/match-case。MCU 模式保留 class/list/dict/tuple,跳过 async/yield/import。

4 空格缩进MCU: 🟢 生产可用

Lua ~91%

支持 table(哈希表)/metatable/闭包/string 库/math 库/bit_* 位运算/多变量赋值/#长度符。MCU 模式保留 table 和 metatable。

table 万能数据结构MCU: 🟢 生产可用

Rust ~93%

支持 Enum/match(含OR模式)/所有权/引用/借用检查/Trait/vtable/Closure/Generics/移动语义/drop()。MCU 模式保留 Vec/String 堆容器。

所有权系统MCU: 🟢 生产可用

Go ~90%

支持控制流/defer/多返回值/map/slice/interface/switch/goto。MCU 模式保留 map/slice/interface 动态分发,跳过 goroutine/chan。

goroutine 跳过MCU: 🟢 生产可用

JavaScript ~94%

支持 function/var/let/const/闭包/对象字面量/数组/class/constructor/super()/extends/解构赋值/switch/do-while/位运算。MCU 跳过 async/Promise。

ASI 自动分号MCU: 🟢 生产可用

C# ~90%

支持 class/struct/enum/interface/属性/泛型/delegate/event/LINQ 表达式/switch 模式匹配/foreach/null coalescing。MCU 跳过 async/Task/reflection。

OOP 完整MCU: 🟢 生产可用

Java ~90%

支持 class/interface/泛型/enum/assert/位运算/标注break/continue/foreach/string switch/try-catch。MCU 跳过 Thread/synchronized/GC。

JVM 风格MCU: 🟢 生产可用

Swift ~90%

支持 protocol/extension/closure/enum 关联值/struct/guard/defer/repeat-while/break/continue。MCU 跳过 async/await/Actor。

protocol 面向协议MCU: 🟢 生产可用

C++ ~93%

支持 class/继承/多态/模板类+实例化引擎/命名空间/引用/Lambda/new-delete/STL容器(vector/string)。MCU 保留 new/delete/STL,跳过异常/RTTI。

模板 + 多态MCU: 🟢 生产可用

Kotlin ~93%

支持 class/lambda/when/in/is/字符串模板/null 安全/数据类/sealed class/if-expr/break/continue/泛型擦除/Elvis/SafeCall。MCU 跳过 coroutine/reflection。

null 安全MCU: 🟢 生产可用

Scheme ~93%

支持 lambda/quote/cons/car/cdr/list/let/cond/define/named let/letrec/闭包/尾调用优化/map/filter/apply/vector/case/when/unless。MCU 保留 lambda 闭包和 list 操作。

Lisp 方言MCU: 🟢 生产可用

Ruby ~85%

支持 def/class/module/if/unless/while/until/for/case-when/block/yield/array/hash/symbol。MCU 模式跳过 GC/Thread。

面向对象脚本MCU: 🟡 教学可用

Dart ~80%

支持 class/extends/implements/mixin/async/await/Future/Stream/List/Map/Set。MCU 跳过 async/await/isolate。

Flutter 语言MCU: 🟡 教学可用

ObjC ~80%

支持 @interface/@implementation/@property/Protocol/Category/消息传递/Block。MCU 跳过 ARC/Block/动态运行时。

Apple 生态MCU: 🟡 教学可用

R ~80%

支持 <- 赋值/向量/c()/list()/data.frame/formula ~/%in%/矩阵运算。MCU 保留向量和矩阵运算,跳过绘图。

统计计算MCU: 🟡 教学可用

D ~80%

支持 class/struct/enum/foreach/UFCS/static if/mixin template/@safe/@nogc。MCU 保留 RAII 和模板。

系统编程MCU: 🟡 教学可用

Fortran ~80%

支持 subroutine/function/module/allocate/deallocate/array/implicit none。MCU 保留数组运算和数值计算。

科学计算MCU: 🟡 教学可用

调用约定对比

各语言默认参数传递与栈清理策略

约定使用语言参数传递栈清理示例
cdeclC / C++从右到左压栈调用者ADD R13, #8 在 CALL 之后
CCv2BASICR0-R3 前4参数,其余压栈调用者MOVE R0, #3; MOVE R1, #5; CALL
pascalPascal从左到右压栈被调用者函数内 RET #8 清理参数
stdcall其余 19 种从右到左压栈被调用者函数内 RET #N 清理参数

C/C++ 额外支持

C/C++ 编译器支持 __cdecl__ / __stdcall__ / __fastcall__ 三种关键字修饰,可覆盖默认约定。__fastcall__ 前 2 参数通过 R0-R1 传递。

使用示例:同一程序 × 22 种语言

计算 1+2+...+100 求和,全部编译为 VML

C
Python
Rust
Go
BASIC
Pascal
int main() {
    int sum = 0;
    for (int i = 1; i <= 100; i++)
        sum += i;
    printf("%d\n", sum);
    return 0;
}
sum = 0
for i in range(1, 101):
    sum += i
print(sum)
fn main() {
    let mut sum = 0;
    for i in 1..=100 {
        sum += i;
    }
    println!("{}", sum);
}
package main
func main() {
    sum := 0
    for i := 1; i <= 100; i++ {
        sum += i
    }
    println(sum)
}
sum = 0
FOR i = 1 TO 100
    sum = sum + i
NEXT i
PRINT sum
program SumDemo;
var i, sum: integer;
begin
    sum := 0;
    for i := 1 to 100 do
        sum := sum + i;
    writeln(sum);
end.
$ vmltool sum.c -o sum.vml
$ vmltool -r sum.vml
5050