完善ir注释

This commit is contained in:
Luke 2025-04-29 10:46:45 +08:00
parent debe4fa22d
commit 97cb2ba05f
15 changed files with 637 additions and 115 deletions

View File

@ -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" />

View File

@ -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");
} // }
} // }
} }
} }

View File

@ -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()))));

View File

@ -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();
}
} }

View File

@ -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_I32CONSTRET
*
* @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();
}
} }

View File

@ -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
} }

View File

@ -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();
} }
} }

View File

@ -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 {
}

View File

@ -1,6 +1,23 @@
// file: compiler/ir/Label.java
package org.jcnc.snow.compiler.ir; package org.jcnc.snow.compiler.ir;
/**
* Label 表示 IR 中的跳转目标标签
*
* 在中间表示IR控制流指令 JUMPJUMP_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 + ":";
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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();
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }