feat: 增加指令生成器集中注册表

This commit is contained in:
Luke 2025-06-17 18:34:30 +08:00
parent a51502c622
commit 49f91e3b4e
2 changed files with 52 additions and 16 deletions

View File

@ -0,0 +1,42 @@
package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.core.IRInstruction;
import java.util.List;
/**
* 指令生成器集中注册表
*
* <p>本类在类加载阶段即完成所有后端 {@link InstructionGenerator} 实例
* 的创建并以不可变列表形式对外暴露
*/
public final class InstructionGeneratorProvider {
/** 工具类禁止实例化。 */
private InstructionGeneratorProvider() { /* no-instance */ }
/** 缺省指令生成器列表(不可修改,顺序即执行顺序)。 */
private static final List<InstructionGenerator<? extends IRInstruction>> DEFAULT =
List.of(
new LoadConstGenerator(), // 常量加载
new BinaryOpGenerator(), // 二元运算
new UnaryOpGenerator(), // 一元运算
new CallGenerator(), // 函数调用
new ReturnGenerator(), // 函数返回
new LabelGenerator(), // 标签定义
new JumpGenerator(), // 无条件跳转
new CmpJumpGenerator() // 条件跳转
);
/**
* 返回生产环境使用的缺省指令生成器列表
* 该列表为不可变集合如尝试修改将抛出
* {@link UnsupportedOperationException}
*
* @return 不可变的 {@code List} 实例
*/
public static List<InstructionGenerator<? extends IRInstruction>> defaultGenerators() {
return DEFAULT;
}
}

View File

@ -4,11 +4,12 @@ import org.jcnc.snow.compiler.backend.alloc.RegisterAllocator;
import org.jcnc.snow.compiler.backend.builder.VMCodeGenerator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.backend.generator.*;
import org.jcnc.snow.compiler.backend.generator.InstructionGeneratorProvider;
import org.jcnc.snow.compiler.ir.builder.IRProgramBuilder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.core.IRInstruction;
import org.jcnc.snow.compiler.ir.core.IRProgram;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import org.jcnc.snow.compiler.lexer.core.LexerEngine;
import org.jcnc.snow.compiler.parser.ast.base.Node;
import org.jcnc.snow.compiler.parser.context.ParserContext;
@ -20,7 +21,8 @@ import org.jcnc.snow.vm.engine.VirtualMachineEngine;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
/**
@ -78,19 +80,10 @@ public class SnowCompiler {
/* ---------- 5. IR → VM 指令 ---------- */
VMProgramBuilder builder = new VMProgramBuilder();
List<InstructionGenerator<? extends IRInstruction>> generators = Arrays.asList(
new LoadConstGenerator(),
new BinaryOpGenerator(),
new UnaryOpGenerator(),
new CallGenerator(),
new ReturnGenerator(),
new LabelGenerator(),
new JumpGenerator(),
new CmpJumpGenerator()
);
List<InstructionGenerator<? extends IRInstruction>> generators = InstructionGeneratorProvider.defaultGenerators();
for (IRFunction fn : program.functions()) {
Map<org.jcnc.snow.compiler.ir.value.IRVirtualRegister, Integer> slotMap =
Map<IRVirtualRegister, Integer> slotMap =
new RegisterAllocator().allocate(fn);
new VMCodeGenerator(slotMap, builder, generators).generate(fn);
}
@ -137,7 +130,8 @@ public class SnowCompiler {
int idx = -1;
for (int i = 0; i < ordered.size(); i++) {
if ("main".equals(ordered.get(i).name())) {
idx = i; break;
idx = i;
break;
}
}
if (idx > 0) Collections.swap(ordered, 0, idx);