package org.jcnc.snow.compiler.backend;

import org.jcnc.snow.compiler.ir.core.IROpCode;

import java.util.EnumMap;
import java.util.Map;

/**
 * 提供 IR 操作码（{@link IROpCode}）到虚拟机指令名（{@code String}）的一一映射工具类。
 * <p>
 * 本类在编译器后端负责将中间表示中的操作码转换为对应的 VM 指令，用于最终的代码生成。
 * 不负责操作数或参数传递的逻辑，仅做纯映射处理。
 * </p>
 * <p>
 * 如需扩展更多操作码或新增指令语义，可在此集中管理映射关系。
 * </p>
 */
public final class IROpCodeMapper {

    /**
     * IR 操作码到 VM 指令名的映射表，基于 {@code EnumMap} 实现以提升性能。
     */
    private static final Map<IROpCode, String> opcodeMap = new EnumMap<>(IROpCode.class);

    static {
        opcodeMap.put(IROpCode.ADD_I32,    "I_ADD");
        opcodeMap.put(IROpCode.SUB_I32,    "I_SUB");
        opcodeMap.put(IROpCode.MUL_I32,    "I_MUL");
        opcodeMap.put(IROpCode.DIV_I32,    "I_DIV");
        opcodeMap.put(IROpCode.NEG_I32,    "I_NEG");

        opcodeMap.put(IROpCode.CMP_EQ,     "IC_EQ");
        opcodeMap.put(IROpCode.CMP_NE,     "IC_NE");
        opcodeMap.put(IROpCode.CMP_LT,     "IC_L");
        opcodeMap.put(IROpCode.CMP_GT,     "IC_G");
        opcodeMap.put(IROpCode.CMP_LE,     "IC_LE");
        opcodeMap.put(IROpCode.CMP_GE,     "IC_GE");

        opcodeMap.put(IROpCode.LOAD,       "I_LOAD");
        opcodeMap.put(IROpCode.STORE,      "I_STORE");
        opcodeMap.put(IROpCode.CONST,      "I_PUSH");

        opcodeMap.put(IROpCode.JUMP,       "JMP");
        opcodeMap.put(IROpCode.JUMP_IF_ZERO, "JZ");
        opcodeMap.put(IROpCode.LABEL,      "LABEL");

        opcodeMap.put(IROpCode.CALL,       "CALL");
        opcodeMap.put(IROpCode.RET,        "RET");
    }

    /**
     * 将给定的 IR 操作码转换为对应的 VM 指令名。
     *
     * @param irOp 需转换的 IR 操作码
     * @return 与 IR 操作码对应的 VM 指令名称
     * @throws IllegalArgumentException 若 {@code irOp} 未在映射表中定义
     */
    public static String toVMOp(IROpCode irOp) {
        String vmCode = opcodeMap.get(irOp);
        if (vmCode == null) {
            throw new IllegalArgumentException("未映射的 IR 操作码: " + irOp);
        }
        return vmCode;
    }

    // 私有构造函数，防止实例化
    private IROpCodeMapper() {
        // 不允许实例化
    }
}
