← 返回目录

第一章:语言与编译器全景

从 MiniLang 的第一段程序出发,理解源码如何经过 Token、AST、IR、字节码并在虚拟机中执行。

1. 我们要实现什么

编译器不是神秘黑盒。这个系列会用 TypeScript 实现一条完整流水线:源码先变成 Token,再被 Parser 组织成 AST,经过语义检查后降低为 IR,最后生成字节码并交给虚拟机执行。

MiniLang 的目标很小:变量、表达式、if、while、函数和块级作用域。范围小,才能把编译器每一层讲清楚。

let total: number = 0;
let i: number = 1;

while (i <= 3) {
  total = total + i;
  i = i + 1;
}

print(total);

2. 编译流水线

一条实用流水线可以拆成五个稳定边界。Lexer 只关心字符如何组成 Token;Parser 只关心 Token 如何组成 AST;语义阶段检查名称和类型;IR 让控制流更明确;字节码让虚拟机能逐条执行。

type PipelineResult = {
  tokens: Token[];
  ast: Program;
  ir: IRFunction[];
  bytecode: Instruction[];
};

function compile(source: string): PipelineResult {
  const tokens = new Lexer(source).scanTokens();
  const ast = new Parser(tokens).parseProgram();
  const checked = new TypeChecker().check(ast);
  const ir = lowerToIR(checked);
  const bytecode = emitBytecode(ir);
  return { tokens, ast: checked, ir, bytecode };
}
返回目录 下一章:词法分析 Lexer