diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instruction/CallInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instruction/CallInstruction.java
index 405f0f6..13db658 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/instruction/CallInstruction.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/instruction/CallInstruction.java
@@ -1,115 +1,95 @@
package org.jcnc.snow.compiler.ir.instruction;
+import org.jcnc.snow.compiler.ir.common.GlobalFunctionTable;
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 org.jcnc.snow.compiler.ir.core.IRValue;
import java.util.ArrayList;
import java.util.List;
/**
* CallInstruction —— 表示一次函数调用的中间代码指令
- * 形式为:dest = CALL functionName, arg1, arg2, ...
+ *
+ * dest = CALL foo, arg1, arg2, ...
+ *
+ * 若被调函数返回 void,则 {@code dest} 可以为 {@code null},
+ * 并且不会参与寄存器分配。
*/
public class CallInstruction extends IRInstruction {
- /**
- * 调用结果存放的目标虚拟寄存器
- */
+ /** 调用结果目标寄存器;void 返回时可为 null */
private final IRVirtualRegister dest;
-
- /**
- * 被调用的函数名
- */
+ /** 被调用的函数名(含模块限定) */
private final String functionName;
-
- /**
- * 传递给函数的参数列表
- */
+ /** 实参列表 */
private final List arguments;
- /**
- * 构造函数,创建一个函数调用指令
- *
- * @param dest 调用结果存放的目标寄存器
- * @param functionName 被调用的函数名
- * @param args 参数列表
- */
- public CallInstruction(IRVirtualRegister dest, String functionName, List args) {
+ public CallInstruction(IRVirtualRegister dest,
+ String functionName,
+ List args) {
this.dest = dest;
this.functionName = functionName;
this.arguments = List.copyOf(args);
}
- /**
- * 获取该指令的操作码
- *
- * @return 操作码 CALL
- */
+ // === 基本信息 ===
@Override
public IROpCode op() {
return IROpCode.CALL;
}
- /**
- * 获取该指令涉及的操作数(目标寄存器和所有参数)
- *
- * @return 操作数列表
- */
+ /** 仅在函数有返回值时才暴露目标寄存器 */
+ @Override
+ public IRVirtualRegister dest() {
+ return isVoidReturn() ? null : dest;
+ }
+
+ /** 操作数列表:void 调用不包含 dest */
@Override
public List operands() {
List ops = new ArrayList<>();
- ops.add(dest);
+ if (!isVoidReturn() && dest != null) {
+ ops.add(dest);
+ }
ops.addAll(arguments);
return ops;
}
- /**
- * 获取目标虚拟寄存器
- *
- * @return 目标虚拟寄存器
- */
+ // === Getter ===
public IRVirtualRegister getDest() {
return dest;
}
- /**
- * 获取被调用的函数名
- *
- * @return 函数名
- */
public String getFunctionName() {
return functionName;
}
- /**
- * 获取参数列表
- *
- * @return 参数列表
- */
public List getArguments() {
return arguments;
}
- /**
- * 接受 IRVisitor 访问
- *
- * @param visitor 访问者
- */
+ // === 帮助方法 ===
+ /** 判断被调函数是否返回 void */
+ private boolean isVoidReturn() {
+ return "void".equals(GlobalFunctionTable.getReturnType(functionName));
+ }
+
+ // === 访客模式 ===
@Override
public void accept(IRVisitor visitor) {
visitor.visit(this);
}
- /**
- * 获取该指令的字符串表示
- *
- * @return 字符串形式
- */
+ // === 字符串表示 ===
@Override
public String toString() {
- StringBuilder sb = new StringBuilder(dest + " = CALL " + functionName);
+ StringBuilder sb = new StringBuilder();
+ if (!isVoidReturn() && dest != null) {
+ sb.append(dest).append(" = ");
+ }
+ sb.append("CALL ").append(functionName);
for (IRValue arg : arguments) {
sb.append(", ").append(arg);
}