This commit is contained in:
Luke 2025-05-06 22:03:20 +08:00
parent f886933d7c
commit e6bf9ecd12
5 changed files with 307 additions and 195 deletions

View File

@ -1,193 +0,0 @@
package org.jcnc.snow.compiler.builder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.core.IROp;
import org.jcnc.snow.compiler.ir.core.IRProgram;
import org.jcnc.snow.compiler.ir.instr.BinOpInstruction;
import org.jcnc.snow.compiler.ir.instr.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.instr.ReturnInstruction;
import org.jcnc.snow.compiler.ir.value.Constant;
import org.jcnc.snow.compiler.ir.value.VirtualRegister;
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;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* BasicIRBuilder 负责将 AST抽象语法树转换为 IR中间表示
* <p>
* 支持的功能包括
* <ul>
* <li>模块Module到函数Function到语句Statement到表达式Expression的递归编译</li>
* <li>整数字面量变量标识符四则运算+ - * /的表达式处理</li>
* <li>变量声明赋值返回return语句的处理</li>
* </ul>
* <p>
* 注意
* - 当前仅支持简单语言特性
* - 变量采用虚拟寄存器VirtualRegister建模未来可扩展 SSA
*/
public final class BasicIRBuilder {
/* ───────────────── 顶层 API ───────────────── */
/**
* 当前作用域中变量名 -> 虚拟寄存器VirtualRegister的映射
*/
private final Map<String, VirtualRegister> variables = new HashMap<>();
/* ───────────────── 内部实现 ───────────────── */
/**
* 当前正在构建的 IRFunction 实例
*/
private IRFunction currentFn;
/**
* 将一组顶层 AST 节点模块函数语句编译为 IRProgram
*
* @param roots AST 根节点列表
* @return 编译生成的 IRProgram 对象
*/
public IRProgram buildProgram(List<Node> roots) {
IRProgram prog = new IRProgram(); // 创建新的 IRProgram
for (Node node : roots) dispatchTop(node, prog); // 依次处理所有顶层节点
return prog;
}
/* ─────────────── 函数体级别状态 ─────────────── */
/**
* 处理单个顶层节点
* 可能是模块ModuleNode函数FunctionNode单条语句StatementNode
*
* @param node AST 顶层节点
* @param irProgram 正在构建的 IRProgram
*/
private void dispatchTop(Node node, IRProgram irProgram) {
switch (node) {
case ModuleNode moduleNode ->
moduleNode.functions().forEach(functionNode -> dispatchTop(functionNode, irProgram)); // 递归处理模块内的函数
case FunctionNode functionNode ->
irProgram.add(buildFunction(functionNode)); // 将函数编译成 IRFunction 并加入 IRProgram
case StatementNode _ -> {
//TODO 单条语句如脚本式 main
}
default -> throw new IllegalStateException("不支持的顶级节点: " + node);
}
}
/**
* 将一个 FunctionNode 编译成 IRFunction
*
* @param functionNode AST 中的函数节点
* @return 生成的 IRFunction
*/
private IRFunction buildFunction(FunctionNode functionNode) {
currentFn = new IRFunction(functionNode.name()); // 创建新 IRFunction
variables.clear(); // 清空变量表每个函数独立
// 将函数参数映射为新的寄存器未进一步使用参数但保留未来拓展空间
for (ParameterNode parameterNode : functionNode.parameters()) {
variables.put(parameterNode.name(), currentFn.newRegister());
}
// 编译函数体中的每条语句
for (StatementNode statementNode : functionNode.body()) stmt(statementNode);
return currentFn;
}
/* ─── 处理语句 ─── */
/**
* 编译单个语句节点为 IR 指令
*
* @param statementNode 语句 AST 节点
*/
private void stmt(StatementNode statementNode) {
switch (statementNode) {
case ExpressionStatementNode expressionStatementNode ->
expr(expressionStatementNode.expression()); // 表达式语句只求值无需保存
case AssignmentNode assignmentNode -> { // 赋值语句
VirtualRegister virtualRegister = expr(assignmentNode.value());
variables.put(assignmentNode.variable(), virtualRegister);
}
case DeclarationNode declarationNode -> { // 变量声明
if (declarationNode.getInitializer().isPresent()) { // 有初始化器
VirtualRegister virtualRegister = expr(declarationNode.getInitializer().get());
variables.put(declarationNode.getName(), virtualRegister);
} else { // 无初始化器分配空寄存器
variables.put(declarationNode.getName(), currentFn.newRegister());
}
}
case ReturnNode returnNode -> { // 返回语句
if (returnNode.getExpression().isPresent())
currentFn.add(new ReturnInstruction(expr(returnNode.getExpression().get())));
else currentFn.add(new ReturnInstruction(null));
}
default -> throw new IllegalStateException("不支持的语句: " + statementNode);
}
}
/* ─── 处理表达式 ─── */
/**
* 编译单个表达式节点结果保存在一个新的寄存器中
*
* @param expressionNode 表达式 AST 节点
* @return 保存结果的虚拟寄存器
*/
private VirtualRegister expr(ExpressionNode expressionNode) {
return switch (expressionNode) {
case BinaryExpressionNode binaryExpressionNode -> bin(binaryExpressionNode); // 二元运算
case NumberLiteralNode numberLiteralNode -> number(numberLiteralNode); // 数字字面量
case IdentifierNode identifierNode -> { // 变量引用
VirtualRegister virtualRegister = variables.get(identifierNode.name());
if (virtualRegister == null)
throw new IllegalStateException("变量 " + identifierNode.name() + " 未定义");
yield virtualRegister;
}
default -> throw new IllegalStateException("不支持的表达式: " + expressionNode);
};
}
/**
* 二元运算表达式如加减乘除
*
* @param b 二元表达式节点
* @return 保存结果的寄存器
*/
private VirtualRegister bin(BinaryExpressionNode b) {
VirtualRegister l = expr(b.left()); // 左操作数
VirtualRegister r = expr(b.right()); // 右操作数
VirtualRegister d = currentFn.newRegister(); // 结果寄存器
// 选择对应的 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());
};
currentFn.add(new BinOpInstruction(op, d, l, r)); // 添加二元运算指令
return d;
}
/**
* 编译一个整数字面量
*
* @param numberLiteralNode 数字字面量节点
* @return 保存常量的寄存器
*/
private VirtualRegister number(NumberLiteralNode numberLiteralNode) {
VirtualRegister virtualRegister = currentFn.newRegister(); // 分配一个新的寄存器
currentFn.add(new LoadConstInstruction(virtualRegister, new Constant(Integer.parseInt(numberLiteralNode.value())))); // 加载常量指令
return virtualRegister;
}
}

View File

@ -1,6 +1,6 @@
package org.jcnc.snow.compiler.cli; package org.jcnc.snow.compiler.cli;
import org.jcnc.snow.compiler.builder.BasicIRBuilder; import org.jcnc.snow.compiler.ir.builder.ProgramBuilder;
import org.jcnc.snow.compiler.ir.core.IRProgram; import org.jcnc.snow.compiler.ir.core.IRProgram;
import org.jcnc.snow.compiler.lexer.core.LexerEngine; import org.jcnc.snow.compiler.lexer.core.LexerEngine;
import org.jcnc.snow.compiler.lexer.token.Token; import org.jcnc.snow.compiler.lexer.token.Token;
@ -50,10 +50,11 @@ public class SnowCompiler {
SemanticAnalyzerRunner.runSemanticAnalysis(ast, false); SemanticAnalyzerRunner.runSemanticAnalysis(ast, false);
/* 4. AST → IRProgram */ /* 4. AST → IRProgram */
IRProgram program = new BasicIRBuilder().buildProgram(ast); IRProgram program = new ProgramBuilder().buildProgram(ast);
System.out.println("=== IR ==="); System.out.println("=== IR ===");
System.out.println(program); System.out.println(program);
/* 5. 后端:寄存器分配 & 代码生成 + VM 执行 */ /* 5. 后端:寄存器分配 & 代码生成 + VM 执行 */
// for (IRFunction fn : program.functions()) { // for (IRFunction fn : program.functions()) {
// var alloc = new RegisterAllocator(); // var alloc = new RegisterAllocator();

View File

@ -0,0 +1,145 @@
package org.jcnc.snow.compiler.ir.builder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.core.IROp;
import org.jcnc.snow.compiler.ir.instr.BinOpInstruction;
import org.jcnc.snow.compiler.ir.instr.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.instr.ReturnInstruction;
import org.jcnc.snow.compiler.ir.value.Constant;
import org.jcnc.snow.compiler.ir.value.VirtualRegister;
import org.jcnc.snow.compiler.parser.ast.*;
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
/**
* FunctionBuilder 负责将 AST 中的 FunctionNode 构建为 IRFunction
*
* <p>构建流程
* <ol>
* <li>创建 IRFunction 并绑定到作用域</li>
* <li>将函数参数声明为虚拟寄存器</li>
* <li>遍历函数体中的语句生成对应的 IR 指令</li>
* </ol>
*/
final class FunctionBuilder {
/** 当前正在构建的 IRFunction 实例 */
private IRFunction fn;
/** 管理变量名到虚拟寄存器的映射 */
private final Scope scope = new Scope();
/**
* 将给定的 FunctionNode 转换为 IRFunction
*
* @param node 要转换的函数节点
* @return 构建完成的 IRFunction
*/
IRFunction build(FunctionNode node) {
fn = new IRFunction(node.name());
scope.attachFunction(fn);
for (ParameterNode p : node.parameters()) {
scope.declare(p.name());
}
for (StatementNode s : node.body()) {
stmt(s);
}
return fn;
}
/**
* 处理不同类型的语句节点并生成相应的 IR 指令
*
* @param s 要处理的语句节点
*/
private void stmt(StatementNode s) {
switch (s) {
case ExpressionStatementNode(ExpressionNode expression) ->
// 处理表达式语句无需保存结果
expr(expression);
case AssignmentNode(String variable, ExpressionNode value) -> {
// 处理赋值语句计算右侧表达式并赋值
VirtualRegister result = expr(value);
if (scope.lookup(variable) == null) {
scope.declare(variable, result);
} else {
scope.put(variable, result);
}
}
case DeclarationNode d -> {
// 处理声明语句可能带初始化
if (d.getInitializer().isPresent()) {
scope.declare(d.getName(), expr(d.getInitializer().get()));
} else {
scope.declare(d.getName());
}
}
case ReturnNode r -> {
// 处理返回语句区分是否带返回值
if (r.getExpression().isPresent()) {
fn.add(new ReturnInstruction(expr(r.getExpression().get())));
} else {
fn.add(new ReturnInstruction(null));
}
}
case null, default -> throw new IllegalStateException("Unsupported statement: " + s);
}
}
/**
* 根据表达式类型生成对应的 IR 并返回结果寄存器
*
* @param e 要处理的表达式节点
* @return 存放表达式结果的虚拟寄存器
*/
private VirtualRegister expr(ExpressionNode e) {
if (e instanceof NumberLiteralNode num) {
return number(num);
} else if (e instanceof IdentifierNode(String name)) {
// 处理变量引用从作用域获取寄存器
VirtualRegister vr = scope.lookup(name);
if (vr == null) {
throw new IllegalStateException("Undefined variable " + name);
}
return vr;
} else if (e instanceof BinaryExpressionNode bin) {
return bin(bin);
}
throw new IllegalStateException("Unsupported expression: " + e);
}
/**
* 生成加载数值常量的指令
*
* @param n 数字字面量节点
* @return 存放常量的虚拟寄存器
*/
private VirtualRegister number(NumberLiteralNode n) {
VirtualRegister vr = fn.newRegister();
fn.add(new LoadConstInstruction(vr, new Constant(Integer.parseInt(n.value()))));
return vr;
}
/**
* 生成二元运算指令并返回结果寄存器
*
* @param b 二元表达式节点
* @return 存放运算结果的虚拟寄存器
*/
private VirtualRegister bin(BinaryExpressionNode b) {
VirtualRegister l = expr(b.left());
VirtualRegister r = expr(b.right());
VirtualRegister d = fn.newRegister();
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("Unknown operator " + b.operator());
};
fn.add(new BinOpInstruction(op, d, l, r));
return d;
}
}

View File

@ -0,0 +1,82 @@
package org.jcnc.snow.compiler.ir.builder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.core.IRProgram;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.ModuleNode;
import org.jcnc.snow.compiler.parser.ast.base.Node;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
import java.util.List;
/**
* ProgramBuilder 用于将 AST 根节点列表构建为 IRProgram
*
* <p>功能
* <ul>
* <li>遍历顶层节点识别模块函数或顶层语句</li>
* <li>将函数节点转换为 IRFunction 并添加到 IRProgram</li>
* <li>对脚本式顶层语句自动包装为特殊的 _start 函数</li>
* </ul>
*/
public final class ProgramBuilder {
/**
* 构建一个完整的 IRProgram
*
* @param roots AST 根节点列表可包含 ModuleNodeFunctionNode StatementNode
* @return 构建好的 IRProgram 实例
* @throws IllegalStateException 当遇到不支持的顶层节点时抛出
*/
public IRProgram buildProgram(List<Node> roots) {
IRProgram prog = new IRProgram();
for (Node n : roots) {
if (n instanceof ModuleNode m) {
// 模块节点将模块内的所有函数加入程序
m.functions().forEach(f -> prog.add(buildFunction(f)));
} else if (n instanceof FunctionNode f) {
// 顶层函数节点
prog.add(buildFunction(f));
} else if (n instanceof StatementNode s) {
// 顶层脚本语句包装为 _start 函数
prog.add(buildFunction(wrapTopLevel(s)));
} else {
throw new IllegalStateException("Unsupported top-level node: " + n);
}
}
return prog;
}
/**
* 使用 FunctionBuilder 构建 IRFunction
*
* @param fn AST 中的 FunctionNode
* @return 构建完成的 IRFunction
*/
private IRFunction buildFunction(FunctionNode fn) {
return new FunctionBuilder().build(fn);
}
/**
* 将顶层脚本式语句包装为名为 _start FunctionNode
*
* <p>构造参数说明
* <ul>
* <li>函数名固定为 "_start"</li>
* <li>返回类型设为 null表示类型推断或默认处理</li>
* <li>参数列表为空</li>
* <li>函数体仅包含给定的单条语句</li>
* </ul>
*
* @param stmt 要包装的顶层语句节点
* @return 新建的 FunctionNode
*/
private FunctionNode wrapTopLevel(StatementNode stmt) {
return new FunctionNode(
"_start",
null,
String.valueOf(List.of()),
List.of(stmt)
);
}
}

View File

@ -0,0 +1,77 @@
package org.jcnc.snow.compiler.ir.builder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.value.VirtualRegister;
import java.util.HashMap;
import java.util.Map;
/**
* Scope 用于管理单个函数的变量名与虚拟寄存器的映射
*
* <p>功能
* <ul>
* <li>维护变量声明后的寄存器分配</li>
* <li>支持将已有寄存器与变量重新绑定</li>
* <li>根据变量名查找对应的虚拟寄存器</li>
* </ul>
*/
final class Scope {
/** 存储变量名到 VirtualRegister 的映射 */
private final Map<String, VirtualRegister> vars = new HashMap<>();
/**
* 当前作用域所属的 IRFunction用于分配新的寄存器
*/
private IRFunction fn;
/**
* 关联一个 IRFunction 到当前作用域用于后续寄存器分配
*
* @param fn 要绑定的 IRFunction 实例
*/
void attachFunction(IRFunction fn) {
this.fn = fn;
}
/**
* 声明一个新变量并为其分配一个新的虚拟寄存器
*
* @param name 变量名
*/
void declare(String name) {
VirtualRegister reg = fn.newRegister();
vars.put(name, reg);
}
/**
* 声明或导入一个已有寄存器到当前作用域
*
* @param name 变量名
* @param reg 对应的虚拟寄存器
*/
void declare(String name, VirtualRegister reg) {
vars.put(name, reg);
}
/**
* 更新已声明变量对应的虚拟寄存器
*
* @param name 变量名
* @param reg 新的虚拟寄存器
*/
void put(String name, VirtualRegister reg) {
vars.put(name, reg);
}
/**
* 根据变量名查找其对应的虚拟寄存器
*
* @param name 变量名
* @return 对应的 VirtualRegister若未声明则返回 null
*/
VirtualRegister lookup(String name) {
return vars.get(name);
}
}