使用访问者模式

This commit is contained in:
Luke 2025-05-09 11:07:49 +08:00
parent eaf7a8f9dc
commit 3dc67f3da9
11 changed files with 202 additions and 44 deletions

View File

@ -2,4 +2,5 @@ module org.jcnc.snow.compiler {
requires java.desktop;
requires java.logging;
exports org.jcnc.snow.compiler.ir.core;
exports org.jcnc.snow.compiler.ir.instruction;
}

View File

@ -1,54 +1,16 @@
package org.jcnc.snow.compiler.ir.core;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
*
* IRInstruction 所有 IR 指令的抽象基类Abstract Base Class
* <p>
* 每一条 IR 指令都至少具备以下基本属性
* <p>
* - 操作符op指示这条指令的操作类型如加法常量加载等
* <p>
* - 目标寄存器dest保存运算结果的寄存器某些指令可能没有结果
* <p>
* - 操作数列表operands指令所使用的操作数如常量或寄存器
* <p>
* 继承类可以根据需要覆盖 dest() operands() 方法
* IRInstruction 所有 IR 指令的抽象基类
*/
public abstract class IRInstruction {
/**
* 获取指令的操作符
* 例如ADD_I32CONSTRET
*
* @return 操作符枚举值IROpCode
*/
public abstract IROpCode op();
public IRVirtualRegister dest() { return null; }
public List<IRValue> operands() { return List.of(); }
/**
* 获取指令的目标寄存器若有的话
*
* 默认返回 null表示该指令没有结果寄存器
* 子类可以根据需要覆盖此方法
*
* @return 目标寄存器或 null
*/
public IRVirtualRegister dest() {
return null;
}
/**
* 获取指令的操作数列表
*
* 默认返回空列表表示没有任何操作数
* 子类通常会根据指令类型重写此方法返回实际的操作数如左右子表达式常量等
*
* @return 操作数列表
*/
public List<IRValue> operands() {
return List.of();
}
}
/** 访问者模式接口 */
public abstract void accept(IRVisitor visitor);
}

View File

@ -0,0 +1,27 @@
package org.jcnc.snow.compiler.ir.core;
import org.jcnc.snow.compiler.ir.instruction.IRAddInstruction;
import org.jcnc.snow.compiler.ir.instruction.IRJumpInstruction;
import org.jcnc.snow.compiler.ir.instruction.IRReturnInstruction;
/**
* 一个示例访问者实现 IRVisitor用于打印 IR 指令信息
*/
public abstract class IRPrinter implements IRVisitor {
@Override
public void visit(IRAddInstruction inst) {
System.out.println("Add: " + inst);
}
@Override
public void visit(IRJumpInstruction inst) {
System.out.println("Jump: " + inst);
}
@Override
public void visit(IRReturnInstruction inst) {
System.out.println("Return: " + inst);
}
// 你可以继续添加对其他 IRInstruction 子类的 visit 方法
}

View File

@ -0,0 +1,16 @@
package org.jcnc.snow.compiler.ir.core;
import org.jcnc.snow.compiler.ir.instruction.*;
/**
* IRVisitor 访问者接口用于对不同类型的 IR 指令进行操作如打印优化等
*/
public interface IRVisitor {
void visit(IRAddInstruction inst);
void visit(IRJumpInstruction inst);
void visit(IRReturnInstruction inst);
void visit(BinaryOperationInstruction inst);
void visit(LoadConstInstruction inst);
void visit(ReturnInstruction inst);
void visit(UnaryOperationInstruction inst);
}

View File

@ -3,6 +3,7 @@ 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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
@ -80,4 +81,10 @@ public final class BinaryOperationInstruction extends IRInstruction {
public String toString() {
return dest + " = " + op + " " + lhs + ", " + rhs;
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -0,0 +1,49 @@
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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
/**
* 表示一个加法指令形如dest = op1 + op2
*/
public class IRAddInstruction extends IRInstruction {
private final IRVirtualRegister dest;
private final IRValue lhs;
private final IRValue rhs;
public IRAddInstruction(IRVirtualRegister dest, IRValue lhs, IRValue rhs) {
this.dest = dest;
this.lhs = lhs;
this.rhs = rhs;
}
@Override
public IROpCode op() {
return IROpCode.ADD_I32;
}
@Override
public IRVirtualRegister dest() {
return dest;
}
@Override
public List<IRValue> operands() {
return List.of(lhs, rhs);
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return dest + " = " + lhs + " + " + rhs;
}
}

View File

@ -0,0 +1,35 @@
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.IRVisitor;
/**
* 表示无条件跳转到标签的指令
*/
public class IRJumpInstruction extends IRInstruction {
private final String label;
public IRJumpInstruction(String label) {
this.label = label;
}
@Override
public IROpCode op() {
return IROpCode.JUMP;
}
public String label() {
return label;
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return "jump " + label;
}
}

View File

@ -0,0 +1,40 @@
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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import java.util.List;
/**
* 表示返回值的指令
*/
public class IRReturnInstruction extends IRInstruction {
private final IRValue returnValue;
public IRReturnInstruction(IRValue returnValue) {
this.returnValue = returnValue;
}
@Override
public IROpCode op() {
return IROpCode.RET;
}
@Override
public List<IRValue> operands() {
return List.of(returnValue);
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return "ret " + returnValue;
}
}

View File

@ -3,6 +3,7 @@ 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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import org.jcnc.snow.compiler.ir.value.IRConstant;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
@ -74,4 +75,10 @@ public final class LoadConstInstruction extends IRInstruction {
public String toString() {
return dest + " = CONST " + k;
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -3,6 +3,7 @@ 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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
@ -83,4 +84,10 @@ public final class ReturnInstruction extends IRInstruction {
public String toString() {
return value == null ? "RET" : "RET " + value;
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -3,6 +3,7 @@ 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;
import org.jcnc.snow.compiler.ir.core.IRVisitor;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.List;
@ -82,4 +83,10 @@ public final class UnaryOperationInstruction extends IRInstruction {
public String toString() {
return dest + " = " + op + " " + val;
}
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
}