aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-01-19 13:56:32 +0000
committerMichael Williamson <mike@zwobble.org>2025-01-19 13:56:32 +0000
commitd3a3473e892726bfb0ec0878d1eb1703108b5bd4 (patch)
treeba3e6ae602def440d094e1a3b797a8e8cf347ed7 /src/main/java
parent436f43fa2667c77ef8a7d05bb5b8001c17c7822b (diff)
Add basic compilation to native C headers
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/Backends.java1
-rw-r--r--src/main/java/org/shedlang/compiler/backends/PatioNativeCHeadersBackend.java116
2 files changed, 117 insertions, 0 deletions
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<ShidNamespace> 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);
+ }
+ }
+}