From d4c8aea05fd76a0a29f81c2c374161416bdc8468 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 7 May 2025 20:05:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=87=E8=AF=86=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compiler/backend/VMCodeGenerator.java | 73 ++++++++++--------- .../ir/instruction/LoadConstInstruction.java | 10 ++- 2 files changed, 46 insertions(+), 37 deletions(-) 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 92d2d80..7ec94c8 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java +++ b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java @@ -2,7 +2,10 @@ package org.jcnc.snow.compiler.backend; import org.jcnc.snow.compiler.ir.core.IRFunction; import org.jcnc.snow.compiler.ir.core.IRInstruction; -import org.jcnc.snow.compiler.ir.instruction.*; +import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction; +import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction; +import org.jcnc.snow.compiler.ir.instruction.ReturnInstruction; +import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction; import org.jcnc.snow.compiler.ir.value.IRConstant; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.vm.engine.VMOpCode; @@ -18,26 +21,28 @@ import java.util.Map; */ public final class VMCodeGenerator { - private final Map slotMap; - private final List code = new ArrayList<>(); + private final Map slotMap; + private final List code = new ArrayList<>(); private String currentFnName; // ← 当前正在生成的函数名 - public VMCodeGenerator(Map slotMap){ + public VMCodeGenerator(Map slotMap) { this.slotMap = slotMap; } - /** 主入口:IR → 指令序列 */ - public List generate(IRFunction fn){ + /** + * 主入口:IR → 指令序列 + */ + public List generate(IRFunction fn) { currentFnName = fn.name(); // ← 保存函数名 for (IRInstruction inst : fn.body()) { switch (inst) { case LoadConstInstruction c -> genLoadConst(c); - case BinaryOperationInstruction b -> genBinOp(b); - case UnaryOperationInstruction u -> genUnary(u); - case ReturnInstruction r -> genRet(r); - default -> throw new IllegalStateException("Unsupported IR: "+inst); + case BinaryOperationInstruction b -> genBinOp(b); + case UnaryOperationInstruction u -> genUnary(u); + case ReturnInstruction r -> genRet(r); + default -> throw new IllegalStateException("Unsupported IR: " + inst); } } /* 注意:不再额外添加 HALT,结束行为由 genRet 决定 */ @@ -46,43 +51,43 @@ public final class VMCodeGenerator { /* ───────────── 指令生成 ───────────── */ - private void genLoadConst(LoadConstInstruction c){ - IRConstant k = (IRConstant)c.operands().get(0); - emit(op("I_PUSH"), k.value().toString()); - emit(op("I_STORE"), slot(c.dest())+""); + private void genLoadConst(LoadConstInstruction c) { + IRConstant k = (IRConstant) c.operands().get(0); + emit(op("I_PUSH"), k.value().toString()); + emit(op("I_STORE"), slot(c.dest()) + ""); } - private void genBinOp(BinaryOperationInstruction b){ - emit(op("I_LOAD"), slot((IRVirtualRegister)b.operands().get(0))+""); - emit(op("I_LOAD"), slot((IRVirtualRegister)b.operands().get(1))+""); + private void genBinOp(BinaryOperationInstruction b) { + emit(op("I_LOAD"), slot((IRVirtualRegister) b.operands().get(0)) + ""); + emit(op("I_LOAD"), slot((IRVirtualRegister) b.operands().get(1)) + ""); - String opcode = switch (b.op()){ + String opcode = switch (b.op()) { case ADD_I32 -> "I_ADD"; case SUB_I32 -> "I_SUB"; case MUL_I32 -> "I_MUL"; case DIV_I32 -> "I_DIV"; - default -> throw new IllegalStateException("Unsupported bin op "+b.op()); + default -> throw new IllegalStateException("Unsupported bin op " + b.op()); }; emit(op(opcode)); - emit(op("I_STORE"), slot(b.dest())+""); + emit(op("I_STORE"), slot(b.dest()) + ""); } - private void genUnary(UnaryOperationInstruction u){ - emit(op("I_LOAD"), slot((IRVirtualRegister)u.operands().get(0))+""); + private void genUnary(UnaryOperationInstruction u) { + emit(op("I_LOAD"), slot((IRVirtualRegister) u.operands().get(0)) + ""); - String opcode = switch (u.op()){ + String opcode = switch (u.op()) { case NEG_I32 -> "I_NEG"; - default -> throw new IllegalStateException("Unsupported unary op "+u.op()); + default -> throw new IllegalStateException("Unsupported unary op " + u.op()); }; emit(op(opcode)); - emit(op("I_STORE"), slot(u.dest())+""); + emit(op("I_STORE"), slot(u.dest()) + ""); } - private void genRet(ReturnInstruction r){ + private void genRet(ReturnInstruction r) { /* — 主函数:加载返回值(若有) → HALT — */ if ("main".equals(currentFnName)) { if (r.value() != null) { - emit(op("I_LOAD"), slot(r.value())+""); + emit(op("I_LOAD"), slot(r.value()) + ""); } emit(op("HALT")); // 结束整个程序 return; @@ -90,29 +95,29 @@ public final class VMCodeGenerator { /* — 普通函数:LOAD (可选) → RET — */ if (r.value() != null) { - emit(op("I_LOAD"), slot(r.value())+""); + emit(op("I_LOAD"), slot(r.value()) + ""); } emit(op("RET")); } /* ───────────── 工具函数 ───────────── */ - private int slot(IRVirtualRegister r){ + private int slot(IRVirtualRegister r) { Integer s = slotMap.get(r); - if (s == null) throw new IllegalStateException("Register "+r+" 未映射槽位"); + if (s == null) throw new IllegalStateException("Register " + r + " 未映射槽位"); return s; } - private String op(String name){ + private String op(String name) { try { Field f = VMOpCode.class.getField(name); return f.get(null).toString(); - } catch (Exception e){ - throw new RuntimeException("Unknown opcode "+name, e); + } catch (Exception e) { + throw new RuntimeException("Unknown opcode " + name, e); } } - private void emit(String opcode, String... args){ + private void emit(String opcode, String... args) { StringBuilder sb = new StringBuilder(opcode); for (String a : args) sb.append(' ').append(a); code.add(sb.toString()); 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 1ca0eb3..2756e46 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 @@ -14,10 +14,14 @@ import java.util.List; * 将字面量常量 k 加载到目标虚拟寄存器 dest 中,以便后续指令使用该常量值。 */ public final class LoadConstInstruction extends IRInstruction { - /** 要加载的常量值 */ + /** + * 要加载的常量值 + */ private final IRConstant k; - /** 存放常量的目标虚拟寄存器 */ + /** + * 存放常量的目标虚拟寄存器 + */ private final IRVirtualRegister dest; /** @@ -28,7 +32,7 @@ public final class LoadConstInstruction extends IRInstruction { */ public LoadConstInstruction(IRVirtualRegister dest, IRConstant k) { this.dest = dest; - this.k = k; + this.k = k; } /**