diff --git a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java index 6864c59..ed6ec2c 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java +++ b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java @@ -92,7 +92,7 @@ public final class VMCodeGenerator { * 生成一元运算(如取负) */ private void genUnary(UnaryOperationInstruction u) { - emit(op("I_LOAD"), slot((IRVirtualRegister) u.operands().get(0)) + ""); + emit(op("I_LOAD"), slot((IRVirtualRegister) u.operands().getFirst()) + ""); String opcode = IROpCodeMapper.toVMOp(u.op()); emit(op(opcode)); diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IRInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IRInstruction.java index 12f0c68..5146d27 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/core/IRInstruction.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRInstruction.java @@ -4,13 +4,43 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import java.util.List; /** - * IRInstruction —— 所有 IR 指令的抽象基类。 + * IRInstruction —— 所有 IR(中间表示)指令的抽象基类。 + *
+ * 本类定义了编译器中间表示系统中所有指令的基本结构和行为。
+ * 子类需实现具体的操作码(Opcode)和指令行为。
+ * 这是采用“访问者模式”设计的一部分,便于对指令进行统一访问和操作。
*/
public abstract class IRInstruction {
+
+ /**
+ * 获取该指令的操作码(Opcode)。
+ * 每条具体指令子类都必须实现此方法以返回对应的操作码枚举。
+ *
+ * @return 表示该指令类型的 IROpCode 实例
+ */
public abstract IROpCode op();
+
+ /**
+ * 获取该指令的目标虚拟寄存器(destination register)。
+ * 默认为 null。部分子类(如赋值、运算类指令)应重写以返回具体目标寄存器。
+ *
+ * @return 指令的目标虚拟寄存器,或为 null(若无目标寄存器)
+ */
public IRVirtualRegister dest() { return null; }
+
+ /**
+ * 获取该指令的操作数列表。
+ * 默认为空列表。子类应重写以提供实际使用的操作数集合。
+ *
+ * @return 一个包含所有操作数(IRValue)的列表
+ */
public List
- * 每种操作码代表一条基本指令的种类,供 IRInstruction 使用。
- * 可以根据编译器需求继续扩展。
+ * 本枚举类定义了中间表示层可用的所有基本指令类型,供 {@link IRInstruction} 使用。
+ * 每个枚举值代表一种语义明确的 IR 操作,涵盖常见的算术、逻辑、数据操作和控制流等指令。
+ * 可根据后续需求继续扩展。
*/
public enum IROpCode {
+
/* ───── 算术运算 ───── */
- /** 整型加法(32位) */
+ /** 整型加法(32位),形如:a = b + c */
ADD_I32,
- /** 整型减法(32位) */
+ /** 整型减法(32位),形如:a = b - c */
SUB_I32,
- /** 整型乘法(32位) */
+ /** 整型乘法(32位),形如:a = b * c */
MUL_I32,
- /** 整型除法(32位) */
+ /** 整型除法(32位),形如:a = b / c */
DIV_I32,
- /** 整型取负(32位),一元运算 */
+ /** 整型取负(32位),形如:a = -b(一元运算) */
NEG_I32,
/* ───── 逻辑/比较运算 ───── */
- /** 相等比较(==) */
+ /** 相等比较(==),结果为布尔值,形如:a = (b == c) */
CMP_EQ,
- /** 不等比较(!=) */
+ /** 不等比较(!=),结果为布尔值,形如:a = (b != c) */
CMP_NE,
- /** 小于比较(<) */
+ /** 小于比较(<),结果为布尔值,形如:a = (b < c) */
CMP_LT,
- /** 大于比较(>) */
+ /** 大于比较(>),结果为布尔值,形如:a = (b > c) */
CMP_GT,
- /** 小于等于(<=) */
+ /** 小于等于(<=),结果为布尔值,形如:a = (b <= c) */
CMP_LE,
- /** 大于等于(>=) */
+ /** 大于等于(>=),结果为布尔值,形如:a = (b >= c) */
CMP_GE,
/* ───── 数据搬运 ───── */
- /** 从内存加载(Load) */
+ /** 从内存加载到寄存器(Load),形如:a = *addr */
LOAD,
- /** 存储到内存(Store) */
+ /** 将数据存储到内存地址(Store),形如:*addr = a */
STORE,
- /** 加载常量(IRConstant) */
+ /** 加载常量值(IRConstant)到寄存器,形如:a = 123 */
CONST,
/* ───── 控制流 ───── */
- /** 无条件跳转(Jump) */
+ /** 无条件跳转(Jump),直接跳转到指定标签位置 */
JUMP,
- /** 条件跳转(Jump if zero),若条件为 0 则跳转 */
+ /** 条件跳转(Jump if zero),如果条件为 0 则跳转 */
JUMP_IF_ZERO,
- /** 标签(IRLabel),跳转目标位置 */
+ /** 标签定义(Label),作为跳转目标使用 */
LABEL,
/* ───── 函数调用相关 ───── */
- /** 函数调用(Call) */
+ /** 函数调用(Call),可能带返回值和参数 */
CALL,
- /** 返回(Return) */
+ /** 函数返回(Return),结束当前函数执行,可返回值 */
RET
}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java
index 02a72f7..ce8f678 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java
@@ -5,23 +5,46 @@ import org.jcnc.snow.compiler.ir.instruction.IRJumpInstruction;
import org.jcnc.snow.compiler.ir.instruction.IRReturnInstruction;
/**
- * 一个示例访问者,实现 IRVisitor,用于打印 IR 指令信息。
+ * IRPrinter —— 一个示例访问者(Visitor),用于打印 IR 指令的信息。
+ *
+ * 本类实现了 IRVisitor 接口,用于演示如何使用访问者模式处理 IRInstruction 子类。
+ * 每个 visit 方法负责处理特定类型的 IR 指令。此实现以控制台输出(System.out)形式展示指令内容。
+ *
+ * 子类可扩展该类以进行更复杂的打印或格式化,或添加对更多 IR 指令类型的支持。
*/
public abstract class IRPrinter implements IRVisitor {
+
+ /**
+ * 处理 IRAddInstruction 类型的指令。
+ * 打印加法指令的基本信息。
+ *
+ * @param inst 被访问的加法指令
+ */
@Override
public void visit(IRAddInstruction inst) {
System.out.println("Add: " + inst);
}
+ /**
+ * 处理 IRJumpInstruction 类型的指令。
+ * 打印跳转指令的基本信息。
+ *
+ * @param inst 被访问的跳转指令
+ */
@Override
public void visit(IRJumpInstruction inst) {
System.out.println("Jump: " + inst);
}
+ /**
+ * 处理 IRReturnInstruction 类型的指令。
+ * 打印返回指令的基本信息。
+ *
+ * @param inst 被访问的返回指令
+ */
@Override
public void visit(IRReturnInstruction inst) {
System.out.println("Return: " + inst);
}
- // 你可以继续添加对其他 IRInstruction 子类的 visit 方法
}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IRProgram.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IRProgram.java
index 0baf09c..67835d2 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/core/IRProgram.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRProgram.java
@@ -7,10 +7,12 @@ import java.util.List;
/**
* IRProgram 表示一份完整的中间表示(IR)程序。
*
- * 每个 IRProgram 由多个 IRFunction 组成,
- * 是编译器后端进行目标代码生成的核心数据结构。
+ * 本类作为编译器后端的主要数据结构之一,承载着所有 IRFunction 的集合。
+ * 每个函数封装一段 IR 指令序列,整体表示源代码编译后的结构化中间结果。
+ * 通常用于代码生成、优化、分析等阶段。
*/
public final class IRProgram {
+
/** 存储程序中所有函数的列表 */
private final List
+ * 返回的列表不能被外部修改,确保 IRProgram 的封装性和安全性。
*
* @return 包含所有 IRFunction 的只读列表
*/
@@ -34,7 +38,7 @@ public final class IRProgram {
/**
* 将整个 IRProgram 转换为字符串表示,方便打印或调试。
- * 每个函数占据单独一行。
+ * 每个函数调用其 toString 方法,占据单独一行。
*
* @return 程序的字符串表示
*/
@@ -46,4 +50,4 @@ public final class IRProgram {
}
return sb.toString();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IRValue.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IRValue.java
index e7268be..9439a34 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/core/IRValue.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRValue.java
@@ -5,18 +5,26 @@ import org.jcnc.snow.compiler.ir.value.IRLabel;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
/**
- * IRValue 表示在中间表示(IR)系统中可用于指令操作数的基本单位。
+ * IRValue —— 表示在中间表示(IR)系统中可作为指令操作数的基本单位。
*
- * 支持的具体类型包括:
+ * 本接口定义了 IR 指令可接受的值类型,是一个“值对象”的抽象。
+ * 所有实现 IRInstruction 的类在定义操作数时,其元素类型均为 IRValue。
+ *
+ * 典型用途包括操作数、跳转目标、返回值、函数参数等。
+ *
+ * 支持的具体子类型包括:
*
- * 本接口使用 sealed 限定,明确列出了所有允许的实现子类型,
- * 有助于在编译期进行穷尽性对齐和类型安全检查。
+ * 本接口为
+ * 本接口定义了“访问者模式”的核心机制。通过将每种 IRInstruction 子类对应为一个独立的 visit 方法,
+ * 可实现类型安全的指令操作逻辑分离,例如打印、优化、代码生成等。
+ *
+ * 使用场景包括:
+ *
- * 支持的操作符由 IROpCode 定义,例如加法、减法、乘法、除法等。
- * 将 lhs 和 rhs 两个操作数进行指定 OP 运算,并将结果存储到 dest 虚拟寄存器中。
+ * 该类用于描述形如 a = b + c 或 a = x * y 的二元运算指令。
+ * 运算类型(OP)由 {@link IROpCode} 指定,包括加法、减法、乘法、除法等。
+ * 左右操作数为 IRValue 类型,结果保存在目标虚拟寄存器 dest 中。
*/
public final class BinaryOperationInstruction extends IRInstruction {
- /** 二元运算操作符,如 ADD、SUB、MUL、DIV 等 */
+
+ /** 指令操作符,如 ADD_I32、SUB_I32 等,取自 IROpCode 枚举 */
private final IROpCode op;
- /** 运算结果存放的目标虚拟寄存器 */
+ /** 运算结果将写入的目标虚拟寄存器 */
private final IRVirtualRegister dest;
- /** 左操作数 */
+ /** 运算的左操作数 */
private final IRValue lhs;
- /** 右操作数 */
+ /** 运算的右操作数 */
private final IRValue rhs;
/**
- * 构造函数,创建一个二元运算指令实例。
+ * 构造函数,创建一个完整的二元运算指令。
*
- * @param op 指定的二元运算操作符
- * @param dest 结果存放的目标虚拟寄存器
- * @param lhs 左侧参与运算的操作数
- * @param rhs 右侧参与运算的操作数
+ * @param op 运算类型(加、减、乘、除等)
+ * @param dest 运算结果的目标寄存器
+ * @param lhs 左操作数
+ * @param rhs 右操作数
*/
public BinaryOperationInstruction(IROpCode op, IRVirtualRegister dest, IRValue lhs, IRValue rhs) {
this.op = op;
@@ -43,9 +45,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
}
/**
- * 获取指令的操作符。
+ * 获取该指令的操作符。
*
- * @return 当前指令使用的 IROpCode 操作符
+ * @return 运算类型(IROpCode)
*/
@Override
public IROpCode op() {
@@ -53,9 +55,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
}
/**
- * 获取指令结果存放的目标寄存器。
+ * 获取该指令的目标寄存器。
*
- * @return 目标虚拟寄存器
+ * @return 运算结果将写入的虚拟寄存器
*/
@Override
public IRVirtualRegister dest() {
@@ -63,9 +65,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
}
/**
- * 获取指令使用的操作数列表。
+ * 获取该指令使用的操作数。
*
- * @return 包含 lhs 和 rhs 的列表
+ * @return 一个包含左、右操作数的列表
*/
@Override
public List
+ * 本类是一个具体的 IRInstruction 子类,表示将两个值相加,并将结果写入目标寄存器的操作。
+ * 虽然功能与通用的 {@link BinaryOperationInstruction} 类似,但它作为更简化明确的指令实现,
+ * 通常用于测试或示例用途,也可为特殊优化保留独立形式。
*/
public class IRAddInstruction extends IRInstruction {
+
+ /** 运算结果存放的目标虚拟寄存器 */
private final IRVirtualRegister dest;
+
+ /** 左操作数 */
private final IRValue lhs;
+
+ /** 右操作数 */
private final IRValue rhs;
+ /**
+ * 构造函数,创建加法指令实例。
+ *
+ * @param dest 运算结果的存储位置
+ * @param lhs 加法左操作数
+ * @param rhs 加法右操作数
+ */
public IRAddInstruction(IRVirtualRegister dest, IRValue lhs, IRValue rhs) {
this.dest = dest;
this.lhs = lhs;
this.rhs = rhs;
}
+ /**
+ * 返回该指令的操作码:ADD_I32。
+ *
+ * @return 加法操作码
+ */
@Override
public IROpCode op() {
return IROpCode.ADD_I32;
}
+ /**
+ * 获取指令的目标寄存器。
+ *
+ * @return 运算结果存放的虚拟寄存器
+ */
@Override
public IRVirtualRegister dest() {
return dest;
}
+ /**
+ * 获取加法指令的两个操作数。
+ *
+ * @return 包含左、右操作数的列表
+ */
@Override
public List
+ * 该指令用于控制流结构中,实现无条件跳转到指定标签(label)。
+ * 是 if-else、循环、函数跳转等高级语言结构翻译到中间表示的重要组成部分。
*/
public class IRJumpInstruction extends IRInstruction {
+
+ /** 跳转目标的标签名 */
private final String label;
+ /**
+ * 构造函数,创建跳转指令。
+ *
+ * @param label 跳转目标标签的名称
+ */
public IRJumpInstruction(String label) {
this.label = label;
}
+ /**
+ * 获取该指令对应的操作码:JUMP。
+ *
+ * @return IROpCode.JUMP
+ */
@Override
public IROpCode op() {
return IROpCode.JUMP;
}
+ /**
+ * 获取跳转目标标签名。
+ *
+ * @return 标签名称字符串
+ */
public String label() {
return label;
}
+ /**
+ * 接受访问者,用于访问者模式处理。
+ *
+ * @param visitor 实现 IRVisitor 的访问者实例
+ */
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
+ /**
+ * 将指令转为字符串形式,便于打印与调试。
+ * 例如:jump L1
+ *
+ * @return 指令的字符串表示
+ */
@Override
public String toString() {
return "jump " + label;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java
index 61bd8b8..edf5034 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java
@@ -1,6 +1,5 @@
package org.jcnc.snow.compiler.ir.instruction;
-
import org.jcnc.snow.compiler.ir.core.IRInstruction;
import org.jcnc.snow.compiler.ir.core.IROpCode;
import org.jcnc.snow.compiler.ir.core.IRValue;
@@ -9,32 +8,64 @@ import org.jcnc.snow.compiler.ir.core.IRVisitor;
import java.util.List;
/**
- * 表示返回值的指令。
+ * IRReturnInstruction —— 表示一个带返回值的返回(ret)指令。
+ *
+ * 此指令用于函数结束时将某个值作为返回结果返回给调用者。
+ * 返回值可以是常量、寄存器或表达式的结果。
+ * 若不返回值,也可以扩展为 null 代表 void 函数。
*/
public class IRReturnInstruction extends IRInstruction {
+
+ /** 要返回的值,可以是常量、虚拟寄存器等 */
private final IRValue returnValue;
+ /**
+ * 构造函数,创建返回指令。
+ *
+ * @param returnValue 函数的返回值
+ */
public IRReturnInstruction(IRValue returnValue) {
this.returnValue = returnValue;
}
+ /**
+ * 获取该指令的操作码:RET。
+ *
+ * @return IROpCode.RET,表示返回操作
+ */
@Override
public IROpCode op() {
return IROpCode.RET;
}
+ /**
+ * 返回该指令的操作数列表(仅包含返回值)。
+ *
+ * @return 含一个元素的列表,即返回值
+ */
@Override
public List
- * 将字面量常量 k 加载到目标虚拟寄存器 dest 中,以便后续指令使用该常量值。
+ * 该指令的功能是将一个常量(字面量或编译期已知值)加载到一个虚拟寄存器中,
+ * 供后续指令使用。例如,在表达式计算、参数传递、初始化等场景中常用。
*/
public final class LoadConstInstruction extends IRInstruction {
- /**
- * 要加载的常量值
- */
+
+ /** 要加载的常量值,类型为 IRConstant */
private final IRConstant k;
- /**
- * 存放常量的目标虚拟寄存器
- */
+ /** 存放常量结果的目标虚拟寄存器 */
private final IRVirtualRegister dest;
/**
- * 构造函数,创建一个常量加载指令实例。
+ * 构造函数,创建常量加载指令。
*
- * @param dest 目标寄存器,用于存放常量值
- * @param k 要加载的常量
+ * @param dest 存放常量的目标虚拟寄存器
+ * @param k 要加载的常量值
*/
public LoadConstInstruction(IRVirtualRegister dest, IRConstant k) {
this.dest = dest;
@@ -37,9 +35,9 @@ public final class LoadConstInstruction extends IRInstruction {
}
/**
- * 获取此指令的操作符,恒为 CONST。
+ * 获取该指令的操作码,固定为 CONST。
*
- * @return 操作符 IROpCode.CONST
+ * @return IROpCode.CONST
*/
@Override
public IROpCode op() {
@@ -47,9 +45,9 @@ public final class LoadConstInstruction extends IRInstruction {
}
/**
- * 获取指令结果存放的目标寄存器。
+ * 获取指令的目标虚拟寄存器。
*
- * @return 存放常量的虚拟寄存器
+ * @return 用于存放常量的寄存器
*/
@Override
public IRVirtualRegister dest() {
@@ -57,9 +55,9 @@ public final class LoadConstInstruction extends IRInstruction {
}
/**
- * 获取此指令的操作数列表,仅包含要加载的常量 k。
+ * 获取该指令的操作数(仅包含要加载的常量)。
*
- * @return 包含常量 k 的单元素列表
+ * @return 含一个元素(k)的操作数列表
*/
@Override
public List
- * 支持两种形式:
- *
+ * 与 {@link IRReturnInstruction} 类似,但更通用,适配多种函数返回风格。
*/
public final class ReturnInstruction extends IRInstruction {
+
/**
- * 要返回的虚拟寄存器;
- * 如果是 void 返回,则为 null
+ * 返回值所在的虚拟寄存器。
+ * 如果为 null,则代表函数无返回值(即 void)。
*/
private final IRVirtualRegister value;
/**
- * 构造函数,创建一个返回指令实例。
+ * 构造函数,创建返回指令实例。
*
- * @param value 要返回的寄存器;
- * 如果函数不返回值(void),则传入 null
+ * @param value 若函数有返回值,传入对应虚拟寄存器;
+ * 若为 void 函数,则传 null。
*/
public ReturnInstruction(IRVirtualRegister value) {
this.value = value;
}
/**
- * 获取此指令的操作符,恒为 RET。
+ * 返回该指令的操作码类型:RET。
*
- * @return 操作符 IROpCode.RET
+ * @return IROpCode.RET
*/
@Override
public IROpCode op() {
@@ -47,11 +46,9 @@ public final class ReturnInstruction extends IRInstruction {
}
/**
- * 获取此指令的操作数列表:
- *
- * 格式:
- *
- * 支持的操作符由 IROpCode 定义,例如:
+ * 用于对单个操作数 val 执行指定的一元运算 OP(例如取负 NEG),
+ * 并将结果写入目标虚拟寄存器 dest。
+ *
+ * 支持的操作由 {@link IROpCode} 定义,目前常见的一元操作包括:
*
- * 示例:"v1 = NEG v2"
+ * 将该指令格式化为字符串,便于打印与调试。
+ * 形式:dest = OP val,例如:v1 = NEG v2
*
- * @return 指令的字符串形式,用于打印和调试
+ * @return 字符串形式的指令
*/
@Override
public String toString() {
return dest + " = " + op + " " + val;
}
-
+ /**
+ * 接受访问者访问该指令,实现访问者模式。
+ *
+ * @param visitor 访问者实例
+ */
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java b/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java
index 7bf69c0..01eaf2d 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java
@@ -3,18 +3,26 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
- * IRConstant 表示中间表示(IR)系统中的常量值。
+ * IRConstant —— 表示中间表示(IR)系统中的常量值。
*
- * 常量是不可变的字面量或编译期计算结果,
- * 可以是整数、浮点数、字符串等类型。
- * 在 IR 中,常量直接作为操作数使用,而不需要寄存器。
+ * 常量用于表示在编译期间已知的不可变值,例如字面整数、浮点数、布尔值或字符串。
+ * 与 {@link org.jcnc.snow.compiler.ir.value.IRVirtualRegister} 不同,常量不需要通过寄存器存储,
+ * 可直接作为 IR 指令的操作数使用。
+ *
+ * 典型应用:
+ * - 加载常量指令:v1 = CONST 42
+ * - 计算表达式:v2 = ADD v1, 100
*/
public record IRConstant(Object value) implements IRValue {
/**
- * 将常量值转换为字符串表示,用于 IR 指令打印和调试。
+ * 将常量值转换为字符串,用于打印 IR 指令或调试输出。
+ *
+ * 例如:
+ * - 整数常量:42
+ * - 字符串常量:"hello"
*
- * @return 常量的字符串形式
+ * @return 常量的字符串表示
*/
@Override
public String toString() {
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/value/IRLabel.java b/src/main/java/org/jcnc/snow/compiler/ir/value/IRLabel.java
index 4ac77c5..1bbeac8 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/value/IRLabel.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/value/IRLabel.java
@@ -3,21 +3,24 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
- * IRLabel 表示中间表示(IR)系统中的跳转目标标签。
+ * IRLabel —— 表示中间表示(IR)系统中的跳转目标标签。
*
- * 在控制流指令(如 JUMP、JUMP_IF_ZERO、JUMP_IF_NONZERO 等)中,
- * 标签用于标识跳转目的地,确保程序执行流程的可控分支。
- * 本类通过唯一的字符串名称 name 来标识一个标签实例。
+ * 标签用于控制流指令(如 JUMP、JUMP_IF_ZERO 等)中,
+ * 作为程序执行跳转的目的地,是 IR 控制流图(CFG)中的基本构建块。
*
- * IRLabel 同时实现 IRValue 接口,可以直接作为操作数传递给 IRInstruction。
+ * 每个标签由一个唯一的名称(String name)标识,
+ * 可用于生成目标代码中的符号标签或跳转地址。
+ *
+ * 该类实现了 {@link IRValue} 接口,因此也可被视为指令操作数,
+ * 在某些 IRInstruction 中以参数形式出现(如条件跳转目标)。
*/
public record IRLabel(String name) implements IRValue {
/**
- * 将标签转换为字符串表示,用于 IR 打印和调试。
- * 格式为:name:,例如 "L1:"
+ * 返回标签的字符串形式,便于打印或调试。
+ * 通常表示为带冒号的形式,例如 "L1:"。
*
- * @return 带冒号的标签字符串
+ * @return 格式化后的标签字符串
*/
@Override
public String toString() {
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/value/IRVirtualRegister.java b/src/main/java/org/jcnc/snow/compiler/ir/value/IRVirtualRegister.java
index 1dab9a1..f4bdaa3 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/value/IRVirtualRegister.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/value/IRVirtualRegister.java
@@ -3,28 +3,32 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
- * IRVirtualRegister 表示一个静态单赋值(SSA)形式的虚拟寄存器。
+ * IRVirtualRegister —— 表示一个静态单赋值(SSA)形式的虚拟寄存器。
+ *
+ * 在 IR 系统中,虚拟寄存器用于存储每个中间计算结果,是 SSA(Static Single Assignment)形式的核心。
+ * 每个虚拟寄存器在程序中只被赋值一次,其值来源于一条明确的指令输出。
*
- * 在中间表示(IR)系统中,每个中间计算结果都分配到一个唯一的虚拟寄存器。
* 特点:
* This opcode is typically used to negate an byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine. This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine. This method retrieves the byte8 value from the operand stack, negates it, and pushes the result back onto the operand stack. This opcode is typically used to negate an double64 value, making it a fundamental operation for arithmetic logic within the virtual machine. This opcode is typically used to negate a double64 value, making it a fundamental operation for arithmetic logic within the virtual machine. This method retrieves the double64 value from the operand stack, negates it, and pushes the result back onto the operand stack. This opcode is typically used to negate an float32 value, making it a fundamental operation for arithmetic logic within the virtual machine. This opcode is typically used to negate a float32 value, making it a fundamental operation for arithmetic logic within the virtual machine. This method retrieves the float32 value from the operand stack, negates it, and pushes the result back onto the operand stack. This opcode is typically used to negate an long64 value, making it a fundamental operation for arithmetic logic within the virtual machine. This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine. This method retrieves the long64 value from the operand stack, negates it, and pushes the result back onto the operand stack. This opcode is typically used to negate an short16 value, making it a fundamental operation for arithmetic logic within the virtual machine. This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine. This method retrieves the short16 value from the operand stack, negates it, and pushes the result back onto the operand stack. This opcode is implemented by the {@link SPushCommand} class, which defines its specific execution logic. Execution Steps: This opcode is implemented by the {@link DPushCommand} class, which defines its specific execution logic. Execution Steps:
- *
+ *
* sealed interface,仅允许指定的子类型实现它。
+ * 这保证了类型系统的封闭性,便于编译器在处理 IRValue 时进行穷尽性检查,
+ * 增强类型安全与维护性。
+ *
+ *
+ *
+ * 每添加一种新的指令子类,通常也需在本接口中添加对应的 visit 方法,以保持访问能力的完备。
*/
public interface IRVisitor {
+
+ /**
+ * 访问加法指令(简化形式)。
+ */
void visit(IRAddInstruction inst);
+
+ /**
+ * 访问跳转指令。
+ */
void visit(IRJumpInstruction inst);
+
+ /**
+ * 访问返回指令(简化形式)。
+ */
void visit(IRReturnInstruction inst);
+
+ /**
+ * 访问通用的二元运算指令,如 ADD_I32、SUB_I32 等。
+ */
void visit(BinaryOperationInstruction inst);
+
+ /**
+ * 访问加载常量的指令(将常量加载到虚拟寄存器)。
+ */
void visit(LoadConstInstruction inst);
+
+ /**
+ * 访问更通用的返回指令(可带返回值)。
+ */
void visit(ReturnInstruction inst);
+
+ /**
+ * 访问一元运算指令,如 NEG_I32。
+ */
void visit(UnaryOperationInstruction inst);
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/BinaryOperationInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/BinaryOperationInstruction.java
index 22f6b10..e42df97 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/BinaryOperationInstruction.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/BinaryOperationInstruction.java
@@ -9,31 +9,33 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
- * BinaryOperationInstruction 表示一个二元运算指令,格式:dest = lhs OP rhs
+ * BinaryOperationInstruction —— 表示一个二元运算指令,格式为:dest = lhs OP rhs
*
- *
- *
- * 返回指令用于结束函数执行,并将可选的返回值传递给调用者。
+ * 此类用于描述函数执行完毕后的返回操作。支持两种返回形式:
+ * - 无返回值(void):生成无参的 RET 指令
+ * - 有返回值:将指定虚拟寄存器中的值返回给调用者
+ *
- *
+ * 获取该指令的操作数。
+ * 如果为 void 返回,则返回空列表;
+ * 否则返回一个仅包含返回寄存器的列表。
*
* @return 操作数列表
*/
@@ -61,33 +58,33 @@ public final class ReturnInstruction extends IRInstruction {
}
/**
- * 获取要返回的寄存器。
+ * 获取返回值所在的虚拟寄存器(如有)。
*
- * @return 返回值寄存器;如果为 void 返回,则为 null
+ * @return 返回值寄存器,或 null(表示 void)
*/
public IRVirtualRegister value() {
return value;
}
/**
- * 将返回指令转换为字符串形式,便于打印和调试。
- *
- *
+ * 转换为字符串形式,便于调试与输出。
+ * - 无返回值:RET
+ * - 有返回值:RET v1
*
- * @return 指令的字符串表示
+ * @return 字符串表示的返回指令
*/
@Override
public String toString() {
return value == null ? "RET" : "RET " + value;
}
-
+ /**
+ * 接受访问者对象,实现访问者模式分发。
+ *
+ * @param visitor 实现 IRVisitor 的访问者
+ */
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/UnaryOperationInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/UnaryOperationInstruction.java
index 8ee8e84..25b9e96 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/UnaryOperationInstruction.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/UnaryOperationInstruction.java
@@ -9,31 +9,33 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
- * UnaryOperationInstruction 表示一个一元运算指令,格式:dest = OP val
+ * UnaryOperationInstruction —— 表示一个一元运算指令,格式:dest = OP val
*
- *
- *
- * 将单一操作数 val 进行指定 OP 运算,并将结果存储到目标寄存器 dest。
*/
public final class UnaryOperationInstruction extends IRInstruction {
- /** 一元运算操作符,如 NEG、NOT 等 */
+
+ /** 一元运算操作符(如 NEG_I32) */
private final IROpCode op;
- /** 运算结果存放的目标虚拟寄存器 */
+ /** 运算结果写入的目标虚拟寄存器 */
private final IRVirtualRegister dest;
- /** 一元运算的操作数 */
+ /** 被操作的值(唯一操作数) */
private final IRValue val;
/**
- * 构造函数,创建一个一元运算指令实例。
+ * 构造函数,创建一元运算指令。
*
- * @param op 指定的一元操作符
- * @param dest 运算结果存放的目标寄存器
+ * @param op 一元运算操作符
+ * @param dest 运算结果目标寄存器
* @param val 参与运算的操作数
*/
public UnaryOperationInstruction(IROpCode op, IRVirtualRegister dest, IRValue val) {
@@ -43,9 +45,9 @@ public final class UnaryOperationInstruction extends IRInstruction {
}
/**
- * 获取此指令对应的操作符。
+ * 获取该指令的操作码。
*
- * @return 当前指令使用的一元操作符
+ * @return 一元运算的操作码(如 NEG_I32)
*/
@Override
public IROpCode op() {
@@ -53,9 +55,9 @@ public final class UnaryOperationInstruction extends IRInstruction {
}
/**
- * 获取指令结果存放的目标寄存器。
+ * 获取该指令的目标寄存器。
*
- * @return 目标虚拟寄存器
+ * @return 运算结果的目标寄存器
*/
@Override
public IRVirtualRegister dest() {
@@ -63,9 +65,9 @@ public final class UnaryOperationInstruction extends IRInstruction {
}
/**
- * 获取此指令的操作数列表,仅包含一个操作数 val。
+ * 获取指令的操作数(仅一个)。
*
- * @return 单元素列表,其中元素为 val
+ * @return 单元素列表,仅包含 val
*/
@Override
public List
- *
*
- * IRVirtualRegister 同时实现 IRValue 接口,可作为 IRInstruction 的操作数。
+ * 适用于表达式求值、参数传递、函数返回值、临时变量等所有中间值场景。
*
- * @param id 寄存器的唯一编号
+ * @param id 寄存器的唯一编号,通常从 0 开始递增
*/
public record IRVirtualRegister(int id) implements IRValue {
/**
- * 将虚拟寄存器转换为字符串表示,格式为 "%