diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-04-11 21:04:02 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-04-11 21:04:02 +0100 |
| commit | 612eaf73eba92a633c4790db2e406eb0def2f6fe (patch) | |
| tree | 3a7642c872228b1ffb90e562480f56c0f77be513 /src | |
| parent | 67ddc893da418073e78109d69726e2fe188e01db (diff) | |
Allow explicit selection of backend
Diffstat (limited to 'src')
9 files changed, 104 insertions, 22 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/BackendFactory.java b/src/main/java/org/shedlang/compiler/backends/BackendFactory.java index b8fcdb46..66b0bc9d 100644 --- a/src/main/java/org/shedlang/compiler/backends/BackendFactory.java +++ b/src/main/java/org/shedlang/compiler/backends/BackendFactory.java @@ -3,5 +3,6 @@ package org.shedlang.compiler.backends; import java.util.Optional; public interface BackendFactory { + String name(); Optional<Backend> backendForTarget(ShedTarget target); } diff --git a/src/main/java/org/shedlang/compiler/backends/Backends.java b/src/main/java/org/shedlang/compiler/backends/Backends.java index d266302f..333f73ad 100644 --- a/src/main/java/org/shedlang/compiler/backends/Backends.java +++ b/src/main/java/org/shedlang/compiler/backends/Backends.java @@ -1,9 +1,11 @@ package org.shedlang.compiler.backends; +import org.shedlang.compiler.backends.cranelift.CraneliftBackendFactory; import org.shedlang.compiler.backends.llvm.LlvmBackendFactory; import org.shedlang.compiler.backends.wasm.WasmBackendFactory; import java.util.List; +import java.util.Optional; public class Backends { private Backends() { @@ -12,19 +14,25 @@ public class Backends { private static final List<BackendFactory> BACKEND_FACTORIES = List.of( new LlvmBackendFactory(), new WasmBackendFactory(), + new CraneliftBackendFactory(), PatioNativeCHeadersBackend.FACTORY, PatioTextBackend.FACTORY, ShidTextBackend.FACTORY ); - public static List<String> targetNames() { - return ShedTarget.targetNames(); + public static List<String> backendNames() { + return BACKEND_FACTORIES.stream() + .map(factory -> factory.name()) + .toList(); } - public static Backend backendForTarget(String targetName) { - var target = ShedTarget.fromString(targetName) - .orElseThrow(() -> new UnsupportedOperationException("TODO")); + public static Optional<BackendFactory> backendFactory(String backendName) { + return BACKEND_FACTORIES.stream() + .filter(factory -> factory.name().equals(backendName)) + .findFirst(); + } + public static Backend backendForTarget(ShedTarget target) { for (var factory : BACKEND_FACTORIES) { var backend = factory.backendForTarget(target); if (backend.isPresent()) { diff --git a/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java b/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java index ea8bde7c..84f7332a 100644 --- a/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java @@ -16,11 +16,19 @@ import java.util.List; import java.util.Optional; public class PatioNativeCHeadersBackend implements Backend { - public static final BackendFactory FACTORY = target -> { - if (target == ShedTarget.PATIO_NATIVE_C_HEADERS) { - return Optional.of(PatioNativeCHeadersBackend.INSTANCE); - } else { - return Optional.empty(); + public static final BackendFactory FACTORY = new BackendFactory() { + @Override + public String name() { + return "patio-native-c-headers"; + } + + @Override + public Optional<Backend> backendForTarget(ShedTarget target) { + if (target == ShedTarget.PATIO_NATIVE_C_HEADERS) { + return Optional.of(PatioNativeCHeadersBackend.INSTANCE); + } else { + return Optional.empty(); + } } }; diff --git a/src/main/java/org/shedlang/compiler/backends/PatioTextBackend.java b/src/main/java/org/shedlang/compiler/backends/PatioTextBackend.java index c2fe8708..e93c7644 100644 --- a/src/main/java/org/shedlang/compiler/backends/PatioTextBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/PatioTextBackend.java @@ -16,11 +16,19 @@ import java.util.List; import java.util.Optional; public class PatioTextBackend implements Backend { - public static final BackendFactory FACTORY = target -> { - if (target == ShedTarget.PATIO_TEXT) { - return Optional.of(PatioTextBackend.INSTANCE); - } else { - return Optional.empty(); + public static final BackendFactory FACTORY = new BackendFactory() { + @Override + public String name() { + return "patio-text"; + } + + @Override + public Optional<Backend> backendForTarget(ShedTarget target) { + if (target == ShedTarget.PATIO_TEXT) { + return Optional.of(PatioTextBackend.INSTANCE); + } else { + return Optional.empty(); + } } }; diff --git a/src/main/java/org/shedlang/compiler/backends/ShidTextBackend.java b/src/main/java/org/shedlang/compiler/backends/ShidTextBackend.java index 7468336f..56174101 100644 --- a/src/main/java/org/shedlang/compiler/backends/ShidTextBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/ShidTextBackend.java @@ -13,11 +13,19 @@ import java.util.List; import java.util.Optional; public class ShidTextBackend implements Backend { - public static final BackendFactory FACTORY = target -> { - if (target == ShedTarget.SHID_TEXT) { - return Optional.of(ShidTextBackend.INSTANCE); - } else { - return Optional.empty(); + public static final BackendFactory FACTORY = new BackendFactory() { + @Override + public String name() { + return "shid-text"; + } + + @Override + public Optional<Backend> backendForTarget(ShedTarget target) { + if (target == ShedTarget.SHID_TEXT) { + return Optional.of(ShidTextBackend.INSTANCE); + } else { + return Optional.empty(); + } } }; diff --git a/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackendFactory.java b/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackendFactory.java new file mode 100644 index 00000000..b933d975 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackendFactory.java @@ -0,0 +1,25 @@ +package org.shedlang.compiler.backends.cranelift; + +import org.shedlang.compiler.backends.Backend; +import org.shedlang.compiler.backends.BackendFactory; +import org.shedlang.compiler.backends.ShedTarget; +import org.shedlang.compiler.backends.llvm.LlvmTarget; + +import java.util.Optional; + +public class CraneliftBackendFactory implements BackendFactory { + @Override + public String name() { + return "cranelift"; + } + + @Override + public Optional<Backend> backendForTarget(ShedTarget target) { + Optional<LlvmTarget> llvmTarget = switch (target) { + case AMD64 -> Optional.of(LlvmTarget.AMD64); + default -> Optional.empty(); + }; + + return llvmTarget.map(CraneliftBackend::forTarget); + } +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackendFactory.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackendFactory.java index bb8a952a..301a912b 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackendFactory.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackendFactory.java @@ -8,6 +8,11 @@ import java.util.Optional; public class LlvmBackendFactory implements BackendFactory { @Override + public String name() { + return "llvm"; + } + + @Override public Optional<Backend> backendForTarget(ShedTarget target) { Optional<LlvmTarget> llvmTarget = switch (target) { case AMD64 -> Optional.of(LlvmTarget.AMD64); diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackendFactory.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackendFactory.java index 5cf8446f..439bc05d 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackendFactory.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackendFactory.java @@ -8,6 +8,11 @@ import java.util.Optional; public class WasmBackendFactory implements BackendFactory { @Override + public String name() { + return "wasm"; + } + + @Override public Optional<Backend> backendForTarget(ShedTarget target) { Optional<WasmTarget> wasmTarget = switch (target) { case WASM32 -> Optional.of(WasmTarget.WASM32); diff --git a/src/main/java/org/shedlang/compiler/cli/ShedCli.java b/src/main/java/org/shedlang/compiler/cli/ShedCli.java index 46bf9b5f..e4f98607 100644 --- a/src/main/java/org/shedlang/compiler/cli/ShedCli.java +++ b/src/main/java/org/shedlang/compiler/cli/ShedCli.java @@ -6,6 +6,7 @@ import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.Namespace; import org.shedlang.compiler.ShedCompiler; import org.shedlang.compiler.backends.Backends; +import org.shedlang.compiler.backends.ShedTarget; import org.shedlang.compiler.errors.CompilerError; import java.io.IOException; @@ -31,7 +32,19 @@ public class ShedCli { switch (args.<Command>get("command")) { case COMPILE -> { - var backend = Backends.backendForTarget(args.getString("target")); + var target = ShedTarget.fromString(args.getString("target")).orElseThrow(); + var backend = Optional.ofNullable(args.getString("backend")) + .map( + backendName -> + Backends + .backendFactory(backendName) + // In principle, this should be prevented by the arg parsing. + .orElseThrow(() -> new UnsupportedOperationException("Unrecognised backend: " + backendName)) + .backendForTarget(target) + // TODO: better error + .orElseThrow(() -> new UnsupportedOperationException("Backend " + backendName + " does not support target " + target.targetName())) + ) + .orElseGet(() -> Backends.backendForTarget(target)); var profile = Optional.ofNullable(args.getString("profile")); compiler.compile(sourcePath, backend, profile); } @@ -50,7 +63,8 @@ public class ShedCli { .addArgument("source") .type(new PathArgumentType()) .required(true); - compileSubParser.addArgument("--target").choices(Backends.targetNames()).required(true); + compileSubParser.addArgument("--backend").choices(Backends.backendNames()).required(false); + compileSubParser.addArgument("--target").choices(ShedTarget.targetNames()).required(true); compileSubParser.addArgument("--profile").required(false); try { |
