aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-01-24 20:17:23 +0000
committerMichael Williamson <mike@zwobble.org>2024-01-24 20:17:23 +0000
commit33b25bfd3fbd214864126d88e0e52e0c4c2fcb1d (patch)
tree6fd70d85630c00cf6335a649dedda0c4dd1ee457 /src/main/java
parent10aee360aeca39d6f605394762f5d732b9688315 (diff)
Extract common code for Patio backends
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/PatioBackends.java76
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java100
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java75
3 files changed, 179 insertions, 72 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/PatioBackends.java b/src/main/java/org/shedlang/compiler/backends/PatioBackends.java
new file mode 100644
index 00000000..e7eec057
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/backends/PatioBackends.java
@@ -0,0 +1,76 @@
+package org.shedlang.compiler.backends;
+
+import org.shedlang.compiler.config.BinConfig;
+import org.shedlang.compiler.config.ProjectConfig;
+import org.shedlang.compiler.patio.PatioCompilationUnit;
+import org.shedlang.compiler.shid.ShidNamespace;
+import org.shedlang.compiler.shidtopatio.ShidToPatio;
+import org.shedlang.compiler.shidtopatio.ShidToPatioContext;
+import org.shedlang.compiler.sources.Sources;
+import org.shedlang.compiler.typechecker.TypeInfos;
+import org.shedlang.compiler.types.NamespaceName;
+
+import java.io.IOException;
+import java.util.List;
+
+public class PatioBackends {
+ public interface PatioToTarget {
+ PatioToTarget namespace(
+ NamespaceName namespaceName,
+ PatioCompilationUnit patioCompilationUnit
+ ) throws IOException, InterruptedException;
+
+ void bin(
+ String binName,
+ PatioCompilationUnit patioCompilationUnit,
+ String mainFunctionName
+ ) throws IOException, InterruptedException;
+ }
+
+ public static void compile(
+ ProjectConfig config,
+ List<ShidNamespace> namespaces,
+ TypeInfos typeInfos,
+ PatioToTarget patioToTarget
+ ) throws IOException, InterruptedException {
+ var shidToPatioContext = ShidToPatioContext.forTypeInfos(typeInfos);
+
+ for (var namespace : namespaces) {
+ var patioCompilationUnitResult = ShidToPatio.generateNamespace(
+ namespace,
+ shidToPatioContext
+ );
+ var patioCompilationUnit = patioCompilationUnitResult.value();
+ shidToPatioContext = patioCompilationUnitResult.context();
+
+ patioToTarget = patioToTarget.namespace(namespace.namespaceName(), patioCompilationUnit);
+ }
+
+ for (var bin : config.bins()) {
+ generateMain(bin, shidToPatioContext, patioToTarget);
+ }
+ }
+
+ private static void generateMain(
+ BinConfig binConfig,
+ ShidToPatioContext shidToPatioContext,
+ PatioToTarget patioToTarget
+ ) throws IOException, InterruptedException {
+ // TODO: set appropriate source
+ var source = Sources.NULL;
+
+ var generateMainResult = ShidToPatio.generateMain(
+ binConfig.mainNamespace(),
+ source,
+ shidToPatioContext
+ );
+ var mainFunctionName = generateMainResult.value();
+ shidToPatioContext = generateMainResult.context();
+
+ var patioCompilationUnitResult = shidToPatioContext.toCompilationUnit(source);
+ var patioCompilationUnit = patioCompilationUnitResult.value();
+ shidToPatioContext = patioCompilationUnitResult.context();
+
+ patioToTarget.bin(binConfig.name(), patioCompilationUnit, mainFunctionName);
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java
index 027fc4b9..0f398a79 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java
@@ -1,6 +1,8 @@
package org.shedlang.compiler.backends.llvm;
+import org.pcollections.PVector;
import org.shedlang.compiler.backends.Backend;
+import org.shedlang.compiler.backends.PatioBackends;
import org.shedlang.compiler.backends.llvm.codegen.PatioToLlvm;
import org.shedlang.compiler.backends.llvm.codegen.PatioToLlvmGlobalContext;
import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock;
@@ -15,12 +17,11 @@ import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes;
import org.shedlang.compiler.backends.paths.TargetDir;
import org.shedlang.compiler.config.ProjectConfig;
import org.shedlang.compiler.filesystem.ShedCompilerFiles;
-import org.shedlang.compiler.shidtopatio.ShidToPatio;
-import org.shedlang.compiler.shidtopatio.ShidToPatioContext;
+import org.shedlang.compiler.patio.PatioCompilationUnit;
import org.shedlang.compiler.shid.ShidNamespace;
-import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.typechecker.TypeInfos;
import org.shedlang.compiler.types.NamespaceName;
+import org.shedlang.compiler.util.P;
import org.shedlang.compiler.util.processes.ProcessError;
import java.io.IOException;
@@ -57,47 +58,79 @@ public class LlvmBackend implements Backend {
TypeInfos typeInfos,
TargetDir targetDir
) throws IOException, InterruptedException {
- var llvmCompiler = LlvmCompiler.forTarget(this.target);
-
- var objectFilePaths = new ArrayList<Path>();
- var shidToPatioContext = ShidToPatioContext.forTypeInfos(typeInfos);
- var patioToLlvmGlobalContext = PatioToLlvmGlobalContext.empty(this.target);
+ PatioBackends.compile(
+ config,
+ namespaces,
+ typeInfos,
+ new PatioToBinary(
+ LlvmCompiler.forTarget(this.target),
+ targetDir,
+ P.vector(),
+ PatioToLlvmGlobalContext.empty(this.target)
+ )
+ );
+ }
- for (var namespace : namespaces) {
- var patioCompilationUnitResult = ShidToPatio.generateNamespace(
- namespace,
- shidToPatioContext
- );
- var patioCompilationUnit = patioCompilationUnitResult.value();
- shidToPatioContext = patioCompilationUnitResult.context();
+ private class PatioToBinary implements PatioBackends.PatioToTarget {
+ private final LlvmCompiler llvmCompiler;
+ private final TargetDir targetDir;
+ private final PVector<Path> objectFilePaths;
+ private final PatioToLlvmGlobalContext patioToLlvmGlobalContext;
+
+ public PatioToBinary(
+ LlvmCompiler llvmCompiler,
+ TargetDir targetDir,
+ PVector<Path> objectFilePaths,
+ PatioToLlvmGlobalContext patioToLlvmGlobalContext
+ ) {
+ this.llvmCompiler = llvmCompiler;
+ this.targetDir = targetDir;
+ this.objectFilePaths = objectFilePaths;
+ this.patioToLlvmGlobalContext = patioToLlvmGlobalContext;
+ }
+ @Override
+ public PatioBackends.PatioToTarget namespace(
+ NamespaceName namespaceName,
+ PatioCompilationUnit patioCompilationUnit
+ ) throws IOException, InterruptedException {
var llvmModuleResult = PatioToLlvm.generateCompilationUnit(
patioCompilationUnit,
- patioToLlvmGlobalContext
+ this.patioToLlvmGlobalContext
);
var llvmModule = llvmModuleResult.value();
- patioToLlvmGlobalContext = llvmModuleResult.context();
+ var patioToLlvmGlobalContext = llvmModuleResult.context();
var objectPath = llvmCompiler.compileLlvmModule(
llvmModule,
- targetDir.namespace(namespace.namespaceName())
+ targetDir.namespace(namespaceName)
);
- objectFilePaths.add(objectPath);
+ return new PatioToBinary(
+ this.llvmCompiler,
+ this.targetDir,
+ this.objectFilePaths.plus(objectPath),
+ patioToLlvmGlobalContext
+ );
}
- for (var bin : config.bins()) {
+ @Override
+ public void bin(
+ String binName,
+ PatioCompilationUnit patioCompilationUnit,
+ String mainFunctionName
+ ) throws IOException, InterruptedException {
var linkInputs = new ArrayList<>(objectFilePaths);
- var mainModule = this.generateMain(
- bin.mainNamespace(),
- shidToPatioContext,
+ var mainModule = generateMain(
+ patioCompilationUnit,
+ mainFunctionName,
patioToLlvmGlobalContext
);
- var mainObjectPath = llvmCompiler.compileLlvmModule(mainModule, targetDir.bin(bin.name()));
+ var mainObjectPath = llvmCompiler.compileLlvmModule(mainModule, targetDir.bin(binName));
linkInputs.add(mainObjectPath);
- link(linkInputs, targetDir.topLevel(bin.name()));
+ link(linkInputs, targetDir.topLevel(binName));
}
}
@@ -125,22 +158,11 @@ public class LlvmBackend implements Backend {
runInheritIo(clangArgs);
}
- private LlvmModule generateMain(
- NamespaceName main,
- ShidToPatioContext shidToPatioContext,
+ private static LlvmModule generateMain(
+ PatioCompilationUnit patioCompilationUnit,
+ String mainFunctionName,
PatioToLlvmGlobalContext patioToLlvmGlobalContext
) {
- // TODO: use more appropriate source
- var source = Sources.NULL;
-
- var generateMainResult = ShidToPatio.generateMain(main, source, shidToPatioContext);
- var mainFunctionName = generateMainResult.value();
- shidToPatioContext = generateMainResult.context();
-
- var patioCompilationUnitResult = shidToPatioContext.toCompilationUnit(source);
- var patioCompilationUnit = patioCompilationUnitResult.value();
- shidToPatioContext = patioCompilationUnitResult.context();
-
var llvmModuleResult = PatioToLlvm.generateCompilationUnit(
patioCompilationUnit,
patioToLlvmGlobalContext
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java
index d6392ab3..913c5c09 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java
@@ -1,6 +1,8 @@
package org.shedlang.compiler.backends.wasm;
+import org.pcollections.PVector;
import org.shedlang.compiler.backends.Backend;
+import org.shedlang.compiler.backends.PatioBackends;
import org.shedlang.compiler.backends.paths.PartialTargetPath;
import org.shedlang.compiler.backends.paths.TargetDir;
import org.shedlang.compiler.backends.wasm.structure.WasmBinaryFormat;
@@ -12,10 +14,8 @@ import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmFunction;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmModule;
import org.shedlang.compiler.config.ProjectConfig;
import org.shedlang.compiler.filesystem.ShedCompilerFiles;
-import org.shedlang.compiler.shidtopatio.ShidToPatio;
-import org.shedlang.compiler.shidtopatio.ShidToPatioContext;
+import org.shedlang.compiler.patio.PatioCompilationUnit;
import org.shedlang.compiler.shid.ShidNamespace;
-import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.typechecker.TypeInfos;
import org.shedlang.compiler.types.NamespaceName;
import org.shedlang.compiler.util.P;
@@ -56,37 +56,57 @@ public class WasmBackend implements Backend {
TypeInfos typeInfos,
TargetDir targetDir
) throws IOException, InterruptedException {
- var objectFilePaths = new ArrayList<Path>();
- var shidToPatioContext = ShidToPatioContext.forTypeInfos(typeInfos);
+ PatioBackends.compile(
+ config,
+ namespaces,
+ typeInfos,
+ new PatioToWasmBinary(targetDir, P.vector())
+ );
+ }
- for (var namespace : namespaces) {
- var patioCompilationUnitResult = ShidToPatio.generateNamespace(
- namespace,
- shidToPatioContext
- );
- var patioCompilationUnit = patioCompilationUnitResult.value();
- shidToPatioContext = patioCompilationUnitResult.context();
+ private class PatioToWasmBinary implements PatioBackends.PatioToTarget {
+ private final TargetDir targetDir;
+ private final PVector<Path> objectFilePaths;
+
+ public PatioToWasmBinary(TargetDir targetDir, PVector<Path> objectFilePaths) {
+ this.targetDir = targetDir;
+ this.objectFilePaths = objectFilePaths;
+ }
+ @Override
+ public PatioBackends.PatioToTarget namespace(
+ NamespaceName namespaceName,
+ PatioCompilationUnit patioCompilationUnit
+ ) throws IOException {
var wasmModule = PatioToWasm.generateCompilationUnit(
patioCompilationUnit,
- this.target
+ target
);
var objectPath = writeObjectFile(
wasmModule,
- targetDir.namespace(namespace.namespaceName())
+ this.targetDir.namespace(namespaceName)
+ );
+
+ return new PatioToWasmBinary(
+ this.targetDir,
+ this.objectFilePaths.plus(objectPath)
);
- objectFilePaths.add(objectPath);
}
- for (var bin : config.bins()) {
+ @Override
+ public void bin(
+ String binName,
+ PatioCompilationUnit patioCompilationUnit,
+ String mainFunctionName
+ ) throws IOException, InterruptedException {
var linkInputs = new ArrayList<>(objectFilePaths);
- var mainModule = this.generateMain(bin.mainNamespace(), shidToPatioContext);
- var mainObjectPath = writeObjectFile(mainModule, targetDir.bin(bin.name()));
+ var mainModule = generateMain(patioCompilationUnit, mainFunctionName);
+ var mainObjectPath = writeObjectFile(mainModule, targetDir.bin(binName));
linkInputs.add(mainObjectPath);
- var targetBinPath = targetDir.topLevel(bin.name() + ".wasm");
+ var targetBinPath = targetDir.topLevel(binName + ".wasm");
link(linkInputs, targetBinPath);
validate(targetBinPath);
}
@@ -115,20 +135,9 @@ public class WasmBackend implements Backend {
}
private WasmModule generateMain(
- NamespaceName main,
- ShidToPatioContext shidToPatioContext
+ PatioCompilationUnit patioCompilationUnit,
+ String mainFunctionName
) {
- // TODO: set appropriate source
- var source = Sources.NULL;
-
- var generateMainResult = ShidToPatio.generateMain(main, source, shidToPatioContext);
- var mainFunctionName = generateMainResult.value();
- shidToPatioContext = generateMainResult.context();
-
- var patioCompilationUnitResult = shidToPatioContext.toCompilationUnit(source);
- var patioCompilationUnit = patioCompilationUnitResult.value();
- shidToPatioContext = patioCompilationUnitResult.context();
-
var wasmModule = PatioToWasm.generateCompilationUnit(
patioCompilationUnit,
this.target
@@ -157,7 +166,7 @@ public class WasmBackend implements Backend {
return wasmModule;
}
- private Path writeObjectFile(
+ private static Path writeObjectFile(
WasmModule module,
PartialTargetPath targetPath
) throws IOException {