From d3a3473e892726bfb0ec0878d1eb1703108b5bd4 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 19 Jan 2025 13:56:32 +0000 Subject: Add basic compilation to native C headers --- .../org/shedlang/compiler/backends/Backends.java | 1 + .../backends/PatioNativeCHeadersBackend.java | 116 +++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/Backends.java b/src/main/java/org/shedlang/compiler/backends/Backends.java index f1d0abc4..0be1ecb2 100644 --- a/src/main/java/org/shedlang/compiler/backends/Backends.java +++ b/src/main/java/org/shedlang/compiler/backends/Backends.java @@ -17,6 +17,7 @@ public class Backends { Stream.of( LlvmBackend.AMD64, LlvmBackend.I686, + PatioNativeCHeadersBackend.INSTANCE, PatioTextBackend.INSTANCE, ShidTextBackend.INSTANCE, WasmBackend.WASM32, diff --git a/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java b/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java new file mode 100644 index 00000000..e483708b --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java @@ -0,0 +1,116 @@ +package org.shedlang.compiler.backends; + +import org.shedlang.compiler.backends.paths.PartialTargetPath; +import org.shedlang.compiler.backends.paths.TargetDir; +import org.shedlang.compiler.config.ProfileConfig; +import org.shedlang.compiler.config.ProjectConfig; +import org.shedlang.compiler.patio.PatioCompilationUnit; +import org.shedlang.compiler.patio.PatioFunctionDeclaration; +import org.shedlang.compiler.shid.ShidNamespace; +import org.shedlang.compiler.typechecker.TypeInfos; +import org.shedlang.compiler.types.NamespaceName; + +import java.io.IOException; +import java.nio.file.Files; +import java.util.List; + +public class PatioNativeCHeadersBackend implements Backend { + public static final PatioNativeCHeadersBackend INSTANCE = new PatioNativeCHeadersBackend(); + + private PatioNativeCHeadersBackend() { + } + + @Override + public String targetName() { + return "patio-native-c-headers"; + } + + public void compile( + ProjectConfig config, + ProfileConfig profileConfig, + List namespaces, + TypeInfos typeInfos, + TargetDir targetDir + ) throws IOException, InterruptedException { + PatioBackends.compile( + config, + profileConfig, + namespaces, + typeInfos, + new PatioToNativeHeaders(targetDir) + ); + } + + private static class PatioToNativeHeaders implements PatioBackends.PatioToTarget { + + private final TargetDir targetDir; + + public PatioToNativeHeaders(TargetDir targetDir) { + this.targetDir = targetDir; + } + + @Override + public PatioBackends.PatioToTarget namespace( + NamespaceName namespaceName, + PatioCompilationUnit patioCompilationUnit + ) throws IOException, InterruptedException { + serializeToDisk( + targetDir.namespace(namespaceName), + patioCompilationUnit + ); + + return this; + } + + @Override + public void bin( + String binName, + PatioCompilationUnit patioCompilationUnit, + String mainFunctionName, + ProfileConfig profileConfig + ) throws IOException, InterruptedException { + serializeToDisk( + targetDir.bin(binName), + patioCompilationUnit + ); + } + + private void serializeToDisk( + PartialTargetPath partialTargetPath, + PatioCompilationUnit patioCompilationUnit + ) throws IOException { + var empty = true; + + var builder = new StringBuilder(); + // TODO: path to header file? Use angle brackets? + builder.append("#include \"shed.h\"\n"); + for (var element : patioCompilationUnit.elements()) { + if (element instanceof PatioFunctionDeclaration patioFunctionDeclaration) { + // TODO: pass this information through rather than having to inspect the string? + // TODO: ignore dependency projects? + if (patioFunctionDeclaration.name().startsWith("shed__runtime__namespace__")) { + empty = false; + builder.append("ShedObject "); + builder.append(patioFunctionDeclaration.name()); + builder.append("(ShedClosurePointer closurePointer"); + for (var param : patioFunctionDeclaration.params()) { + builder.append(", ShedObject "); + builder.append(param.name()); + } + builder.append(");\n"); + } + } + } + + if (empty) { + return; + } + + var compilationUnitString = builder.toString(); + + var path = partialTargetPath.withExtension(".h"); + Files.createDirectories(path.getParent()); + Files.writeString(path, compilationUnitString); + } + } +} -- cgit v1.2.3