提高性能,增加注释

This commit is contained in:
Luke 2025-05-09 11:17:49 +08:00
parent 3dc67f3da9
commit 49deeef9fd
29 changed files with 427 additions and 195 deletions

View File

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

View File

@ -4,13 +4,43 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* IRInstruction 所有 IR 指令的抽象基类
* IRInstruction 所有 IR中间表示指令的抽象基类
* <p>
* 本类定义了编译器中间表示系统中所有指令的基本结构和行为
* 子类需实现具体的操作码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<IRValue> operands() { return List.of(); }
/** 访问者模式接口 */
/**
* 接收一个 IRVisitor 实例实现访问者模式的入口
* 子类必须实现此方法以允许访问者根据具体类型进行相应处理
*
* @param visitor 实现 IRVisitor 接口的访问者实例
*/
public abstract void accept(IRVisitor visitor);
}

View File

@ -3,74 +3,76 @@ package org.jcnc.snow.compiler.ir.core;
/**
* IROpCode IR 层支持的操作码Opcode枚举类型
* <p>
* 每种操作码代表一条基本指令的种类 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
}

View File

@ -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 指令的信息
* <p>
* 本类实现了 IRVisitor 接口用于演示如何使用访问者模式处理 IRInstruction 子类
* 每个 visit 方法负责处理特定类型的 IR 指令此实现以控制台输出System.out形式展示指令内容
* <p>
* 子类可扩展该类以进行更复杂的打印或格式化或添加对更多 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 方法
}

View File

@ -7,10 +7,12 @@ import java.util.List;
/**
* IRProgram 表示一份完整的中间表示IR程序
* <p>
* 每个 IRProgram 由多个 IRFunction 组成
* 是编译器后端进行目标代码生成的核心数据结构
* 本类作为编译器后端的主要数据结构之一承载着所有 IRFunction 的集合
* 每个函数封装一段 IR 指令序列整体表示源代码编译后的结构化中间结果
* 通常用于代码生成优化分析等阶段
*/
public final class IRProgram {
/** 存储程序中所有函数的列表 */
private final List<IRFunction> functions = new ArrayList<>();
@ -25,6 +27,8 @@ public final class IRProgram {
/**
* 获取程序中所有函数的不可变视图
* <p>
* 返回的列表不能被外部修改确保 IRProgram 的封装性和安全性
*
* @return 包含所有 IRFunction 的只读列表
*/
@ -34,7 +38,7 @@ public final class IRProgram {
/**
* 将整个 IRProgram 转换为字符串表示方便打印或调试
* 每个函数占据单独一行
* 每个函数调用其 toString 方法占据单独一行
*
* @return 程序的字符串表示
*/

View File

@ -5,17 +5,25 @@ import org.jcnc.snow.compiler.ir.value.IRLabel;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
/**
* IRValue 表示在中间表示IR系统中可用于指令操作数的基本单位
* IRValue 表示在中间表示IR系统中可作为指令操作数的基本单位
* <p>
* 支持的具体类型包括
* 本接口定义了 IR 指令可接受的值类型是一个值对象的抽象
* 所有实现 IRInstruction 的类在定义操作数时其元素类型均为 IRValue
* <p>
* 典型用途包括操作数跳转目标返回值函数参数等
* <p>
* 支持的具体子类型包括
* <ul>
* <li>{@link IRVirtualRegister} 虚拟寄存器代表计算中间结果的临时存储</li>
* <li>{@link IRConstant} 常量值表示字面量或计算常量</li>
* <li>{@link IRLabel} 跳转标签用于控制流跳转目标</li>
* <li>{@link IRVirtualRegister} 虚拟寄存器用于存储计算结果或中间值</li>
* <li>{@link IRConstant} 常量值如字面整型常数等</li>
* <li>{@link IRLabel} 跳转标签用于表示代码中的控制流目标</li>
* </ul>
*
* <p>
* 本接口使用 sealed 限定明确列出了所有允许的实现子类型
* 有助于在编译期进行穷尽性对齐和类型安全检查
* 本接口为 <code>sealed interface</code>仅允许指定的子类型实现它
* 这保证了类型系统的封闭性便于编译器在处理 IRValue 时进行穷尽性检查
* 增强类型安全与维护性
* </p>
*/
public sealed interface IRValue
permits IRVirtualRegister, IRConstant, IRLabel {

View File

@ -3,14 +3,54 @@ package org.jcnc.snow.compiler.ir.core;
import org.jcnc.snow.compiler.ir.instruction.*;
/**
* IRVisitor 访问者接口用于对不同类型的 IR 指令进行操作如打印优化等
* IRVisitor 访问者接口用于对不同类型的 IR 指令进行操作
* <p>
* 本接口定义了访问者模式的核心机制通过将每种 IRInstruction 子类对应为一个独立的 visit 方法
* 可实现类型安全的指令操作逻辑分离例如打印优化代码生成等
* <p>
* 使用场景包括
* <ul>
* <li>IRPrinter打印每条 IR 指令的内容</li>
* <li>IROptimizer IR 进行模式匹配和重写优化</li>
* <li>IRCodeGenerator IR 转换为目标平台指令</li>
* </ul>
*
* 每添加一种新的指令子类通常也需在本接口中添加对应的 visit 方法以保持访问能力的完备
*/
public interface IRVisitor {
/**
* 访问加法指令简化形式
*/
void visit(IRAddInstruction inst);
/**
* 访问跳转指令
*/
void visit(IRJumpInstruction inst);
/**
* 访问返回指令简化形式
*/
void visit(IRReturnInstruction inst);
/**
* 访问通用的二元运算指令 ADD_I32SUB_I32
*/
void visit(BinaryOperationInstruction inst);
/**
* 访问加载常量的指令将常量加载到虚拟寄存器
*/
void visit(LoadConstInstruction inst);
/**
* 访问更通用的返回指令可带返回值
*/
void visit(ReturnInstruction inst);
/**
* 访问一元运算指令 NEG_I32
*/
void visit(UnaryOperationInstruction inst);
}

View File

@ -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
* <p>
* 支持的操作符由 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<IRValue> operands() {
@ -73,16 +75,21 @@ public final class BinaryOperationInstruction extends IRInstruction {
}
/**
* 将指令格式化为字符串样式dest = op lhs, rhs
* 转换为字符串格式便于调试与打印
* v1 = ADD_I32 v2, v3
*
* @return 指令的字符串表示方便打印与调试
* @return 指令的字符串表示形式
*/
@Override
public String toString() {
return dest + " = " + op + " " + lhs + ", " + rhs;
}
/**
* 接受访问者对象实现访问者模式分发逻辑
*
* @param visitor 实现 IRVisitor 的访问者对象
*/
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);

View File

@ -9,39 +9,82 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* 表示一个加法指令形如dest = op1 + op2
* IRAddInstruction 表示一个加法指令形如dest = lhs + rhs
* <p>
* 本类是一个具体的 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<IRValue> operands() {
return List.of(lhs, rhs);
}
/**
* 使用访问者处理当前加法指令
*
* @param visitor 实现 IRVisitor 的访问者对象
*/
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
/**
* 返回指令的字符串形式方便调试
* 例如v1 = v2 + v3
*
* @return 字符串表示形式
*/
@Override
public String toString() {
return dest + " = " + lhs + " + " + rhs;

View File

@ -5,29 +5,60 @@ import org.jcnc.snow.compiler.ir.core.IROpCode;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
/**
* 表示无条件跳转到标签的指令
* IRJumpInstruction 表示一个无条件跳转jump IR 指令
* <p>
* 该指令用于控制流结构中实现无条件跳转到指定标签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;

View File

@ -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,30 +8,62 @@ import org.jcnc.snow.compiler.ir.core.IRVisitor;
import java.util.List;
/**
* 表示返回值的指令
* IRReturnInstruction 表示一个带返回值的返回ret指令
* <p>
* 此指令用于函数结束时将某个值作为返回结果返回给调用者
* 返回值可以是常量寄存器或表达式的结果
* 若不返回值也可以扩展为 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<IRValue> operands() {
return List.of(returnValue);
}
/**
* 接受访问者处理该指令适用于访问者模式
*
* @param visitor 实现了 IRVisitor 的访问者对象
*/
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
/**
* 转换为字符串形式便于调试与打印
* 示例ret v1
*
* @return 字符串形式的返回指令
*/
@Override
public String toString() {
return "ret " + returnValue;

View File

@ -10,26 +10,24 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* LoadConstInstruction 表示一个常量加载指令格式dest = CONST k
* LoadConstInstruction 表示一个常量加载指令格式dest = CONST k
* <p>
* 将字面量常量 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<IRValue> operands() {
@ -67,16 +65,21 @@ public final class LoadConstInstruction extends IRInstruction {
}
/**
* 将指令转换为字符串表示格式dest = CONST k
* 返回该指令的字符串形式便于调试或打印
* 例如v1 = CONST 42
*
* @return 指令的字符串形式便于打印和调试
* @return 指令的字符串表示
*/
@Override
public String toString() {
return dest + " = CONST " + k;
}
/**
* 接受访问者模式处理
*
* @param visitor 实现 IRVisitor 的访问者对象
*/
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);

View File

@ -9,37 +9,36 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* ReturnInstruction 表示函数返回指令格式return [value]
* ReturnInstruction 表示函数返回指令格式RET RET <value>
* <p>
* 支持两种形式
* <ul>
* <li>无返回值void: value null生成无参 RET 指令</li>
* <li>有返回值: value 为要返回的虚拟寄存器生成带参数 RET 指令</li>
* </ul>
*
* 返回指令用于结束函数执行并将可选的返回值传递给调用者
* 此类用于描述函数执行完毕后的返回操作支持两种返回形式
* - 无返回值void生成无参的 RET 指令
* - 有返回值将指定虚拟寄存器中的值返回给调用者
* <p>
* {@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 {
}
/**
* 获取此指令的操作数列表
* <ul>
* <li>如果无返回值返回空列表</li>
* <li>否则返回包含要返回的寄存器</li>
* </ul>
* 获取该指令的操作数
* 如果为 void 返回则返回空列表
* 否则返回一个仅包含返回寄存器的列表
*
* @return 操作数列表
*/
@ -61,31 +58,31 @@ public final class ReturnInstruction extends IRInstruction {
}
/**
* 获取返回的寄存器
* 获取返回值所在虚拟寄存器如有
*
* @return 返回值寄存器如果为 void 返回则为 null
* @return 返回值寄存器 null表示 void
*/
public IRVirtualRegister value() {
return value;
}
/**
* 将返回指令转换为字符串形式便于打印和调试
* <p>
* 格式
* <ul>
* <li>无返回值: "RET"</li>
* <li>有返回值: "RET <寄存器>"</li>
* </ul>
* 转换为字符串形式便于调试与输出
* - 无返回值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);

View File

@ -9,31 +9,33 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* UnaryOperationInstruction 表示一个一元运算指令格式dest = OP val
* UnaryOperationInstruction 表示一个一元运算指令格式dest = OP val
* <p>
* 支持的操作符由 IROpCode 定义例如
* 用于对单个操作数 val 执行指定的一元运算 OP例如取负 NEG
* 并将结果写入目标虚拟寄存器 dest
* <p>
* 支持的操作由 {@link IROpCode} 定义目前常见的一元操作包括
* <ul>
* <li>NEG 取负</li>
* <li>NOT 按位取反或逻辑非</li>
* <li>NEG_I32 整数取负dest = -val</li>
* <li>可扩展逻辑非按位非等</li>
* </ul>
*
* 将单一操作数 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<IRValue> operands() {
@ -73,18 +75,21 @@ public final class UnaryOperationInstruction extends IRInstruction {
}
/**
* 将一元运算指令转换为字符串表示格式dest = OP val
* <p>
* 示例"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);

View File

@ -3,18 +3,26 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
* IRConstant 表示中间表示IR系统中的常量值
* IRConstant 表示中间表示IR系统中的常量值
* <p>
* 常量是不可变的字面量或编译期计算结果
* 可以是整数浮点数字符串等类型
* IR 常量直接作为操作数使用而不需要寄存器
* 常量用于表示在编译期间已知的不可变值例如字面整数浮点数布尔值或字符串
* {@link org.jcnc.snow.compiler.ir.value.IRVirtualRegister} 不同常量不需要通过寄存器存储
* 可直接作为 IR 指令的操作数使用
* <p>
* 典型应用
* - 加载常量指令v1 = CONST 42
* - 计算表达式v2 = ADD v1, 100
*/
public record IRConstant(Object value) implements IRValue {
/**
* 将常量值转换为字符串表示用于 IR 指令打印和调试
* 将常量值转换为字符串用于打印 IR 指令或调试输出
* <p>
* 例如
* - 整数常量42
* - 字符串常量"hello"
*
* @return 常量的字符串形式
* @return 常量的字符串表示
*/
@Override
public String toString() {

View File

@ -3,21 +3,24 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
* IRLabel 表示中间表示IR系统中的跳转目标标签
* IRLabel 表示中间表示IR系统中的跳转目标标签
* <p>
* 在控制流指令 JUMPJUMP_IF_ZEROJUMP_IF_NONZERO
* 标签用于标识跳转目的地确保程序执行流程的可控分支
* 本类通过唯一的字符串名称 name 来标识一个标签实例
* 标签用于控制流指令 JUMPJUMP_IF_ZERO
* 作为程序执行跳转的目的地 IR 控制流图CFG中的基本构建块
* <p>
* IRLabel 同时实现 IRValue 接口可以直接作为操作数传递给 IRInstruction
* 每个标签由一个唯一的名称String name标识
* 可用于生成目标代码中的符号标签或跳转地址
* <p>
* 该类实现了 {@link IRValue} 接口因此也可被视为指令操作数
* 在某些 IRInstruction 中以参数形式出现如条件跳转目标
*/
public record IRLabel(String name) implements IRValue {
/**
* 将标签转换为字符串表示用于 IR 打印和调试
* 格式为name:例如 "L1:"
* 返回标签的字符串形式便于打印或调试
* 通常表示为带冒号的形式例如 "L1:"
*
* @return 带冒号的标签字符串
* @return 格式化后的标签字符串
*/
@Override
public String toString() {

View File

@ -3,25 +3,29 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
* IRVirtualRegister 表示一个静态单赋值SSA形式的虚拟寄存器
* IRVirtualRegister 表示一个静态单赋值SSA形式的虚拟寄存器
* <p>
* IR 系统中虚拟寄存器用于存储每个中间计算结果 SSAStatic Single Assignment形式的核心
* 每个虚拟寄存器在程序中只被赋值一次其值来源于一条明确的指令输出
* <p>
* 在中间表示IR系统中每个中间计算结果都分配到一个唯一的虚拟寄存器
* 特点
* <ul>
* <li>每个寄存器都有唯一的 id IRFunction.newRegister() 自动生成</li>
* <li>遵循 SSA 形式每个寄存器仅在创建时被赋值一次</li>
* <li>每个寄存器有唯一编号 {@code id} {@code IRFunction.newRegister()} 自动生成</li>
* <li>实现 {@link IRValue} 接口可作为 IRInstruction 的操作数</li>
* <li>具备良好的打印与调试格式%id</li>
* </ul>
*
* IRVirtualRegister 同时实现 IRValue 接口可作为 IRInstruction 的操作数
* 适用于表达式求值参数传递函数返回值临时变量等所有中间值场景
*
* @param id 寄存器的唯一编号
* @param id 寄存器的唯一编号通常从 0 开始递增
*/
public record IRVirtualRegister(int id) implements IRValue {
/**
* 将虚拟寄存器转换为字符串表示格式为 "%<id>"便于打印和调试
* 将虚拟寄存器转换为字符串格式方便输出和调试
* 格式为%<id>例如 %3 表示编号为 3 的虚拟寄存器
*
* @return 带有百分号前缀的寄存器编号字符串
* @return 格式化的字符串表示
*/
@Override
public String toString() {

View File

@ -56,12 +56,10 @@ public enum BuiltinType implements Type {
*/
@Override
public boolean isNumeric() {
switch (this) {
case BYTE, SHORT, INT, LONG, FLOAT, DOUBLE:
return true;
default:
return false;
}
return switch (this) {
case BYTE, SHORT, INT, LONG, FLOAT, DOUBLE -> true;
default -> false;
};
}
/**

View File

@ -16,7 +16,7 @@ import org.jcnc.snow.vm.module.OperandStack;
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
* <p>This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public class BNegCommand implements Command {
@ -29,7 +29,7 @@ public class BNegCommand implements Command {
}
/**
* Executes the virtual machine instruction's operation for negating an byte8 value.
* Executes the virtual machine instruction's operation for negating a byte8 value.
*
* <p>This method retrieves the byte8 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*

View File

@ -40,8 +40,7 @@ public class B2ICommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack,
LocalVariableStore localVariableStore, CallStack callStack) {
byte value = (byte) operandStack.pop();
int convertedValue = (int) value;
int convertedValue = (byte) operandStack.pop();
operandStack.push(convertedValue);
return currentPC + 1;
}

View File

@ -40,8 +40,7 @@ public class F2DCommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack,
LocalVariableStore localVariableStore, CallStack callStack) {
float value = (float) operandStack.pop();
double convertedValue = (double) value;
double convertedValue = (float) operandStack.pop();
operandStack.push(convertedValue);
return currentPC + 1;
}

View File

@ -40,8 +40,7 @@ public class I2DCommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack,
LocalVariableStore localVariableStore, CallStack callStack) {
int value = (int) operandStack.pop();
double convertedValue = (double) value;
double convertedValue = (int) operandStack.pop();
operandStack.push(convertedValue);
return currentPC + 1;
}

View File

@ -40,8 +40,7 @@ public class I2LCommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack,
LocalVariableStore localVariableStore, CallStack callStack) {
int value = (int) operandStack.pop();
long convertedValue = (long) value;
long convertedValue = (int) operandStack.pop();
operandStack.push(convertedValue);
return currentPC + 1;
}

View File

@ -40,8 +40,7 @@ public class S2ICommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack,
LocalVariableStore localVariableStore, CallStack callStack) {
short value = (short) operandStack.pop();
int convertedValue = (int) value;
int convertedValue = (short) operandStack.pop();
operandStack.push(convertedValue);
return currentPC + 1;
}

View File

@ -16,7 +16,7 @@ import org.jcnc.snow.vm.module.OperandStack;
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an double64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
* <p>This opcode is typically used to negate a double64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public class DNegCommand implements Command {
@ -29,7 +29,7 @@ public class DNegCommand implements Command {
}
/**
* Executes the virtual machine instruction's operation for negating an double64 value.
* Executes the virtual machine instruction's operation for negating a double64 value.
*
* <p>This method retrieves the double64 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*

View File

@ -16,7 +16,7 @@ import org.jcnc.snow.vm.module.OperandStack;
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an float32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
* <p>This opcode is typically used to negate a float32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public class FNegCommand implements Command {
@ -29,7 +29,7 @@ public class FNegCommand implements Command {
}
/**
* Executes the virtual machine instruction's operation for negating an float32 value.
* Executes the virtual machine instruction's operation for negating a float32 value.
*
* <p>This method retrieves the float32 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*

View File

@ -16,7 +16,7 @@ import org.jcnc.snow.vm.module.OperandStack;
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
* <p>This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public class LNegCommand implements Command {
@ -29,7 +29,7 @@ public class LNegCommand implements Command {
}
/**
* Executes the virtual machine instruction's operation for negating an long64 value.
* Executes the virtual machine instruction's operation for negating a long64 value.
*
* <p>This method retrieves the long64 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*

View File

@ -16,7 +16,7 @@ import org.jcnc.snow.vm.module.OperandStack;
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
* <p>This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public class SNegCommand implements Command {
@ -29,7 +29,7 @@ public class SNegCommand implements Command {
}
/**
* Executes the virtual machine instruction's operation for negating an short16 value.
* Executes the virtual machine instruction's operation for negating a short16 value.
*
* <p>This method retrieves the short16 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*

View File

@ -1288,7 +1288,7 @@ public class VMOpCode {
*/
public static final int L_PUSH = 112;
/**
* S_PUSH Opcode: Represents a stack operation that pushes an short16 value onto the operand stack.
* S_PUSH Opcode: Represents a stack operation that pushes a short16 value onto the operand stack.
* <p>This opcode is implemented by the {@link SPushCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
@ -1326,7 +1326,7 @@ public class VMOpCode {
*/
public static final int B_PUSH = 114;
/**
* I_PUSH Opcode: Represents a stack operation that pushes an double64 value onto the operand stack.
* I_PUSH Opcode: Represents a stack operation that pushes a double64 value onto the operand stack.
* <p>This opcode is implemented by the {@link DPushCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>