修改注释
This commit is contained in:
parent
b26ff57f4e
commit
919f68550f
@ -4,6 +4,7 @@ import org.jcnc.snow.compiler.ir.core.IRFunction;
|
||||
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
|
||||
import org.jcnc.snow.compiler.parser.ast.ParameterNode;
|
||||
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
|
||||
|
||||
/**
|
||||
* FunctionBuilder 负责将 AST 中的 FunctionNode 构建为可执行的 IRFunction。
|
||||
*
|
||||
|
||||
@ -8,36 +8,68 @@ import org.jcnc.snow.compiler.parser.ast.ReturnNode;
|
||||
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
|
||||
|
||||
/**
|
||||
* 负责语句节点到 IR 的转换。
|
||||
* StatementBuilder 负责将解析器生成的语句 AST 节点(StatementNode)
|
||||
* 转换为编译器中间表示(IR)中的指令序列。
|
||||
* <p>
|
||||
* 支持的语句类型包括:
|
||||
* <ul>
|
||||
* <li>表达式语句(ExpressionStatementNode)</li>
|
||||
* <li>赋值语句(AssignmentNode)</li>
|
||||
* <li>声明语句(DeclarationNode)</li>
|
||||
* <li>返回语句(ReturnNode)</li>
|
||||
* </ul>
|
||||
* 对于不支持的节点类型,方法会抛出 IllegalStateException。
|
||||
*/
|
||||
public class StatementBuilder {
|
||||
/** 当前的 IR 上下文,用于生成指令和管理作用域 */
|
||||
private final IRContext ctx;
|
||||
/** 用于生成表达式对应的 IR 寄存器和指令的构建器 */
|
||||
private final ExpressionBuilder exprBuilder;
|
||||
|
||||
/**
|
||||
* 构造函数,初始化 IR 上下文并创建 ExpressionBuilder 实例。
|
||||
*
|
||||
* @param ctx IR 上下文对象,包含当前函数的作用域、指令列表等信息
|
||||
*/
|
||||
public StatementBuilder(IRContext ctx) {
|
||||
this.ctx = ctx;
|
||||
this.exprBuilder = new ExpressionBuilder(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* 入口:根据不同语句类型分发
|
||||
* 根据不同的语句节点类型,将其转换为相应的 IR 指令:
|
||||
* <ul>
|
||||
* <li>ExpressionStatementNode:生成表达式指令,忽略返回值</li>
|
||||
* <li>AssignmentNode:生成右侧表达式指令,将结果绑定到变量(第一次声明或更新)</li>
|
||||
* <li>DeclarationNode:如带初始化器,则先生成初始化表达式指令,并声明变量;否则只声明变量</li>
|
||||
* <li>ReturnNode:如带返回表达式,则生成带返回值的指令;否则生成无返回值指令</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param stmt 要构建的语句 AST 节点
|
||||
* @throws IllegalStateException 如果遇到不支持的语句类型,则抛出此异常
|
||||
*/
|
||||
public void build(StatementNode stmt) {
|
||||
if (stmt instanceof ExpressionStatementNode(org.jcnc.snow.compiler.parser.ast.base.ExpressionNode expression)) {
|
||||
// 表达式语句: 仅生成表达式对应的 IR 指令,不关注结果
|
||||
if (stmt instanceof ExpressionStatementNode(
|
||||
org.jcnc.snow.compiler.parser.ast.base.ExpressionNode expression)) {
|
||||
exprBuilder.build(expression);
|
||||
return;
|
||||
}
|
||||
// 赋值语句: 先生成右侧表达式指令,获取寄存器,再声明或更新变量的值绑定
|
||||
if (stmt instanceof AssignmentNode(
|
||||
String variable, org.jcnc.snow.compiler.parser.ast.base.ExpressionNode value
|
||||
)) {
|
||||
IRVirtualRegister vr = exprBuilder.build(value);
|
||||
if (ctx.getScope().lookup(variable) == null) {
|
||||
// 首次赋值:声明变量并绑定寄存器
|
||||
ctx.getScope().declare(variable, vr);
|
||||
} else {
|
||||
// 变量已存在:更新绑定的寄存器
|
||||
ctx.getScope().put(variable, vr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 声明语句: 如有初始化表达式,则先构建初始化值并声明;否则直接声明变量
|
||||
if (stmt instanceof DeclarationNode dn) {
|
||||
if (dn.getInitializer().isPresent()) {
|
||||
IRVirtualRegister init = exprBuilder.build(dn.getInitializer().get());
|
||||
@ -47,6 +79,7 @@ public class StatementBuilder {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 返回语句: 区分有返回值和无返回值两种情况
|
||||
if (stmt instanceof ReturnNode rn) {
|
||||
if (rn.getExpression().isPresent()) {
|
||||
IRVirtualRegister vr = exprBuilder.build(rn.getExpression().get());
|
||||
@ -56,6 +89,7 @@ public class StatementBuilder {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 不支持的语句类型
|
||||
throw new IllegalStateException("Unsupported statement: " + stmt.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,79 +6,98 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表示一个函数级别的中间表示(IR)。
|
||||
* 每个 IRFunction 包含函数名称、指令列表(函数体)和用于管理寄存器编号的计数器。
|
||||
* IRFunction 表示一个函数级别的中间表示(IR)实体。
|
||||
* <p>
|
||||
* 每个 IRFunction 包含:
|
||||
* <ul>
|
||||
* <li>函数名称</li>
|
||||
* <li>函数体的指令列表</li>
|
||||
* <li>用于分配虚拟寄存器编号的计数器</li>
|
||||
* </ul>
|
||||
*
|
||||
* 该类提供虚拟寄存器分配、指令添加和调试输出等功能。
|
||||
*/
|
||||
public class IRFunction {
|
||||
// 函数的名称
|
||||
/** 函数名称 */
|
||||
private final String name;
|
||||
|
||||
// 存放函数体中的指令列表
|
||||
/** 存放函数体中所有中间表示指令 */
|
||||
private final List<IRInstruction> body = new ArrayList<>();
|
||||
|
||||
// 寄存器编号计数器,用于为新建的虚拟寄存器分配唯一编号
|
||||
/**
|
||||
* 虚拟寄存器编号计数器;
|
||||
* 每调用一次 newRegister(),计数器自增并分配唯一编号
|
||||
*/
|
||||
private int regCounter = 0;
|
||||
|
||||
/**
|
||||
* 构造函数,创建一个新的 IRFunction 实例。
|
||||
* 构造函数,初始化 IRFunction 实例并设置函数名称。
|
||||
*
|
||||
* @param name 函数的名称
|
||||
* @param name 函数名称
|
||||
*/
|
||||
public IRFunction(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/* —— API —— */
|
||||
/* —— 公共 API —— */
|
||||
|
||||
/**
|
||||
* 创建一个新的虚拟寄存器,并自动分配一个唯一的编号。
|
||||
* 创建并返回一个新的虚拟寄存器。
|
||||
*
|
||||
* @return 新建的虚拟寄存器
|
||||
* @return 分配了唯一编号的 IRVirtualRegister 实例
|
||||
*/
|
||||
public IRVirtualRegister newRegister() {
|
||||
return new IRVirtualRegister(regCounter++);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向函数体中添加一条指令。
|
||||
* 向函数体中添加一条中间表示指令。
|
||||
*
|
||||
* @param inst 要添加的中间表示指令
|
||||
* @param inst 要添加的 IRInstruction 对象
|
||||
*/
|
||||
public void add(IRInstruction inst) {
|
||||
body.add(inst);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取函数体的全部指令列表。
|
||||
* 获取函数体的所有中间表示指令。
|
||||
*
|
||||
* @return 包含所有指令的列表
|
||||
* @return 包含所有 IRInstruction 的列表
|
||||
*/
|
||||
public List<IRInstruction> body() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取函数的名称。
|
||||
* 获取该函数的名称。
|
||||
*
|
||||
* @return 函数名称
|
||||
* @return 函数名称字符串
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前已分配的寄存器数量。
|
||||
* 获取当前已分配的虚拟寄存器数量。
|
||||
*
|
||||
* @return 当前寄存器计数值
|
||||
* @return 当前的寄存器计数器值
|
||||
*/
|
||||
public int registerCount() {
|
||||
return regCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将整个函数(包括函数名和函数体)转换为字符串形式,便于打印或调试。
|
||||
* 将整个 IRFunction 对象格式化为字符串,便于打印和调试。
|
||||
* 输出示例:
|
||||
* <pre>
|
||||
* func 方法名 {
|
||||
* 指令1
|
||||
* 指令2
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @return 函数的字符串表示
|
||||
* @return 格式化后的函数字符串表示
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -86,4 +105,4 @@ public class IRFunction {
|
||||
body.forEach(i -> sb.append(" ").append(i).append("\n"));
|
||||
return sb.append('}').toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,36 +5,36 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IRProgram —— 表示一份完整的中间表示(IR)程序。
|
||||
* IRProgram 表示一份完整的中间表示(IR)程序。
|
||||
* <p>
|
||||
* 每个 IRProgram 由多个函数(IRFunction)组成,
|
||||
* 是编译器后端生成目标代码的基础单位。
|
||||
* 每个 IRProgram 由多个 IRFunction 组成,
|
||||
* 是编译器后端进行目标代码生成的核心数据结构。
|
||||
*/
|
||||
public final class IRProgram {
|
||||
// 存储程序中所有函数的列表
|
||||
/** 存储程序中所有函数的列表 */
|
||||
private final List<IRFunction> functions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 向程序中添加一个函数。
|
||||
* 向 IRProgram 中添加一个函数。
|
||||
*
|
||||
* @param fn 要添加的 IRFunction
|
||||
* @param fn 要添加的 IRFunction 对象
|
||||
*/
|
||||
public void add(IRFunction fn) {
|
||||
functions.add(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有函数的不可变列表。
|
||||
* 获取程序中所有函数的不可变视图。
|
||||
*
|
||||
* @return 包含所有 IRFunction 的不可修改视图
|
||||
* @return 包含所有 IRFunction 的只读列表
|
||||
*/
|
||||
public List<IRFunction> functions() {
|
||||
return Collections.unmodifiableList(functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将整个 IRProgram 转换成字符串表示。
|
||||
* 每个函数独占一行,适合打印调试。
|
||||
* 将整个 IRProgram 转换为字符串表示,方便打印或调试。
|
||||
* 每个函数占据单独一行。
|
||||
*
|
||||
* @return 程序的字符串表示
|
||||
*/
|
||||
@ -46,4 +46,4 @@ public final class IRProgram {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,16 +5,18 @@ import org.jcnc.snow.compiler.ir.value.IRLabel;
|
||||
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||
|
||||
/**
|
||||
* IRValue —— 表示在中间表示(IR)系统中能作为操作数使用的基本单位。
|
||||
* IRValue 表示在中间表示(IR)系统中可用于指令操作数的基本单位。
|
||||
* <p>
|
||||
* 包括:
|
||||
* • IRVirtualRegister(虚拟寄存器)
|
||||
* • IRConstant(常量)
|
||||
* • IRLabel(跳转标签)
|
||||
* <p>
|
||||
* 本接口使用 sealed 限定,明确列出所有允许实现它的子类型,
|
||||
* 保证类型安全,并便于在编译时做穷尽检查。
|
||||
* 支持的具体类型包括:
|
||||
* <ul>
|
||||
* <li>{@link IRVirtualRegister} —— 虚拟寄存器,代表计算中间结果的临时存储</li>
|
||||
* <li>{@link IRConstant} —— 常量值,表示字面量或计算常量</li>
|
||||
* <li>{@link IRLabel} —— 跳转标签,用于控制流跳转目标</li>
|
||||
* </ul>
|
||||
*
|
||||
* 本接口使用 sealed 限定,明确列出了所有允许的实现子类型,
|
||||
* 有助于在编译期进行穷尽性对齐和类型安全检查。
|
||||
*/
|
||||
public sealed interface IRValue
|
||||
permits IRVirtualRegister, IRConstant, IRLabel {
|
||||
}
|
||||
}
|
||||
@ -8,30 +8,31 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表示一个二元运算指令(Binary Operation Instruction)。
|
||||
* 格式为:dest = lhs (OP) rhs
|
||||
* 其中 dest 是结果寄存器,lhs 和 rhs 是操作数,OP 是操作符(如加法、减法等)。
|
||||
* BinaryOperationInstruction 表示一个二元运算指令,格式:dest = lhs OP rhs
|
||||
* <p>
|
||||
* 支持的操作符由 IROpCode 定义,例如加法、减法、乘法、除法等。
|
||||
* 将 lhs 和 rhs 两个操作数进行指定 OP 运算,并将结果存储到 dest 虚拟寄存器中。
|
||||
*/
|
||||
public final class BinaryOperationInstruction extends IRInstruction {
|
||||
// 二元操作符,例如加法、减法、乘法、除法等
|
||||
/** 二元运算操作符,如 ADD、SUB、MUL、DIV 等 */
|
||||
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;
|
||||
@ -41,9 +42,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此指令对应的操作符。
|
||||
* 获取指令的操作符。
|
||||
*
|
||||
* @return 操作符
|
||||
* @return 当前指令使用的 IROpCode 操作符
|
||||
*/
|
||||
@Override
|
||||
public IROpCode op() {
|
||||
@ -53,7 +54,7 @@ public final class BinaryOperationInstruction extends IRInstruction {
|
||||
/**
|
||||
* 获取指令结果存放的目标寄存器。
|
||||
*
|
||||
* @return 目标寄存器
|
||||
* @return 目标虚拟寄存器
|
||||
*/
|
||||
@Override
|
||||
public IRVirtualRegister dest() {
|
||||
@ -61,9 +62,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此指令所使用的操作数(左操作数和右操作数)。
|
||||
* 获取指令使用的操作数列表。
|
||||
*
|
||||
* @return 操作数列表
|
||||
* @return 包含 lhs 和 rhs 的列表
|
||||
*/
|
||||
@Override
|
||||
public List<IRValue> operands() {
|
||||
@ -71,10 +72,9 @@ public final class BinaryOperationInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指令转换成字符串表示,用于调试和打印。
|
||||
* 格式示例:v1 = add v2, v3
|
||||
* 将指令格式化为字符串,样式:dest = op lhs, rhs
|
||||
*
|
||||
* @return 字符串表示
|
||||
* @return 指令的字符串表示,方便打印与调试
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -9,22 +9,22 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表示常量加载指令(Load IRConstant Instruction)。
|
||||
* 格式为:dest = CONST k
|
||||
* 其中 dest 是结果寄存器,k 是要加载的常量值。
|
||||
* LoadConstInstruction 表示一个常量加载指令,格式:dest = CONST k
|
||||
* <p>
|
||||
* 将字面量常量 k 加载到目标虚拟寄存器 dest 中,以便后续指令使用该常量值。
|
||||
*/
|
||||
public final class LoadConstInstruction extends IRInstruction {
|
||||
// 要加载的常量值
|
||||
/** 要加载的常量值 */
|
||||
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;
|
||||
@ -44,7 +44,7 @@ public final class LoadConstInstruction extends IRInstruction {
|
||||
/**
|
||||
* 获取指令结果存放的目标寄存器。
|
||||
*
|
||||
* @return 目标虚拟寄存器
|
||||
* @return 存放常量的虚拟寄存器
|
||||
*/
|
||||
@Override
|
||||
public IRVirtualRegister dest() {
|
||||
@ -52,9 +52,9 @@ public final class LoadConstInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此指令所用的操作数(只有一个常量)。
|
||||
* 获取此指令的操作数列表,仅包含要加载的常量 k。
|
||||
*
|
||||
* @return 仅包含常量 k 的操作数列表
|
||||
* @return 包含常量 k 的单元素列表
|
||||
*/
|
||||
@Override
|
||||
public List<IRValue> operands() {
|
||||
@ -62,10 +62,9 @@ public final class LoadConstInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指令转换成字符串表示,用于调试和打印。
|
||||
* 格式示例:v1 = CONST 42
|
||||
* 将指令转换为字符串表示,格式:dest = CONST k
|
||||
*
|
||||
* @return 字符串表示
|
||||
* @return 指令的字符串形式,便于打印和调试
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -8,20 +8,28 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表示函数的返回指令(Return Instruction)。
|
||||
* 格式为:return [val]
|
||||
* ReturnInstruction 表示函数返回指令,格式:return [value]
|
||||
* <p>
|
||||
* - 如果是 void 返回(即没有返回值),val 为 null。
|
||||
* - 否则,返回指定寄存器中的值。
|
||||
* 支持两种形式:
|
||||
* <ul>
|
||||
* <li>无返回值(void): value 为 null,生成无参 RET 指令</li>
|
||||
* <li>有返回值: value 为要返回的虚拟寄存器,生成带参数 RET 指令</li>
|
||||
* </ul>
|
||||
*
|
||||
* 返回指令用于结束函数执行,并将可选的返回值传递给调用者。
|
||||
*/
|
||||
public final class ReturnInstruction extends IRInstruction {
|
||||
// 返回值对应的虚拟寄存器,如果是 void 返回则为 null
|
||||
/**
|
||||
* 要返回的虚拟寄存器;
|
||||
* 如果是 void 返回,则为 null
|
||||
*/
|
||||
private final IRVirtualRegister value;
|
||||
|
||||
/**
|
||||
* 构造函数,创建一个返回指令实例。
|
||||
*
|
||||
* @param value 要返回的虚拟寄存器,如果是 void 返回则传入 null
|
||||
* @param value 要返回的寄存器;
|
||||
* 如果函数不返回值(void),则传入 null
|
||||
*/
|
||||
public ReturnInstruction(IRVirtualRegister value) {
|
||||
this.value = value;
|
||||
@ -38,9 +46,11 @@ public final class ReturnInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此指令的操作数列表。
|
||||
* - 如果是 void 返回,返回空列表;
|
||||
* - 否则,返回包含返回值寄存器的列表。
|
||||
* 获取此指令的操作数列表:
|
||||
* <ul>
|
||||
* <li>如果无返回值,返回空列表</li>
|
||||
* <li>否则,返回包含要返回的寄存器</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return 操作数列表
|
||||
*/
|
||||
@ -50,24 +60,27 @@ public final class ReturnInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要返回的值(虚拟寄存器)。
|
||||
* 获取要返回的寄存器。
|
||||
*
|
||||
* @return 返回值寄存器,或 null(表示 void 返回)
|
||||
* @return 返回值寄存器;如果为 void 返回,则为 null
|
||||
*/
|
||||
public IRVirtualRegister value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将返回指令转换成字符串表示,用于调试和打印。
|
||||
* 格式示例:
|
||||
* - "RET" (无返回值)
|
||||
* - "RET v1"(返回寄存器 v1 的值)
|
||||
* 将返回指令转换为字符串形式,便于打印和调试。
|
||||
*
|
||||
* @return 字符串表示
|
||||
* 格式:
|
||||
* <ul>
|
||||
* <li>无返回值: "RET"</li>
|
||||
* <li>有返回值: "RET <寄存器>"</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return 指令的字符串表示
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return value == null ? "RET" : "RET " + value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,29 +8,32 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表示一元运算指令(Unary Operation Instruction)。
|
||||
* 格式为:dest = OP val
|
||||
* UnaryOperationInstruction 表示一个一元运算指令,格式:dest = OP val
|
||||
* <p>
|
||||
* - dest:运算结果存放的目标寄存器
|
||||
* - OP:一元操作符(如取负、按位取反等)
|
||||
* - val:操作数
|
||||
* 支持的操作符由 IROpCode 定义,例如:
|
||||
* <ul>
|
||||
* <li>NEG —— 取负</li>
|
||||
* <li>NOT —— 按位取反或逻辑非</li>
|
||||
* </ul>
|
||||
*
|
||||
* 将单一操作数 val 进行指定 OP 运算,并将结果存储到目标寄存器 dest。
|
||||
*/
|
||||
public final class UnaryOperationInstruction extends IRInstruction {
|
||||
// 一元操作符,例如 NEG(取负)、NOT(逻辑非)等
|
||||
/** 一元运算操作符,如 NEG、NOT 等 */
|
||||
private final IROpCode op;
|
||||
|
||||
// 运算结果存放的目标虚拟寄存器
|
||||
/** 运算结果存放的目标虚拟寄存器 */
|
||||
private final IRVirtualRegister dest;
|
||||
|
||||
// 一元运算的操作数
|
||||
/** 一元运算的操作数 */
|
||||
private final IRValue val;
|
||||
|
||||
/**
|
||||
* 构造函数,创建一个一元运算指令实例。
|
||||
*
|
||||
* @param op 一元操作符
|
||||
* @param dest 结果存放的目标寄存器
|
||||
* @param val 操作数
|
||||
* @param op 指定的一元操作符
|
||||
* @param dest 运算结果存放的目标寄存器
|
||||
* @param val 参与运算的操作数
|
||||
*/
|
||||
public UnaryOperationInstruction(IROpCode op, IRVirtualRegister dest, IRValue val) {
|
||||
this.op = op;
|
||||
@ -41,7 +44,7 @@ public final class UnaryOperationInstruction extends IRInstruction {
|
||||
/**
|
||||
* 获取此指令对应的操作符。
|
||||
*
|
||||
* @return 一元操作符
|
||||
* @return 当前指令使用的一元操作符
|
||||
*/
|
||||
@Override
|
||||
public IROpCode op() {
|
||||
@ -59,9 +62,9 @@ public final class UnaryOperationInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此指令所使用的操作数(只有一个操作数)。
|
||||
* 获取此指令的操作数列表,仅包含一个操作数 val。
|
||||
*
|
||||
* @return 仅包含 val 的操作数列表
|
||||
* @return 单元素列表,其中元素为 val
|
||||
*/
|
||||
@Override
|
||||
public List<IRValue> operands() {
|
||||
@ -69,10 +72,11 @@ public final class UnaryOperationInstruction extends IRInstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指令转换为字符串表示形式,用于调试和打印。
|
||||
* 格式示例:v1 = NEG v2
|
||||
* 将一元运算指令转换为字符串表示,格式:dest = OP val
|
||||
* <p>
|
||||
* 示例:"v1 = NEG v2"
|
||||
*
|
||||
* @return 字符串表示
|
||||
* @return 指令的字符串形式,用于打印和调试
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -3,15 +3,16 @@ package org.jcnc.snow.compiler.ir.value;
|
||||
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||
|
||||
/**
|
||||
* IRConstant 类 —— 表示一个常量值(例如整数常量、字符串常量等)。
|
||||
* IRConstant 表示中间表示(IR)系统中的常量值。
|
||||
* <p>
|
||||
* 在中间表示(IR)中,常量通常是不可变的、直接使用的值,而不是寄存器或临时变量。
|
||||
* 常量是不可变的字面量或编译期计算结果,
|
||||
* 可以是整数、浮点数、字符串等类型。
|
||||
* 在 IR 中,常量直接作为操作数使用,而不需要寄存器。
|
||||
*/
|
||||
public record IRConstant(Object value) implements IRValue {
|
||||
|
||||
/**
|
||||
* 将常量值转换为字符串表示。
|
||||
* 主要用于打印 IR 指令时显示常量内容。
|
||||
* 将常量值转换为字符串表示,用于 IR 指令打印和调试。
|
||||
*
|
||||
* @return 常量的字符串形式
|
||||
*/
|
||||
|
||||
@ -3,20 +3,21 @@ package org.jcnc.snow.compiler.ir.value;
|
||||
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||
|
||||
/**
|
||||
* IRLabel —— 表示 IR 中的跳转目标标签。
|
||||
*
|
||||
* 在中间表示(IR)中,控制流指令(如 JUMP、JUMP_IF_ZERO)需要依赖标签来指定跳转位置。
|
||||
* 本类通过名字(字符串)唯一标识一个标签。
|
||||
*
|
||||
* IRLabel 也是一种 IRValue,因此可以作为指令的操作数。
|
||||
* IRLabel 表示中间表示(IR)系统中的跳转目标标签。
|
||||
* <p>
|
||||
* 在控制流指令(如 JUMP、JUMP_IF_ZERO、JUMP_IF_NONZERO 等)中,
|
||||
* 标签用于标识跳转目的地,确保程序执行流程的可控分支。
|
||||
* 本类通过唯一的字符串名称 name 来标识一个标签实例。
|
||||
* <p>
|
||||
* IRLabel 同时实现 IRValue 接口,可以直接作为操作数传递给 IRInstruction。
|
||||
*/
|
||||
public record IRLabel(String name) implements IRValue {
|
||||
|
||||
/**
|
||||
* 将标签转换为字符串形式。
|
||||
* 打印时在标签名后添加冒号,例如 "L1:"。
|
||||
* 将标签转换为字符串表示,用于 IR 打印和调试。
|
||||
* 格式为:name:,例如 "L1:"
|
||||
*
|
||||
* @return 标签的字符串表示
|
||||
* @return 带冒号的标签字符串
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -3,26 +3,28 @@ package org.jcnc.snow.compiler.ir.value;
|
||||
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||
|
||||
/**
|
||||
* IRVirtualRegister —— 表示一个 SSA(静态单赋值)虚拟寄存器。
|
||||
* <p>
|
||||
* 在中间表示(IR)中,每个中间值都存储在一个虚拟寄存器中。
|
||||
* IRVirtualRegister 表示一个静态单赋值(SSA)形式的虚拟寄存器。
|
||||
* <p>
|
||||
* 在中间表示(IR)系统中,每个中间计算结果都分配到一个唯一的虚拟寄存器。
|
||||
* 特点:
|
||||
* - 每个寄存器都有唯一的 id(通常由 IRBuilder 自动分配)
|
||||
* - 遵循 SSA 形式,即每个寄存器只被赋值一次
|
||||
* <p>
|
||||
* IRVirtualRegister 也是一种 IRValue,可以作为指令的操作数。
|
||||
* <ul>
|
||||
* <li>每个寄存器都有唯一的 id,由 IRFunction.newRegister() 自动生成</li>
|
||||
* <li>遵循 SSA 形式:每个寄存器仅在创建时被赋值一次</li>
|
||||
* </ul>
|
||||
*
|
||||
* IRVirtualRegister 同时实现 IRValue 接口,可作为 IRInstruction 的操作数。
|
||||
*
|
||||
* @param id 寄存器的唯一编号
|
||||
*/
|
||||
public record IRVirtualRegister(int id) implements IRValue {
|
||||
|
||||
/**
|
||||
* 将虚拟寄存器转换为字符串形式。
|
||||
* 通常以 % 开头,例如 "%0"、"%1"。
|
||||
* 将虚拟寄存器转换为字符串表示,格式为 "%<id>",便于打印和调试。
|
||||
*
|
||||
* @return 寄存器的字符串表示
|
||||
* @return 带有百分号前缀的寄存器编号字符串
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "%" + id;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user