This commit is contained in:
Luke 2025-04-29 15:03:13 +08:00
parent 2957541a0c
commit a67ac422bc

View File

@ -1,6 +1,9 @@
package org.jcnc.snow.compiler.ir;
import org.jcnc.snow.compiler.ir.instr.*;
import org.jcnc.snow.compiler.ir.instr.BinOpInstruction;
import org.jcnc.snow.compiler.ir.instr.IRFunction;
import org.jcnc.snow.compiler.ir.instr.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.instr.ReturnInstruction;
import org.jcnc.snow.compiler.parser.ast.*;
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
import org.jcnc.snow.compiler.parser.ast.base.Node;
@ -11,128 +14,118 @@ import java.util.List;
import java.util.Map;
/**
* BasicIRBuilder AST抽象语法树转换为 IR中间表示
* BasicIRBuilder 负责 AST抽象语法树转换为 IR中间表示
* <p>
* 支持功能
* 支持的功能包括
* <ul>
* <li>模块Module到函数Function到语句Statement到表达式Expression的递归编译</li>
* <li>整数字面量变量标识符四则运算+ - * /的表达式处理</li>
* <li>变量声明赋值返回return语句的处理</li>
* </ul>
* <p>
* - 整棵模块Module到函数Function到语句Statement到表达式Expression的递归编译
* <p>
* - 支持整数字面量标识符四则运算+ - * /
* <p>
* - 支持变量声明赋值return 语句
* 注意
* - 当前仅支持简单语言特性
* - 变量采用虚拟寄存器VirtualRegister建模未来可扩展 SSA
*/
public final class BasicIRBuilder {
/* ───────────────── 顶层 API ───────────────── */
/**
* 将一组顶层 AST 节点可能是模块函数或语句转换成 IRProgram
* 当前作用域中变量名 -> 虚拟寄存器VirtualRegister的映射
*/
private final Map<String, VirtualRegister> variables = new HashMap<>();
/* ───────────────── 内部实现 ───────────────── */
/**
* 当前正在构建的 IRFunction 实例
*/
private IRFunction currentFn;
/**
* 将一组顶层 AST 节点模块函数语句编译为 IRProgram
*
* @param roots AST 根节点列表
* @return 构建好的 IRProgram
* @return 编译生成的 IRProgram 对象
*/
public IRProgram buildProgram(List<Node> roots) {
IRProgram prog = new IRProgram();
for (Node n : roots) dispatchTop(n, prog);
IRProgram prog = new IRProgram(); // 创建新的 IRProgram
for (Node n : roots) dispatchTop(n, prog); // 依次处理所有顶层节点
return prog;
}
/* ───────────────── 内部实现 ───────────────── */
/* ─────────────── 函数体级别状态 ─────────────── */
/**
* 处理一个顶层节点可能是模块函数或单条语句
* 处理单个顶层节点
* 可能是模块ModuleNode函数FunctionNode单条语句StatementNode
*
* @param n AST 节点
* @param n AST 顶层节点
* @param prog 正在构建的 IRProgram
*/
private void dispatchTop(Node n, IRProgram prog) {
switch (n) {
/* module { fun* }:递归处理模块内的所有函数 */
case ModuleNode m -> m.functions().forEach(f -> dispatchTop(f, prog));
/* fun foo(...) { stmts }:构建单个函数 */
case FunctionNode f -> prog.add(buildFunction(f));
/* 单条语句:作为匿名 "main" 函数处理 */
case StatementNode s -> {
case ModuleNode m -> m.functions().forEach(f -> dispatchTop(f, prog)); // 递归处理模块内的函数
case FunctionNode f -> prog.add(buildFunction(f)); // 将函数编译成 IRFunction 并加入 IRProgram
case StatementNode s -> { // 单条语句如脚本式 main
FunctionNode fake = new FunctionNode("main", List.of(), "void", List.of(s));
prog.add(buildFunction(fake));
}
default -> throw new IllegalStateException("Unsupported top-level node: " + n);
}
}
/**
* FunctionNode 转换为 IRFunction
* 一个 FunctionNode 编译成 IRFunction
*
* @param fn AST 中的函数节点
* @return 转换后 IRFunction
* @return 生成 IRFunction
*/
private IRFunction buildFunction(FunctionNode fn) {
currentFn = new IRFunction(fn.name());
variables.clear();
currentFn = new IRFunction(fn.name()); // 创建新 IRFunction
variables.clear(); // 清空变量表每个函数独立
/* 将函数参数映射为虚拟寄存器(目前未在其他地方使用,但保留未来支持) */
// 将函数参数映射为新的寄存器未进一步使用参数但保留未来拓展空间
for (ParameterNode p : fn.parameters()) {
variables.put(p.name(), currentFn.newRegister());
}
/* 编译函数体中的每条语句 */
// 编译函数体中的每条语句
for (StatementNode stmt : fn.body()) stmt(stmt);
/* 如果没有显式 return补一个无返回值的 RET 指令 */
if (currentFn.body().isEmpty() ||
!(currentFn.body().getLast() instanceof ReturnInstruction))
// 如果函数末尾没有 return自动添加一个 return无返回值
if (currentFn.body().isEmpty() || !(currentFn.body().getLast() instanceof ReturnInstruction))
currentFn.add(new ReturnInstruction(null));
return currentFn;
}
/* ─────────────── 函数体级别状态 ─────────────── */
/** 当前正在构建的 IRFunction 对象 */
private IRFunction currentFn;
/** 当前作用域内变量名到虚拟寄存器的映射表 */
private final Map<String, VirtualRegister> variables = new HashMap<>();
/* ─── 处理语句 ─── */
/**
* 将一个语句节点编译 IR 指令
* 编译单个语句节点为 IR 指令
*
* @param n AST 语句节点
* @param n 语句 AST 节点
*/
private void stmt(StatementNode n) {
switch (n) {
/* 表达式语句:只编译表达式,结果不保存 */
case ExpressionStatementNode es -> expr(es.expression());
/* 赋值语句:编译右值表达式,并更新变量表 */
case AssignmentNode as -> {
case ExpressionStatementNode es -> expr(es.expression()); // 表达式语句只求值无需保存
case AssignmentNode as -> { // 赋值语句
VirtualRegister rhs = expr(as.value());
variables.put(as.variable(), rhs);
}
/* 变量声明:可带初始化器 */
case DeclarationNode d -> {
if (d.getInitializer().isPresent()) {
case DeclarationNode d -> { // 变量声明
if (d.getInitializer().isPresent()) { // 有初始化器
VirtualRegister init = expr(d.getInitializer().get());
variables.put(d.getName(), init);
} else {
} else { // 无初始化器分配空寄存器
variables.put(d.getName(), currentFn.newRegister());
}
}
/* return 语句:可带返回值也可以没有 */
case ReturnNode r -> {
if (r.getExpression().isPresent())
currentFn.add(new ReturnInstruction(expr(r.getExpression().get())));
else
currentFn.add(new ReturnInstruction(null));
case ReturnNode r -> { // 返回语句
if (r.getExpression().isPresent()) currentFn.add(new ReturnInstruction(expr(r.getExpression().get())));
else currentFn.add(new ReturnInstruction(null));
}
default -> throw new IllegalStateException("Unsupported stmt: " + n);
}
}
@ -140,63 +133,57 @@ public final class BasicIRBuilder {
/* ─── 处理表达式 ─── */
/**
* 将一个表达式节点编译为虚拟寄存器中的值
* 编译单个表达式节点结果保存在一个新的寄存器中
*
* @param e AST 表达式节点
* @return 保存表达式结果的虚拟寄存器
* @param e 表达式 AST 节点
* @return 保存结果的虚拟寄存器
*/
private VirtualRegister expr(ExpressionNode e) {
return switch (e) {
/* 二元运算 */
case BinaryExpressionNode b -> bin(b);
/* 数字字面量 */
case NumberLiteralNode n -> number(n);
/* 变量标识符 */
case IdentifierNode id -> {
case BinaryExpressionNode b -> bin(b); // 二元运算
case NumberLiteralNode n -> number(n); // 数字字面量
case IdentifierNode id -> { // 变量引用
VirtualRegister v = variables.get(id.name());
if (v == null) throw new IllegalStateException("变量 " + id.name() + " 未定义");
yield v;
}
default -> throw new IllegalStateException("Unsupported expr: " + e);
};
}
/**
* 处理二元表达式加减乘除
* 编译一个二元运算表达式加减乘除
*
* @param b AST 二元表达式节点
* @return 保存运算结果的寄存器
* @param b 二元表达式节点
* @return 保存结果的寄存器
*/
private VirtualRegister bin(BinaryExpressionNode b) {
VirtualRegister l = expr(b.left()); // 左操作数
VirtualRegister r = expr(b.right()); // 右操作数
VirtualRegister d = currentFn.newRegister(); // 保存结果
VirtualRegister d = currentFn.newRegister(); // 结果寄存器
/* 映射操作符到 IROp */
// 选择对应的 IR 操作符
IROp op = switch (b.operator()) {
case "+" -> IROp.ADD_I32;
case "-" -> IROp.SUB_I32;
case "*" -> IROp.MUL_I32;
case "/" -> IROp.DIV_I32;
default -> throw new IllegalStateException("未知运算符 " + b.operator());
default -> throw new IllegalStateException("未知运算符 " + b.operator());
};
currentFn.add(new BinOpInstruction(op, d, l, r));
currentFn.add(new BinOpInstruction(op, d, l, r)); // 添加二元运算指令
return d;
}
/**
* 处理整数字面量
* 编译一个整数字面量
*
* @param n AST 数字字面量节点
* @param n 数字字面量节点
* @return 保存常量的寄存器
*/
private VirtualRegister number(NumberLiteralNode n) {
VirtualRegister d = currentFn.newRegister();
currentFn.add(new LoadConstInstruction(d, new Constant(Integer.parseInt(n.value()))));
VirtualRegister d = currentFn.newRegister(); // 分配一个新的寄存器
currentFn.add(new LoadConstInstruction(d, new Constant(Integer.parseInt(n.value())))); // 加载常量指令
return d;
}
}