diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-01-24 20:17:23 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-01-24 20:17:23 +0000 |
| commit | 33b25bfd3fbd214864126d88e0e52e0c4c2fcb1d (patch) | |
| tree | 6fd70d85630c00cf6335a649dedda0c4dd1ee457 /src/main/java | |
| parent | 10aee360aeca39d6f605394762f5d732b9688315 (diff) | |
Extract common code for Patio backends
Diffstat (limited to 'src/main/java')
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 { |
