增加函数调用(没写完)
This commit is contained in:
parent
f506cea9dd
commit
8047533ebf
@ -3,11 +3,13 @@ package org.jcnc.snow.compiler.backend;
|
|||||||
import org.jcnc.snow.compiler.ir.core.IRFunction;
|
import org.jcnc.snow.compiler.ir.core.IRFunction;
|
||||||
import org.jcnc.snow.compiler.ir.core.IRInstruction;
|
import org.jcnc.snow.compiler.ir.core.IRInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
|
||||||
|
import org.jcnc.snow.compiler.ir.instruction.CallInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.ReturnInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.ReturnInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.value.IRConstant;
|
import org.jcnc.snow.compiler.ir.value.IRConstant;
|
||||||
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||||
|
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -16,18 +18,17 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* VMCodeGenerator —— 虚拟机代码生成器。
|
* VMCodeGenerator —— 虚拟机代码生成器。
|
||||||
* <p>
|
*
|
||||||
* 该类负责将中间表示(IRFunction)翻译为 SVM 虚拟机可执行的文本指令。
|
* 该类负责将中间表示(IRFunction)翻译为 SVM 虚拟机可执行的文本指令。
|
||||||
* 当前支持:
|
* 当前支持:
|
||||||
* - int32 类型的常量加载
|
* - int32 类型的常量加载
|
||||||
* - 加减乘除(+ - * /)的二元表达式
|
* - 加减乘除(+ - * /)的二元表达式
|
||||||
* - 取负(一元 -)
|
* - 取负(一元 -)
|
||||||
|
* - 函数调用
|
||||||
* - 函数返回(含 main 函数终止)
|
* - 函数返回(含 main 函数终止)
|
||||||
* </p>
|
*
|
||||||
* <p>
|
|
||||||
* 每个虚拟寄存器通过 slotMap 分配一个槽位(int 索引),用于定位变量。
|
* 每个虚拟寄存器通过 slotMap 分配一个槽位(int 索引),用于定位变量。
|
||||||
* 生成的代码是一系列字符串,格式为汇编式:OPCODE 参数...
|
* 生成的代码是一系列字符串,格式为汇编式:OPCODE 参数...
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
public final class VMCodeGenerator {
|
public final class VMCodeGenerator {
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ public final class VMCodeGenerator {
|
|||||||
case LoadConstInstruction c -> genLoadConst(c); // 常量加载
|
case LoadConstInstruction c -> genLoadConst(c); // 常量加载
|
||||||
case BinaryOperationInstruction b -> genBinOp(b); // 二元操作
|
case BinaryOperationInstruction b -> genBinOp(b); // 二元操作
|
||||||
case UnaryOperationInstruction u -> genUnary(u); // 一元操作
|
case UnaryOperationInstruction u -> genUnary(u); // 一元操作
|
||||||
|
case CallInstruction c -> genCall(c); // 函数调用
|
||||||
case ReturnInstruction r -> genRet(r); // 返回语句
|
case ReturnInstruction r -> genRet(r); // 返回语句
|
||||||
default -> throw new IllegalStateException("不支持的 IR 指令类型: " + inst);
|
default -> throw new IllegalStateException("不支持的 IR 指令类型: " + inst);
|
||||||
}
|
}
|
||||||
@ -99,10 +101,31 @@ public final class VMCodeGenerator {
|
|||||||
emit(op("I_STORE"), slot(u.dest()) + "");
|
emit(op("I_STORE"), slot(u.dest()) + "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成函数调用指令:
|
||||||
|
* - 将所有实参从局部槽加载到栈;
|
||||||
|
* - 执行 CALL,使用函数全名;
|
||||||
|
* - 将返回值存回目标寄存器槽。
|
||||||
|
*/
|
||||||
|
private void genCall(CallInstruction c) {
|
||||||
|
// 参数入栈
|
||||||
|
for (IRValue arg : c.getArguments()) {
|
||||||
|
if (arg instanceof IRVirtualRegister reg) {
|
||||||
|
emit(op("I_LOAD"), slot(reg) + "");
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("不支持的调用参数类型: " + arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 调用指令,函数名为全名(含模块前缀)
|
||||||
|
emit(op("CALL"), c.getFunctionName());
|
||||||
|
// 返回值存储到目标寄存器
|
||||||
|
emit(op("I_STORE"), slot(c.getDest()) + "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成返回语句:
|
* 生成返回语句:
|
||||||
* - 对于 main 函数,使用 HALT 表示程序终止
|
* - 对于 main 函数,使用 HALT 表示程序终止;
|
||||||
* - 其他函数使用 RET 指令返回调用者
|
* - 其他函数使用 RET 指令返回调用者。
|
||||||
*/
|
*/
|
||||||
private void genRet(ReturnInstruction r) {
|
private void genRet(ReturnInstruction r) {
|
||||||
if ("main".equals(currentFnName)) {
|
if ("main".equals(currentFnName)) {
|
||||||
|
|||||||
@ -1,116 +1,197 @@
|
|||||||
package org.jcnc.snow.compiler.ir.builder;
|
package org.jcnc.snow.compiler.ir.builder;
|
||||||
|
|
||||||
import org.jcnc.snow.compiler.ir.core.IROpCode;
|
import org.jcnc.snow.compiler.ir.core.IROpCode;
|
||||||
|
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
|
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
|
||||||
|
import org.jcnc.snow.compiler.ir.instruction.CallInstruction;
|
||||||
import org.jcnc.snow.compiler.ir.value.IRConstant;
|
import org.jcnc.snow.compiler.ir.value.IRConstant;
|
||||||
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||||
import org.jcnc.snow.compiler.parser.ast.BinaryExpressionNode;
|
import org.jcnc.snow.compiler.parser.ast.BinaryExpressionNode;
|
||||||
|
import org.jcnc.snow.compiler.parser.ast.CallExpressionNode;
|
||||||
|
import org.jcnc.snow.compiler.parser.ast.MemberExpressionNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.IdentifierNode;
|
import org.jcnc.snow.compiler.parser.ast.IdentifierNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode;
|
import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
|
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExpressionBuilder 将 AST 中的 ExpressionNode 转换为 IR 指令,并返回结果虚拟寄存器。
|
* ExpressionBuilder 将 AST 中的 ExpressionNode 转换为 IR 指令,并返回结果的虚拟寄存器。
|
||||||
* 支持:
|
*
|
||||||
* <ol>
|
* 支持以下表达式类型:
|
||||||
* <li>NumberLiteralNode:根据文本后缀(b/S/L/f/d)或内容自动区分 bytke/short/int/long/float/double,并生成常量加载指令</li>
|
* <ul>
|
||||||
* <li>IdentifierNode:从作用域获取已声明的虚拟寄存器</li>
|
* <li>NumberLiteralNode —— 常量字面量,生成 LoadConstInstruction;</li>
|
||||||
* <li>BinaryExpressionNode:递归构建子表达式,根据数据宽度和符号生成对应的二元运算指令</li>
|
* <li>IdentifierNode —— 标识符,查找当前作用域寄存器;</li>
|
||||||
* </ol>
|
* <li>BinaryExpressionNode —— 二元运算,生成 BinaryOperationInstruction;</li>
|
||||||
|
* <li>CallExpressionNode —— 函数调用(同模块或模块静态),生成 CallInstruction。</li>
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class ExpressionBuilder {
|
public class ExpressionBuilder {
|
||||||
// 不同位宽整数和浮点的运算码映射
|
private static final Map<String, IROpCode> OP_I8 = Map.of(
|
||||||
private static final Map<String, IROpCode> OP_I8 = Map.of("+", IROpCode.ADD_B8, "-", IROpCode.SUB_B8, "*", IROpCode.MUL_B8, "/", IROpCode.DIV_B8);
|
"+", IROpCode.ADD_B8, "-", IROpCode.SUB_B8,
|
||||||
private static final Map<String, IROpCode> OP_I16 = Map.of("+", IROpCode.ADD_S16, "-", IROpCode.SUB_S16, "*", IROpCode.MUL_S16, "/", IROpCode.DIV_S16);
|
"*", IROpCode.MUL_B8, "/", IROpCode.DIV_B8
|
||||||
private static final Map<String, IROpCode> OP_I32 = Map.of("+", IROpCode.ADD_I32, "-", IROpCode.SUB_I32, "*", IROpCode.MUL_I32, "/", IROpCode.DIV_I32);
|
);
|
||||||
private static final Map<String, IROpCode> OP_L64 = Map.of("+", IROpCode.ADD_L64, "-", IROpCode.SUB_L64, "*", IROpCode.MUL_L64, "/", IROpCode.DIV_L64);
|
private static final Map<String, IROpCode> OP_I16 = Map.of(
|
||||||
private static final Map<String, IROpCode> OP_F32 = Map.of("+", IROpCode.ADD_F32, "-", IROpCode.SUB_F32, "*", IROpCode.MUL_F32, "/", IROpCode.DIV_F32);
|
"+", IROpCode.ADD_S16, "-", IROpCode.SUB_S16,
|
||||||
private static final Map<String, IROpCode> OP_D64 = Map.of("+", IROpCode.ADD_D64, "-", IROpCode.SUB_D64, "*", IROpCode.MUL_D64, "/", IROpCode.DIV_D64);
|
"*", IROpCode.MUL_S16, "/", IROpCode.DIV_S16
|
||||||
|
);
|
||||||
|
private static final Map<String, IROpCode> OP_I32 = Map.of(
|
||||||
|
"+", IROpCode.ADD_I32, "-", IROpCode.SUB_I32,
|
||||||
|
"*", IROpCode.MUL_I32, "/", IROpCode.DIV_I32
|
||||||
|
);
|
||||||
|
private static final Map<String, IROpCode> OP_L64 = Map.of(
|
||||||
|
"+", IROpCode.ADD_L64, "-", IROpCode.SUB_L64,
|
||||||
|
"*", IROpCode.MUL_L64, "/", IROpCode.DIV_L64
|
||||||
|
);
|
||||||
|
private static final Map<String, IROpCode> OP_F32 = Map.of(
|
||||||
|
"+", IROpCode.ADD_F32, "-", IROpCode.SUB_F32,
|
||||||
|
"*", IROpCode.MUL_F32, "/", IROpCode.DIV_F32
|
||||||
|
);
|
||||||
|
private static final Map<String, IROpCode> OP_D64 = Map.of(
|
||||||
|
"+", IROpCode.ADD_D64, "-", IROpCode.SUB_D64,
|
||||||
|
"*", IROpCode.MUL_D64, "/", IROpCode.DIV_D64
|
||||||
|
);
|
||||||
|
|
||||||
private final IRContext ctx;
|
private final IRContext ctx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,传入 IRContext 用于生成寄存器和添加指令
|
||||||
|
* @param ctx 构建上下文
|
||||||
|
*/
|
||||||
public ExpressionBuilder(IRContext ctx) {
|
public ExpressionBuilder(IRContext ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 AST 表达式节点转换为 IR 指令,并返回结果寄存器
|
||||||
|
* @param expr 表达式节点
|
||||||
|
* @return 存放计算结果的虚拟寄存器
|
||||||
|
*/
|
||||||
public IRVirtualRegister build(ExpressionNode expr) {
|
public IRVirtualRegister build(ExpressionNode expr) {
|
||||||
// 1. 常量字面量
|
// 1. 常量字面量处理
|
||||||
if (expr instanceof NumberLiteralNode(String value)) {
|
if (expr instanceof NumberLiteralNode ln) {
|
||||||
// 判断后缀
|
String value = ln.value();
|
||||||
char suffix = value.isEmpty() ? '\0' : Character.toLowerCase(value.charAt(value.length() - 1));
|
char suffix = value.isEmpty() ? '\0' : Character.toLowerCase(value.charAt(value.length() - 1));
|
||||||
String digits = (suffix == 'b' || suffix == 's' || suffix == 'l' || suffix == 'f' || suffix == 'd') ? value.substring(0, value.length() - 1) : value;
|
String digits = (suffix == 'b' || suffix == 's' || suffix == 'l' || suffix == 'f' || suffix == 'd')
|
||||||
|
? value.substring(0, value.length() - 1)
|
||||||
|
: value;
|
||||||
|
|
||||||
IRVirtualRegister reg = ctx.newRegister();
|
IRVirtualRegister reg = ctx.newRegister();
|
||||||
switch (suffix) {
|
switch (suffix) {
|
||||||
case 'b': // byte
|
case 'b' -> ctx.addInstruction(
|
||||||
byte bv = Byte.parseByte(digits);
|
new LoadConstInstruction(reg, new IRConstant(Byte.parseByte(digits)))
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(bv)));
|
);
|
||||||
break;
|
case 's' -> ctx.addInstruction(
|
||||||
case 's': // short
|
new LoadConstInstruction(reg, new IRConstant(Short.parseShort(digits)))
|
||||||
short sv = Short.parseShort(digits);
|
);
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(sv)));
|
case 'l' -> ctx.addInstruction(
|
||||||
break;
|
new LoadConstInstruction(reg, new IRConstant(Long.parseLong(digits)))
|
||||||
case 'l': // long
|
);
|
||||||
long lv = Long.parseLong(digits);
|
case 'f' -> ctx.addInstruction(
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(lv)));
|
new LoadConstInstruction(reg, new IRConstant(Float.parseFloat(digits)))
|
||||||
break;
|
);
|
||||||
case 'f': // float
|
case 'd' -> ctx.addInstruction(
|
||||||
float fv = Float.parseFloat(digits);
|
new LoadConstInstruction(reg, new IRConstant(Double.parseDouble(digits)))
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(fv)));
|
);
|
||||||
break;
|
default -> {
|
||||||
case 'd': // double
|
|
||||||
double dv = Double.parseDouble(digits);
|
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(dv)));
|
|
||||||
break;
|
|
||||||
default: // 无后缀,数字中有小数点或指数 => double,否则 int
|
|
||||||
if (digits.contains(".") || digits.matches(".*[eE].*")) {
|
if (digits.contains(".") || digits.matches(".*[eE].*")) {
|
||||||
double dd = Double.parseDouble(digits);
|
ctx.addInstruction(
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(dd)));
|
new LoadConstInstruction(reg, new IRConstant(Double.parseDouble(digits)))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
int iv = Integer.parseInt(digits);
|
ctx.addInstruction(
|
||||||
ctx.addInstruction(new LoadConstInstruction(reg, new IRConstant(iv)));
|
new LoadConstInstruction(reg, new IRConstant(Integer.parseInt(digits)))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 标识符 => 作用域寄存器
|
// 2. 变量标识符处理
|
||||||
if (expr instanceof IdentifierNode(String name)) {
|
if (expr instanceof IdentifierNode id) {
|
||||||
IRVirtualRegister reg = ctx.getScope().lookup(name);
|
IRVirtualRegister reg = ctx.getScope().lookup(id.name());
|
||||||
if (reg == null) throw new IllegalStateException("未定义变量: " + name);
|
if (reg == null) {
|
||||||
|
throw new IllegalStateException("未定义标识符: " + id.name());
|
||||||
|
}
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 二元表达式
|
// 3. 二元表达式处理
|
||||||
if (expr instanceof BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right)) {
|
if (expr instanceof BinaryExpressionNode bin) {
|
||||||
|
ExpressionNode left = bin.left();
|
||||||
|
ExpressionNode right = bin.right();
|
||||||
|
String op = bin.operator();
|
||||||
IRVirtualRegister lreg = build(left);
|
IRVirtualRegister lreg = build(left);
|
||||||
IRVirtualRegister rreg = build(right);
|
IRVirtualRegister rreg = build(right);
|
||||||
// 判断计算类型:检查两侧是否为 NumberLiteralNode 并提取后缀
|
|
||||||
char leftS = (left instanceof NumberLiteralNode(
|
char suf = resolveSuffix(left, right);
|
||||||
String value
|
|
||||||
)) ? Character.toLowerCase(value.charAt(value.length() - 1)) : '\0';
|
|
||||||
char rightS = (right instanceof NumberLiteralNode(
|
|
||||||
String value
|
|
||||||
)) ? Character.toLowerCase(value.charAt(value.length() - 1)) : '\0';
|
|
||||||
// 选择优先级: byte < short < int < long < float < double
|
|
||||||
char suf = (leftS == 'd' || rightS == 'd') ? 'd' : (leftS == 'f' || rightS == 'f') ? 'f' : (leftS == 'l' || rightS == 'l') ? 'l' : (leftS == 's' || rightS == 's') ? 's' : (leftS == 'b' || rightS == 'b') ? 'b' : '\0';
|
|
||||||
IROpCode code = switch (suf) {
|
IROpCode code = switch (suf) {
|
||||||
case 'b' -> OP_I8.get(operator);
|
case 'b' -> OP_I8.get(op);
|
||||||
case 's' -> OP_I16.get(operator);
|
case 's' -> OP_I16.get(op);
|
||||||
case 'l' -> OP_L64.get(operator);
|
case 'l' -> OP_L64.get(op);
|
||||||
case 'f' -> OP_F32.get(operator);
|
case 'f' -> OP_F32.get(op);
|
||||||
case 'd' -> OP_D64.get(operator);
|
case 'd' -> OP_D64.get(op);
|
||||||
default -> OP_I32.get(operator);
|
default -> OP_I32.get(op);
|
||||||
};
|
};
|
||||||
if (code == null) throw new IllegalStateException("不支持的运算符: " + operator);
|
if (code == null) {
|
||||||
|
throw new IllegalStateException("不支持的运算符: " + op);
|
||||||
|
}
|
||||||
IRVirtualRegister dest = ctx.newRegister();
|
IRVirtualRegister dest = ctx.newRegister();
|
||||||
ctx.addInstruction(new BinaryOperationInstruction(code, dest, lreg, rreg));
|
ctx.addInstruction(new BinaryOperationInstruction(code, dest, lreg, rreg));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalStateException("不支持的表达式类型: " + expr.getClass().getSimpleName());
|
// 4. 函数调用表达式处理
|
||||||
|
if (expr instanceof CallExpressionNode call) {
|
||||||
|
// 构造实参寄存器列表,使用 IRValue 类型
|
||||||
|
List<IRValue> args = new ArrayList<>();
|
||||||
|
for (ExpressionNode argNode : call.arguments()) {
|
||||||
|
args.add(build(argNode));
|
||||||
|
}
|
||||||
|
// 解析 callee
|
||||||
|
String fullName;
|
||||||
|
ExpressionNode callee = call.callee();
|
||||||
|
if (callee instanceof MemberExpressionNode men
|
||||||
|
&& men.object() instanceof IdentifierNode objId) {
|
||||||
|
// 模块静态调用
|
||||||
|
fullName = objId.name() + "." + men.member();
|
||||||
|
} else if (callee instanceof IdentifierNode id2) {
|
||||||
|
// 同模块调用
|
||||||
|
fullName = id2.name();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"不支持的调用目标: " + callee.getClass().getSimpleName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
IRVirtualRegister dest = ctx.newRegister();
|
||||||
|
ctx.addInstruction(new CallInstruction(dest, fullName, args));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"不支持的表达式类型: " + expr.getClass().getSimpleName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 决定二元运算类型后缀,基于两侧 NumberLiteralNode 的后缀。
|
||||||
|
*/
|
||||||
|
private char resolveSuffix(ExpressionNode left, ExpressionNode right) {
|
||||||
|
char l = (left instanceof NumberLiteralNode ln)
|
||||||
|
? Character.toLowerCase(ln.value().charAt(ln.value().length() - 1))
|
||||||
|
: '\0';
|
||||||
|
char r = (right instanceof NumberLiteralNode rn)
|
||||||
|
? Character.toLowerCase(rn.value().charAt(rn.value().length() - 1))
|
||||||
|
: '\0';
|
||||||
|
if (l == 'd' || r == 'd') return 'd';
|
||||||
|
if (l == 'f' || r == 'f') return 'f';
|
||||||
|
if (l == 'l' || r == 'l') return 'l';
|
||||||
|
if (l == 's' || r == 's') return 's';
|
||||||
|
if (l == 'b' || r == 'b') return 'b';
|
||||||
|
return '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,4 +53,7 @@ public interface IRVisitor {
|
|||||||
* 访问一元运算指令,如 NEG_I32。
|
* 访问一元运算指令,如 NEG_I32。
|
||||||
*/
|
*/
|
||||||
void visit(UnaryOperationInstruction inst);
|
void visit(UnaryOperationInstruction inst);
|
||||||
|
|
||||||
|
void visit(CallInstruction instruction);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
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;
|
||||||
|
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
||||||
|
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CallInstruction —— 表示一次函数调用,格式:dest = CALL functionName, arg1, arg2, ...
|
||||||
|
*/
|
||||||
|
public class CallInstruction extends IRInstruction {
|
||||||
|
private final IRVirtualRegister dest;
|
||||||
|
private final String functionName;
|
||||||
|
private final List<IRValue> arguments;
|
||||||
|
|
||||||
|
public CallInstruction(IRVirtualRegister dest, String functionName, List<IRValue> args) {
|
||||||
|
this.dest = dest;
|
||||||
|
this.functionName = functionName;
|
||||||
|
this.arguments = Collections.unmodifiableList(new ArrayList<>(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IROpCode op() {
|
||||||
|
return IROpCode.CALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IRValue> operands() {
|
||||||
|
List<IRValue> ops = new ArrayList<>();
|
||||||
|
ops.add(dest);
|
||||||
|
ops.addAll(arguments);
|
||||||
|
return ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRVirtualRegister getDest() {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFunctionName() {
|
||||||
|
return functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IRValue> getArguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(IRVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder(dest + " = CALL " + functionName);
|
||||||
|
for (IRValue arg : arguments) {
|
||||||
|
sb.append(", ").append(arg);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user