完善ir注释
This commit is contained in:
parent
debe4fa22d
commit
97cb2ba05f
@ -1,5 +1,7 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Main" type="Application" factoryName="Application" nameIsGenerated="true">
|
<configuration default="false" name="SnowCompiler" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||||
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.compiler.cli.SnowCompiler" />
|
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.compiler.cli.SnowCompiler" />
|
||||||
<module name="SCompiler" />
|
<module name="SCompiler" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="test" />
|
<option name="PROGRAM_PARAMETERS" value="test" />
|
||||||
@ -61,27 +61,27 @@ public class SnowCompiler {
|
|||||||
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();
|
||||||
var slotM = alloc.allocate(fn);
|
// var slotM = alloc.allocate(fn);
|
||||||
|
//
|
||||||
var gen = new VMCodeGenerator(slotM);
|
// var gen = new VMCodeGenerator(slotM);
|
||||||
var code = gen.generate(fn);
|
// var code = gen.generate(fn);
|
||||||
|
//
|
||||||
System.out.println("== VM code for " + fn.name() + " ==");
|
// System.out.println("== VM code for " + fn.name() + " ==");
|
||||||
code.forEach(System.out::println);
|
// code.forEach(System.out::println);
|
||||||
|
//
|
||||||
|
//
|
||||||
/* 只执行 main 函数 */
|
// /* 只执行 main 函数 */
|
||||||
if ("main".equals(fn.name())) {
|
// if ("main".equals(fn.name())) {
|
||||||
VirtualMachineEngine vm = new VirtualMachineEngine(VMMode.RUN);
|
// VirtualMachineEngine vm = new VirtualMachineEngine(VMMode.RUN);
|
||||||
|
//
|
||||||
vm.execute(code); // 运行指令
|
// vm.execute(code); // 运行指令
|
||||||
vm.printStack(); // 打印 Operand-/Call-Stack
|
// vm.printStack(); // 打印 Operand-/Call-Stack
|
||||||
vm.printLocalVariables(); // 打印局部变量槽
|
// vm.printLocalVariables(); // 打印局部变量槽
|
||||||
|
//
|
||||||
System.out.println("Process has ended");
|
// System.out.println("Process has ended");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,15 +11,23 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 把 AST 转为 IR。
|
* BasicIRBuilder 类 —— 将 AST(抽象语法树)转换为 IR(中间表示)。
|
||||||
* • 递归处理 Module → Function → Statement → Expression(分而治之)
|
* <p>
|
||||||
* • 目前只支持整数字面量、标识符、+ - * /、变量声明/赋值、return
|
* 支持功能:
|
||||||
|
* • 整棵模块(Module)到函数(Function)到语句(Statement)到表达式(Expression)的递归编译
|
||||||
|
* • 支持整数字面量、标识符、四则运算(+ - * /)
|
||||||
|
* • 支持变量声明、赋值、return 语句
|
||||||
*/
|
*/
|
||||||
public final class BasicIRBuilder {
|
public final class BasicIRBuilder {
|
||||||
|
|
||||||
/* ───────────────── 顶层 API ───────────────── */
|
/* ───────────────── 顶层 API ───────────────── */
|
||||||
|
|
||||||
/** 把整棵 AST(可能含模块/多函数)转换为 IRProgram */
|
/**
|
||||||
|
* 将一组顶层 AST 节点(可能是模块、函数或语句)转换成 IRProgram。
|
||||||
|
*
|
||||||
|
* @param roots AST 根节点列表
|
||||||
|
* @return 构建好的 IRProgram
|
||||||
|
*/
|
||||||
public IRProgram buildProgram(List<Node> roots) {
|
public IRProgram buildProgram(List<Node> roots) {
|
||||||
IRProgram prog = new IRProgram();
|
IRProgram prog = new IRProgram();
|
||||||
for (Node n : roots) dispatchTop(n, prog);
|
for (Node n : roots) dispatchTop(n, prog);
|
||||||
@ -28,16 +36,21 @@ public final class BasicIRBuilder {
|
|||||||
|
|
||||||
/* ───────────────── 内部实现 ───────────────── */
|
/* ───────────────── 内部实现 ───────────────── */
|
||||||
|
|
||||||
/** 处理模块 / 顶层函数 / 单条语句 */
|
/**
|
||||||
|
* 处理一个顶层节点:可能是模块、函数,或单条语句。
|
||||||
|
*
|
||||||
|
* @param n AST 节点
|
||||||
|
* @param prog 正在构建的 IRProgram
|
||||||
|
*/
|
||||||
private void dispatchTop(Node n, IRProgram prog) {
|
private void dispatchTop(Node n, IRProgram prog) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
/* module { fun* } */
|
/* module { fun* }:递归处理模块内的所有函数 */
|
||||||
case ModuleNode m -> m.functions().forEach(f -> dispatchTop(f, prog));
|
case ModuleNode m -> m.functions().forEach(f -> dispatchTop(f, prog));
|
||||||
|
|
||||||
/* fun foo(...) { stmts } */
|
/* fun foo(...) { stmts }:构建单个函数 */
|
||||||
case FunctionNode f -> prog.add(buildFunction(f));
|
case FunctionNode f -> prog.add(buildFunction(f));
|
||||||
|
|
||||||
/* 若直接给了一堆语句,也视作匿名主函数 */
|
/* 单条语句:作为匿名 "main" 函数处理 */
|
||||||
case StatementNode s -> {
|
case StatementNode s -> {
|
||||||
FunctionNode fake = new FunctionNode("main", List.of(), "void", List.of(s));
|
FunctionNode fake = new FunctionNode("main", List.of(), "void", List.of(s));
|
||||||
prog.add(buildFunction(fake));
|
prog.add(buildFunction(fake));
|
||||||
@ -47,22 +60,27 @@ public final class BasicIRBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 将单个 FunctionNode 转成 IRFunction */
|
/**
|
||||||
|
* 将 FunctionNode 转换为 IRFunction。
|
||||||
|
*
|
||||||
|
* @param fn AST 中的函数节点
|
||||||
|
* @return 转换后的 IRFunction
|
||||||
|
*/
|
||||||
private IRFunction buildFunction(FunctionNode fn) {
|
private IRFunction buildFunction(FunctionNode fn) {
|
||||||
currentFn = new IRFunction(fn.name());
|
currentFn = new IRFunction(fn.name());
|
||||||
variables.clear();
|
variables.clear();
|
||||||
|
|
||||||
/* 参数映射到寄存器(暂未用到,保留扩展) */
|
/* 将函数参数映射为虚拟寄存器(目前未在其他地方使用,但保留未来支持) */
|
||||||
for (ParameterNode p : fn.parameters()) {
|
for (ParameterNode p : fn.parameters()) {
|
||||||
variables.put(p.name(), currentFn.newRegister());
|
variables.put(p.name(), currentFn.newRegister());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 编译函数体 */
|
/* 编译函数体中的每条语句 */
|
||||||
for (StatementNode stmt : fn.body()) stmt(stmt);
|
for (StatementNode stmt : fn.body()) stmt(stmt);
|
||||||
|
|
||||||
/* 若无显式 return,补一个 void return */
|
/* 如果没有显式 return,补一个无返回值的 RET 指令 */
|
||||||
if (currentFn.body().isEmpty() ||
|
if (currentFn.body().isEmpty() ||
|
||||||
!(currentFn.body().get(currentFn.body().size() - 1) instanceof ReturnInstruction))
|
!(currentFn.body().getLast() instanceof ReturnInstruction))
|
||||||
currentFn.add(new ReturnInstruction(null));
|
currentFn.add(new ReturnInstruction(null));
|
||||||
|
|
||||||
return currentFn;
|
return currentFn;
|
||||||
@ -70,19 +88,31 @@ public final class BasicIRBuilder {
|
|||||||
|
|
||||||
/* ─────────────── 函数体级别状态 ─────────────── */
|
/* ─────────────── 函数体级别状态 ─────────────── */
|
||||||
|
|
||||||
private IRFunction currentFn; // 正在构建的函数
|
/** 当前正在构建的 IRFunction 对象 */
|
||||||
|
private IRFunction currentFn;
|
||||||
|
|
||||||
|
/** 当前作用域内变量名到虚拟寄存器的映射表 */
|
||||||
private final Map<String, VirtualRegister> variables = new HashMap<>();
|
private final Map<String, VirtualRegister> variables = new HashMap<>();
|
||||||
|
|
||||||
/* ─── 语句 ─── */
|
/* ─── 处理语句 ─── */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一个语句节点编译为 IR 指令。
|
||||||
|
*
|
||||||
|
* @param n AST 语句节点
|
||||||
|
*/
|
||||||
private void stmt(StatementNode n) {
|
private void stmt(StatementNode n) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
|
/* 表达式语句:只编译表达式,结果不保存 */
|
||||||
case ExpressionStatementNode es -> expr(es.expression());
|
case ExpressionStatementNode es -> expr(es.expression());
|
||||||
|
|
||||||
|
/* 赋值语句:编译右值表达式,并更新变量表 */
|
||||||
case AssignmentNode as -> {
|
case AssignmentNode as -> {
|
||||||
VirtualRegister rhs = expr(as.value());
|
VirtualRegister rhs = expr(as.value());
|
||||||
variables.put(as.variable(), rhs);
|
variables.put(as.variable(), rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 变量声明:可带初始化器 */
|
||||||
case DeclarationNode d -> {
|
case DeclarationNode d -> {
|
||||||
if (d.getInitializer().isPresent()) {
|
if (d.getInitializer().isPresent()) {
|
||||||
VirtualRegister init = expr(d.getInitializer().get());
|
VirtualRegister init = expr(d.getInitializer().get());
|
||||||
@ -92,6 +122,7 @@ public final class BasicIRBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return 语句:可带返回值也可以没有 */
|
||||||
case ReturnNode r -> {
|
case ReturnNode r -> {
|
||||||
if (r.getExpression().isPresent())
|
if (r.getExpression().isPresent())
|
||||||
currentFn.add(new ReturnInstruction(expr(r.getExpression().get())));
|
currentFn.add(new ReturnInstruction(expr(r.getExpression().get())));
|
||||||
@ -103,25 +134,45 @@ public final class BasicIRBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── 表达式 ─── */
|
/* ─── 处理表达式 ─── */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一个表达式节点编译为虚拟寄存器中的值。
|
||||||
|
*
|
||||||
|
* @param e AST 表达式节点
|
||||||
|
* @return 保存表达式结果的虚拟寄存器
|
||||||
|
*/
|
||||||
private VirtualRegister expr(ExpressionNode e) {
|
private VirtualRegister expr(ExpressionNode e) {
|
||||||
return switch (e) {
|
return switch (e) {
|
||||||
|
/* 二元运算 */
|
||||||
case BinaryExpressionNode b -> bin(b);
|
case BinaryExpressionNode b -> bin(b);
|
||||||
|
|
||||||
|
/* 数字字面量 */
|
||||||
case NumberLiteralNode n -> number(n);
|
case NumberLiteralNode n -> number(n);
|
||||||
|
|
||||||
|
/* 变量标识符 */
|
||||||
case IdentifierNode id -> {
|
case IdentifierNode id -> {
|
||||||
VirtualRegister v = variables.get(id.name());
|
VirtualRegister v = variables.get(id.name());
|
||||||
if (v == null) throw new IllegalStateException("变量 " + id.name() + " 未定义");
|
if (v == null) throw new IllegalStateException("变量 " + id.name() + " 未定义");
|
||||||
yield v;
|
yield v;
|
||||||
}
|
}
|
||||||
|
|
||||||
default -> throw new IllegalStateException("Unsupported expr: " + e);
|
default -> throw new IllegalStateException("Unsupported expr: " + e);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理二元表达式(加减乘除)。
|
||||||
|
*
|
||||||
|
* @param b AST 二元表达式节点
|
||||||
|
* @return 保存运算结果的寄存器
|
||||||
|
*/
|
||||||
private VirtualRegister bin(BinaryExpressionNode b) {
|
private VirtualRegister bin(BinaryExpressionNode b) {
|
||||||
VirtualRegister l = expr(b.left());
|
VirtualRegister l = expr(b.left()); // 左操作数
|
||||||
VirtualRegister r = expr(b.right());
|
VirtualRegister r = expr(b.right()); // 右操作数
|
||||||
VirtualRegister d = currentFn.newRegister();
|
VirtualRegister d = currentFn.newRegister(); // 保存结果
|
||||||
|
|
||||||
|
/* 映射操作符到 IROp */
|
||||||
IROp op = switch (b.operator()) {
|
IROp op = switch (b.operator()) {
|
||||||
case "+" -> IROp.ADD_I32;
|
case "+" -> IROp.ADD_I32;
|
||||||
case "-" -> IROp.SUB_I32;
|
case "-" -> IROp.SUB_I32;
|
||||||
@ -134,6 +185,12 @@ public final class BasicIRBuilder {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理整数字面量。
|
||||||
|
*
|
||||||
|
* @param n AST 数字字面量节点
|
||||||
|
* @return 保存常量的寄存器
|
||||||
|
*/
|
||||||
private VirtualRegister number(NumberLiteralNode n) {
|
private VirtualRegister number(NumberLiteralNode n) {
|
||||||
VirtualRegister d = currentFn.newRegister();
|
VirtualRegister d = currentFn.newRegister();
|
||||||
currentFn.add(new LoadConstInstruction(d, new Constant(Integer.parseInt(n.value()))));
|
currentFn.add(new LoadConstInstruction(d, new Constant(Integer.parseInt(n.value()))));
|
||||||
|
|||||||
@ -1,5 +1,20 @@
|
|||||||
package org.jcnc.snow.compiler.ir;
|
package org.jcnc.snow.compiler.ir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant 类 —— 表示一个常量值(例如整数常量、字符串常量等)。
|
||||||
|
* <p>
|
||||||
|
* 在中间表示(IR)中,常量通常是不可变的、直接使用的值,而不是寄存器或临时变量。
|
||||||
|
*/
|
||||||
public record Constant(Object value) implements IRValue {
|
public record Constant(Object value) implements IRValue {
|
||||||
@Override public String toString() { return value.toString(); }
|
|
||||||
|
/**
|
||||||
|
* 将常量值转换为字符串表示。
|
||||||
|
* 主要用于打印 IR 指令时显示常量内容。
|
||||||
|
*
|
||||||
|
* @return 常量的字符串形式
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,47 @@ package org.jcnc.snow.compiler.ir;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** 全部 IR 指令的抽象父类 */
|
/**
|
||||||
|
* IRInstruction —— 所有 IR 指令的抽象基类(Abstract Base Class)。
|
||||||
|
* <p>
|
||||||
|
* 每一条 IR 指令都至少具备以下基本属性:
|
||||||
|
* - 操作符(op):指示这条指令的操作类型,如加法、常量加载等。
|
||||||
|
* - 目标寄存器(dest):保存运算结果的寄存器(某些指令可能没有结果)。
|
||||||
|
* - 操作数列表(operands):指令所使用的操作数,如常量或寄存器。
|
||||||
|
* <p>
|
||||||
|
* 继承类可以根据需要覆盖 dest() 和 operands() 方法。
|
||||||
|
*/
|
||||||
public abstract class IRInstruction {
|
public abstract class IRInstruction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指令的操作符。
|
||||||
|
* 例如:ADD_I32、CONST、RET 等。
|
||||||
|
*
|
||||||
|
* @return 操作符枚举值(IROp)
|
||||||
|
*/
|
||||||
public abstract IROp op();
|
public abstract IROp op();
|
||||||
public VirtualRegister dest() { return null; } // 若无结果可返回 null
|
|
||||||
public List<IRValue> operands() { return List.of(); } // 默认无操作数
|
/**
|
||||||
|
* 获取指令的目标寄存器(若有的话)。
|
||||||
|
*
|
||||||
|
* 默认返回 null,表示该指令没有结果寄存器。
|
||||||
|
* 子类可以根据需要覆盖此方法。
|
||||||
|
*
|
||||||
|
* @return 目标寄存器或 null
|
||||||
|
*/
|
||||||
|
public VirtualRegister dest() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指令的操作数列表。
|
||||||
|
*
|
||||||
|
* 默认返回空列表,表示没有任何操作数。
|
||||||
|
* 子类通常会根据指令类型重写此方法,返回实际的操作数(如左右子表达式、常量等)。
|
||||||
|
*
|
||||||
|
* @return 操作数列表
|
||||||
|
*/
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,76 @@
|
|||||||
package org.jcnc.snow.compiler.ir;
|
package org.jcnc.snow.compiler.ir;
|
||||||
|
|
||||||
/** IR 支持的操作码(可按需继续扩展) */
|
/**
|
||||||
|
* IROp —— IR 层支持的操作码(Opcode)枚举类型。
|
||||||
|
* <p>
|
||||||
|
* 每种操作码代表一条基本指令的种类,供 IRInstruction 使用。
|
||||||
|
* 可以根据编译器需求继续扩展。
|
||||||
|
*/
|
||||||
public enum IROp {
|
public enum IROp {
|
||||||
/* 算术 */
|
/* ───── 算术运算 ───── */
|
||||||
ADD_I32, SUB_I32, MUL_I32, DIV_I32, NEG_I32,
|
|
||||||
/* 逻辑/比较 */
|
/** 整型加法(32位) */
|
||||||
CMP_EQ, CMP_NE, CMP_LT, CMP_GT, CMP_LE, CMP_GE,
|
ADD_I32,
|
||||||
/* 数据搬运 */
|
|
||||||
LOAD, STORE, CONST,
|
/** 整型减法(32位) */
|
||||||
/* 控制流 */
|
SUB_I32,
|
||||||
JUMP, JUMP_IF_ZERO, LABEL,
|
|
||||||
/* 函数 */
|
/** 整型乘法(32位) */
|
||||||
CALL, RET
|
MUL_I32,
|
||||||
|
|
||||||
|
/** 整型除法(32位) */
|
||||||
|
DIV_I32,
|
||||||
|
|
||||||
|
/** 整型取负(32位),一元运算 */
|
||||||
|
NEG_I32,
|
||||||
|
|
||||||
|
/* ───── 逻辑/比较运算 ───── */
|
||||||
|
|
||||||
|
/** 相等比较(==) */
|
||||||
|
CMP_EQ,
|
||||||
|
|
||||||
|
/** 不等比较(!=) */
|
||||||
|
CMP_NE,
|
||||||
|
|
||||||
|
/** 小于比较(<) */
|
||||||
|
CMP_LT,
|
||||||
|
|
||||||
|
/** 大于比较(>) */
|
||||||
|
CMP_GT,
|
||||||
|
|
||||||
|
/** 小于等于(<=) */
|
||||||
|
CMP_LE,
|
||||||
|
|
||||||
|
/** 大于等于(>=) */
|
||||||
|
CMP_GE,
|
||||||
|
|
||||||
|
/* ───── 数据搬运 ───── */
|
||||||
|
|
||||||
|
/** 从内存加载(Load) */
|
||||||
|
LOAD,
|
||||||
|
|
||||||
|
/** 存储到内存(Store) */
|
||||||
|
STORE,
|
||||||
|
|
||||||
|
/** 加载常量(Constant) */
|
||||||
|
CONST,
|
||||||
|
|
||||||
|
/* ───── 控制流 ───── */
|
||||||
|
|
||||||
|
/** 无条件跳转(Jump) */
|
||||||
|
JUMP,
|
||||||
|
|
||||||
|
/** 条件跳转(Jump if zero),若条件为 0 则跳转 */
|
||||||
|
JUMP_IF_ZERO,
|
||||||
|
|
||||||
|
/** 标签(Label),跳转目标位置 */
|
||||||
|
LABEL,
|
||||||
|
|
||||||
|
/* ───── 函数调用相关 ───── */
|
||||||
|
|
||||||
|
/** 函数调用(Call) */
|
||||||
|
CALL,
|
||||||
|
|
||||||
|
/** 返回(Return) */
|
||||||
|
RET
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,18 +7,45 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一份完整的中间代码程序,包含多个函数级 IR。
|
* IRProgram —— 表示一份完整的中间表示(IR)程序。
|
||||||
|
* <p>
|
||||||
|
* 每个 IRProgram 由多个函数(IRFunction)组成,
|
||||||
|
* 是编译器后端生成目标代码的基础单位。
|
||||||
*/
|
*/
|
||||||
public final class IRProgram {
|
public final class IRProgram {
|
||||||
|
// 存储程序中所有函数的列表
|
||||||
private final List<IRFunction> functions = new ArrayList<>();
|
private final List<IRFunction> functions = new ArrayList<>();
|
||||||
|
|
||||||
public void add(IRFunction fn) { functions.add(fn); }
|
/**
|
||||||
|
* 向程序中添加一个函数。
|
||||||
|
*
|
||||||
|
* @param fn 要添加的 IRFunction
|
||||||
|
*/
|
||||||
|
public void add(IRFunction fn) {
|
||||||
|
functions.add(fn);
|
||||||
|
}
|
||||||
|
|
||||||
public List<IRFunction> functions() { return Collections.unmodifiableList(functions); }
|
/**
|
||||||
|
* 获取所有函数的不可变列表。
|
||||||
|
*
|
||||||
|
* @return 包含所有 IRFunction 的不可修改视图
|
||||||
|
*/
|
||||||
|
public List<IRFunction> functions() {
|
||||||
|
return Collections.unmodifiableList(functions);
|
||||||
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
/**
|
||||||
|
* 将整个 IRProgram 转换成字符串表示。
|
||||||
|
* 每个函数独占一行,适合打印调试。
|
||||||
|
*
|
||||||
|
* @return 程序的字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (IRFunction f : functions) sb.append(f).append('\n');
|
for (IRFunction f : functions) {
|
||||||
|
sb.append(f).append('\n');
|
||||||
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,16 @@
|
|||||||
package org.jcnc.snow.compiler.ir;
|
package org.jcnc.snow.compiler.ir;
|
||||||
|
|
||||||
/** 常量、寄存器、标签的共同父接口 */
|
/**
|
||||||
public sealed interface IRValue permits VirtualRegister, Constant, Label {}
|
* IRValue —— 表示在中间表示(IR)系统中能作为操作数使用的基本单位。
|
||||||
|
* <p>
|
||||||
|
* 包括:
|
||||||
|
* • VirtualRegister(虚拟寄存器)
|
||||||
|
* • Constant(常量)
|
||||||
|
* • Label(跳转标签)
|
||||||
|
* <p>
|
||||||
|
* 本接口使用 sealed 限定,明确列出所有允许实现它的子类型,
|
||||||
|
* 保证类型安全,并便于在编译时做穷尽检查。
|
||||||
|
*/
|
||||||
|
public sealed interface IRValue
|
||||||
|
permits VirtualRegister, Constant, Label {
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,23 @@
|
|||||||
// file: compiler/ir/Label.java
|
|
||||||
package org.jcnc.snow.compiler.ir;
|
package org.jcnc.snow.compiler.ir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label —— 表示 IR 中的跳转目标标签。
|
||||||
|
*
|
||||||
|
* 在中间表示(IR)中,控制流指令(如 JUMP、JUMP_IF_ZERO)需要依赖标签来指定跳转位置。
|
||||||
|
* 本类通过名字(字符串)唯一标识一个标签。
|
||||||
|
*
|
||||||
|
* Label 也是一种 IRValue,因此可以作为指令的操作数。
|
||||||
|
*/
|
||||||
public record Label(String name) implements IRValue {
|
public record Label(String name) implements IRValue {
|
||||||
@Override public String toString() { return name + ":"; }
|
|
||||||
|
/**
|
||||||
|
* 将标签转换为字符串形式。
|
||||||
|
* 打印时在标签名后添加冒号,例如 "L1:"。
|
||||||
|
*
|
||||||
|
* @return 标签的字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + ":";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,26 @@
|
|||||||
package org.jcnc.snow.compiler.ir;
|
package org.jcnc.snow.compiler.ir;
|
||||||
|
|
||||||
/** SSA 虚拟寄存器 */
|
/**
|
||||||
|
* VirtualRegister —— 表示一个 SSA(静态单赋值)虚拟寄存器。
|
||||||
|
*
|
||||||
|
* 在中间表示(IR)中,每个中间值都存储在一个虚拟寄存器中。
|
||||||
|
*
|
||||||
|
* 特点:
|
||||||
|
* - 每个寄存器都有唯一的 id(通常由 IRBuilder 自动分配)
|
||||||
|
* - 遵循 SSA 形式,即每个寄存器只被赋值一次
|
||||||
|
*
|
||||||
|
* VirtualRegister 也是一种 IRValue,可以作为指令的操作数。
|
||||||
|
*/
|
||||||
public record VirtualRegister(int id) implements IRValue {
|
public record VirtualRegister(int id) implements IRValue {
|
||||||
@Override public String toString() { return "%" + id; }
|
|
||||||
|
/**
|
||||||
|
* 将虚拟寄存器转换为字符串形式。
|
||||||
|
* 通常以 % 开头,例如 "%0"、"%1"。
|
||||||
|
*
|
||||||
|
* @return 寄存器的字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "%" + id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,22 +4,77 @@ import org.jcnc.snow.compiler.ir.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** 二元运算:dest = lhs (OP) rhs */
|
/**
|
||||||
|
* 表示一个二元运算指令(Binary Operation Instruction)。
|
||||||
|
* 格式为:dest = lhs (OP) rhs
|
||||||
|
* 其中 dest 是结果寄存器,lhs 和 rhs 是操作数,OP 是操作符(如加法、减法等)。
|
||||||
|
*/
|
||||||
public final class BinOpInstruction extends IRInstruction {
|
public final class BinOpInstruction extends IRInstruction {
|
||||||
|
// 二元操作符,例如加法、减法、乘法、除法等
|
||||||
private final IROp op;
|
private final IROp op;
|
||||||
|
|
||||||
|
// 存放运算结果的虚拟寄存器
|
||||||
private final VirtualRegister dest;
|
private final VirtualRegister dest;
|
||||||
|
|
||||||
|
// 左操作数
|
||||||
private final IRValue lhs;
|
private final IRValue lhs;
|
||||||
|
|
||||||
|
// 右操作数
|
||||||
private final IRValue rhs;
|
private final IRValue rhs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,创建一个二元运算指令实例。
|
||||||
|
*
|
||||||
|
* @param op 运算操作符
|
||||||
|
* @param dest 运算结果存放的目标寄存器
|
||||||
|
* @param lhs 左侧操作数
|
||||||
|
* @param rhs 右侧操作数
|
||||||
|
*/
|
||||||
public BinOpInstruction(IROp op, VirtualRegister dest, IRValue lhs, IRValue rhs) {
|
public BinOpInstruction(IROp op, VirtualRegister dest, IRValue lhs, IRValue rhs) {
|
||||||
this.op = op;
|
this.op = op;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.lhs = lhs;
|
this.lhs = lhs;
|
||||||
this.rhs = rhs;
|
this.rhs = rhs;
|
||||||
}
|
}
|
||||||
@Override public IROp op() { return op; }
|
|
||||||
@Override public VirtualRegister dest() { return dest; }
|
|
||||||
@Override public List<IRValue> operands() { return List.of(lhs, rhs); }
|
|
||||||
|
|
||||||
@Override public String toString() { return dest + " = " + op + " " + lhs + ", " + rhs; }
|
/**
|
||||||
|
* 获取此指令对应的操作符。
|
||||||
|
*
|
||||||
|
* @return 操作符
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IROp op() {
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指令结果存放的目标寄存器。
|
||||||
|
*
|
||||||
|
* @return 目标寄存器
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public VirtualRegister dest() {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此指令所使用的操作数(左操作数和右操作数)。
|
||||||
|
*
|
||||||
|
* @return 操作数列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
return List.of(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指令转换成字符串表示,用于调试和打印。
|
||||||
|
* 格式示例:v1 = add v2, v3
|
||||||
|
*
|
||||||
|
* @return 字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return dest + " = " + op + " " + lhs + ", " + rhs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,24 +6,85 @@ import org.jcnc.snow.compiler.ir.VirtualRegister;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** 函数字节码级 IR */
|
/**
|
||||||
|
* 表示一个函数级别的中间表示(IR)。
|
||||||
|
* 每个 IRFunction 包含函数名称、指令列表(函数体)和用于管理寄存器编号的计数器。
|
||||||
|
*/
|
||||||
public class IRFunction {
|
public class IRFunction {
|
||||||
|
// 函数的名称
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
// 存放函数体中的指令列表
|
||||||
private final List<IRInstruction> body = new ArrayList<>();
|
private final List<IRInstruction> body = new ArrayList<>();
|
||||||
|
|
||||||
|
// 寄存器编号计数器,用于为新建的虚拟寄存器分配唯一编号
|
||||||
private int regCounter = 0;
|
private int regCounter = 0;
|
||||||
|
|
||||||
public IRFunction(String name){ this.name = name; }
|
/**
|
||||||
|
* 构造函数,创建一个新的 IRFunction 实例。
|
||||||
|
*
|
||||||
|
* @param name 函数的名称
|
||||||
|
*/
|
||||||
|
public IRFunction(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
/* —— API —— */
|
/* —— API —— */
|
||||||
public VirtualRegister newRegister(){ return new VirtualRegister(regCounter++); }
|
|
||||||
public void add(IRInstruction inst){ body.add(inst); }
|
|
||||||
public List<IRInstruction> body(){ return body; }
|
|
||||||
public String name(){ return name; }
|
|
||||||
public int registerCount(){ return regCounter; }
|
|
||||||
|
|
||||||
@Override public String toString(){
|
/**
|
||||||
StringBuilder sb=new StringBuilder("func "+name+" {\\n");
|
* 创建一个新的虚拟寄存器,并自动分配一个唯一的编号。
|
||||||
body.forEach(i->sb.append(" ").append(i).append("\\n"));
|
*
|
||||||
|
* @return 新建的虚拟寄存器
|
||||||
|
*/
|
||||||
|
public VirtualRegister newRegister() {
|
||||||
|
return new VirtualRegister(regCounter++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向函数体中添加一条指令。
|
||||||
|
*
|
||||||
|
* @param inst 要添加的中间表示指令
|
||||||
|
*/
|
||||||
|
public void add(IRInstruction inst) {
|
||||||
|
body.add(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取函数体的全部指令列表。
|
||||||
|
*
|
||||||
|
* @return 包含所有指令的列表
|
||||||
|
*/
|
||||||
|
public List<IRInstruction> body() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取函数的名称。
|
||||||
|
*
|
||||||
|
* @return 函数名称
|
||||||
|
*/
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前已分配的寄存器数量。
|
||||||
|
*
|
||||||
|
* @return 当前寄存器计数值
|
||||||
|
*/
|
||||||
|
public int registerCount() {
|
||||||
|
return regCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将整个函数(包括函数名和函数体)转换为字符串形式,便于打印或调试。
|
||||||
|
*
|
||||||
|
* @return 函数的字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder("func " + name + " {\n");
|
||||||
|
body.forEach(i -> sb.append(" ").append(i).append("\n"));
|
||||||
return sb.append('}').toString();
|
return sb.append('}').toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,18 +4,67 @@ import org.jcnc.snow.compiler.ir.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** 常量加载:dest = CONST k */
|
/**
|
||||||
|
* 表示常量加载指令(Load Constant Instruction)。
|
||||||
|
* 格式为:dest = CONST k
|
||||||
|
* 其中 dest 是结果寄存器,k 是要加载的常量值。
|
||||||
|
*/
|
||||||
public final class LoadConstInstruction extends IRInstruction {
|
public final class LoadConstInstruction extends IRInstruction {
|
||||||
|
// 要加载的常量值
|
||||||
private final Constant k;
|
private final Constant k;
|
||||||
|
|
||||||
|
// 存放常量的目标虚拟寄存器
|
||||||
private final VirtualRegister dest;
|
private final VirtualRegister dest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,创建一个常量加载指令实例。
|
||||||
|
*
|
||||||
|
* @param dest 目标寄存器,用于存放常量
|
||||||
|
* @param k 要加载的常量值
|
||||||
|
*/
|
||||||
public LoadConstInstruction(VirtualRegister dest, Constant k) {
|
public LoadConstInstruction(VirtualRegister dest, Constant k) {
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.k = k;
|
this.k = k;
|
||||||
}
|
}
|
||||||
@Override public IROp op() { return IROp.CONST; }
|
|
||||||
@Override public VirtualRegister dest() { return dest; }
|
|
||||||
@Override public List<IRValue> operands() { return List.of(k); }
|
|
||||||
|
|
||||||
@Override public String toString() { return dest + " = CONST " + k; }
|
/**
|
||||||
|
* 获取此指令的操作符,恒为 CONST。
|
||||||
|
*
|
||||||
|
* @return 操作符 IROp.CONST
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IROp op() {
|
||||||
|
return IROp.CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指令结果存放的目标寄存器。
|
||||||
|
*
|
||||||
|
* @return 目标虚拟寄存器
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public VirtualRegister dest() {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此指令所用的操作数(只有一个常量)。
|
||||||
|
*
|
||||||
|
* @return 仅包含常量 k 的操作数列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
return List.of(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指令转换成字符串表示,用于调试和打印。
|
||||||
|
* 格式示例:v1 = CONST 42
|
||||||
|
*
|
||||||
|
* @return 字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return dest + " = CONST " + k;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,67 @@ import org.jcnc.snow.compiler.ir.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** return [val] */
|
/**
|
||||||
|
* 表示函数的返回指令(Return Instruction)。
|
||||||
|
* 格式为:return [val]
|
||||||
|
* <p>
|
||||||
|
* - 如果是 void 返回(即没有返回值),val 为 null。
|
||||||
|
* - 否则,返回指定寄存器中的值。
|
||||||
|
*/
|
||||||
public final class ReturnInstruction extends IRInstruction {
|
public final class ReturnInstruction extends IRInstruction {
|
||||||
private final VirtualRegister value; // void 时为 null
|
// 返回值对应的虚拟寄存器,如果是 void 返回则为 null
|
||||||
public ReturnInstruction(VirtualRegister value){ this.value = value; }
|
private final VirtualRegister value;
|
||||||
|
|
||||||
@Override public IROp op() { return IROp.RET; }
|
/**
|
||||||
@Override public List<IRValue> operands() { return value==null? List.of() : List.of(value); }
|
* 构造函数,创建一个返回指令实例。
|
||||||
public VirtualRegister value() { return value; }
|
*
|
||||||
|
* @param value 要返回的虚拟寄存器,如果是 void 返回则传入 null
|
||||||
@Override public String toString(){ return value==null? "RET" : "RET " + value; }
|
*/
|
||||||
|
public ReturnInstruction(VirtualRegister value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此指令的操作符,恒为 RET。
|
||||||
|
*
|
||||||
|
* @return 操作符 IROp.RET
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IROp op() {
|
||||||
|
return IROp.RET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此指令的操作数列表。
|
||||||
|
* - 如果是 void 返回,返回空列表;
|
||||||
|
* - 否则,返回包含返回值寄存器的列表。
|
||||||
|
*
|
||||||
|
* @return 操作数列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
return value == null ? List.of() : List.of(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取要返回的值(虚拟寄存器)。
|
||||||
|
*
|
||||||
|
* @return 返回值寄存器,或 null(表示 void 返回)
|
||||||
|
*/
|
||||||
|
public VirtualRegister value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将返回指令转换成字符串表示,用于调试和打印。
|
||||||
|
* 格式示例:
|
||||||
|
* - "RET" (无返回值)
|
||||||
|
* - "RET v1"(返回寄存器 v1 的值)
|
||||||
|
*
|
||||||
|
* @return 字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value == null ? "RET" : "RET " + value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,20 +4,75 @@ import org.jcnc.snow.compiler.ir.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** 一元运算:dest = OP val */
|
/**
|
||||||
|
* 表示一元运算指令(Unary Operation Instruction)。
|
||||||
|
* 格式为:dest = OP val
|
||||||
|
* <p>
|
||||||
|
* - dest:运算结果存放的目标寄存器
|
||||||
|
* - OP:一元操作符(如取负、按位取反等)
|
||||||
|
* - val:操作数
|
||||||
|
*/
|
||||||
public final class UnaryOpInstruction extends IRInstruction {
|
public final class UnaryOpInstruction extends IRInstruction {
|
||||||
|
// 一元操作符,例如 NEG(取负)、NOT(逻辑非)等
|
||||||
private final IROp op;
|
private final IROp op;
|
||||||
|
|
||||||
|
// 运算结果存放的目标虚拟寄存器
|
||||||
private final VirtualRegister dest;
|
private final VirtualRegister dest;
|
||||||
|
|
||||||
|
// 一元运算的操作数
|
||||||
private final IRValue val;
|
private final IRValue val;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,创建一个一元运算指令实例。
|
||||||
|
*
|
||||||
|
* @param op 一元操作符
|
||||||
|
* @param dest 结果存放的目标寄存器
|
||||||
|
* @param val 操作数
|
||||||
|
*/
|
||||||
public UnaryOpInstruction(IROp op, VirtualRegister dest, IRValue val) {
|
public UnaryOpInstruction(IROp op, VirtualRegister dest, IRValue val) {
|
||||||
this.op = op;
|
this.op = op;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.val = val;
|
this.val = val;
|
||||||
}
|
}
|
||||||
@Override public IROp op() { return op; }
|
|
||||||
@Override public VirtualRegister dest() { return dest; }
|
|
||||||
@Override public List<IRValue> operands() { return List.of(val); }
|
|
||||||
|
|
||||||
@Override public String toString() { return dest + " = " + op + " " + val; }
|
/**
|
||||||
|
* 获取此指令对应的操作符。
|
||||||
|
*
|
||||||
|
* @return 一元操作符
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IROp op() {
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指令结果存放的目标寄存器。
|
||||||
|
*
|
||||||
|
* @return 目标虚拟寄存器
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public VirtualRegister dest() {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此指令所使用的操作数(只有一个操作数)。
|
||||||
|
*
|
||||||
|
* @return 仅包含 val 的操作数列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
return List.of(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指令转换为字符串表示形式,用于调试和打印。
|
||||||
|
* 格式示例:v1 = NEG v2
|
||||||
|
*
|
||||||
|
* @return 字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return dest + " = " + op + " " + val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user