From 3dc67f3da90ad379a11e41a2135cceab0c612999 Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 9 May 2025 11:07:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=AE=BF=E9=97=AE=E8=80=85?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/module-info.java | 1 + .../snow/compiler/ir/core/IRInstruction.java | 50 +++---------------- .../jcnc/snow/compiler/ir/core/IRPrinter.java | 27 ++++++++++ .../jcnc/snow/compiler/ir/core/IRVisitor.java | 16 ++++++ .../BinaryOperationInstruction.java | 7 +++ .../ir/instruction/IRAddInstruction.java | 49 ++++++++++++++++++ .../ir/instruction/IRJumpInstruction.java | 35 +++++++++++++ .../ir/instruction/IRReturnInstruction.java | 40 +++++++++++++++ .../ir/instruction/LoadConstInstruction.java | 7 +++ .../ir/instruction/ReturnInstruction.java | 7 +++ .../UnaryOperationInstruction.java | 7 +++ 11 files changed, 202 insertions(+), 44 deletions(-) create mode 100644 src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java create mode 100644 src/main/java/org/jcnc/snow/compiler/ir/core/IRVisitor.java create mode 100644 src/main/java/org/jcnc/snow/compiler/ir/instruction/IRAddInstruction.java create mode 100644 src/main/java/org/jcnc/snow/compiler/ir/instruction/IRJumpInstruction.java create mode 100644 src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 80c699c..4759b93 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -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; } 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 a0a5379..12f0c68 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 @@ -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)。 - *

- * 每一条 IR 指令都至少具备以下基本属性: - *

- * - 操作符(op):指示这条指令的操作类型,如加法、常量加载等。 - *

- * - 目标寄存器(dest):保存运算结果的寄存器(某些指令可能没有结果)。 - *

- * - 操作数列表(operands):指令所使用的操作数,如常量或寄存器。 - *

- * 继承类可以根据需要覆盖 dest() 和 operands() 方法。 + * IRInstruction —— 所有 IR 指令的抽象基类。 */ public abstract class IRInstruction { - - /** - * 获取指令的操作符。 - * 例如:ADD_I32、CONST、RET 等。 - * - * @return 操作符枚举值(IROpCode) - */ public abstract IROpCode op(); + public IRVirtualRegister dest() { return null; } + public List operands() { return List.of(); } - /** - * 获取指令的目标寄存器(若有的话)。 - * - * 默认返回 null,表示该指令没有结果寄存器。 - * 子类可以根据需要覆盖此方法。 - * - * @return 目标寄存器或 null - */ - public IRVirtualRegister dest() { - return null; - } - - /** - * 获取指令的操作数列表。 - * - * 默认返回空列表,表示没有任何操作数。 - * 子类通常会根据指令类型重写此方法,返回实际的操作数(如左右子表达式、常量等)。 - * - * @return 操作数列表 - */ - public List operands() { - return List.of(); - } -} + /** 访问者模式接口 */ + public abstract void accept(IRVisitor visitor); +} \ No newline at end of file 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 new file mode 100644 index 0000000..02a72f7 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRPrinter.java @@ -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 方法 +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IRVisitor.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IRVisitor.java new file mode 100644 index 0000000..f26489b --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IRVisitor.java @@ -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); +} \ 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 21455c6..22f6b10 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 @@ -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); + } } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRAddInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRAddInstruction.java new file mode 100644 index 0000000..4e7a4b4 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRAddInstruction.java @@ -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 operands() { + return List.of(lhs, rhs); + } + + @Override + public void accept(IRVisitor visitor) { + visitor.visit(this); + } + + @Override + public String toString() { + return dest + " = " + lhs + " + " + rhs; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRJumpInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRJumpInstruction.java new file mode 100644 index 0000000..9b5bd3e --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRJumpInstruction.java @@ -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; + } +} \ 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 new file mode 100644 index 0000000..61bd8b8 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/IRReturnInstruction.java @@ -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 operands() { + return List.of(returnValue); + } + + @Override + public void accept(IRVisitor visitor) { + visitor.visit(this); + } + + @Override + public String toString() { + return "ret " + returnValue; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/LoadConstInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/LoadConstInstruction.java index 2756e46..bdf5a2e 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/LoadConstInstruction.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/LoadConstInstruction.java @@ -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); + } } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/ReturnInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/ReturnInstruction.java index 6f2921f..4b00499 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/ReturnInstruction.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/ReturnInstruction.java @@ -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); + } } \ 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 540fc0d..8ee8e84 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 @@ -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); + } }