修复
This commit is contained in:
parent
2957541a0c
commit
a67ac422bc
@ -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,42 +133,36 @@ 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;
|
||||
@ -184,19 +171,19 @@ public final class BasicIRBuilder {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user