aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-14 21:27:24 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-14 21:27:24 +0100
commit76fc235449f03fd76ab9a5bd96d9e8f2aec025c3 (patch)
tree34370080396a17fdf6f0e6f92b4e1e431fb20217 /src
parente1c58cd188df9ba3c5db1ea43e9ec922cc38e2b7 (diff)
Add if instruction
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java3
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java3
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java27
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java18
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java2
-rw-r--r--src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java29
-rw-r--r--src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java7
7 files changed, 78 insertions, 11 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
index e2236dcc..2f20e55b 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
@@ -147,6 +147,9 @@ public class LlvmCodeGen {
yield context.push(fieldValue);
}
+ case IfInstruction if_ ->
+ throw new UnsupportedOperationException("TODO");
+
case IntAddInstruction intAdd ->
generateBinaryOperation(
(target, left, right, operationContext) ->
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
index a9ee98ac..e7ebff16 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
@@ -179,6 +179,9 @@ public class WasmCodeGen {
);
}
+ case IfInstruction if_ ->
+ throw new UnsupportedOperationException("TODO");
+
case IntAddInstruction intAdd ->
context.addInstruction(new WasmI32Add());
diff --git a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
index baaf4b49..17d778df 100644
--- a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
+++ b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
@@ -12,11 +12,7 @@ public class InstructionSerializer {
}
public static void serializeInstructions(List<Instruction> instructions, StringBuilder builder) {
- var tree = treeListIndented(
- instructions.stream()
- .map(instruction -> toTree(instruction))
- .toList()
- );
+ var tree = instructionsToTree(instructions);
serializeTree(tree, builder, 0);
}
@@ -25,6 +21,14 @@ public class InstructionSerializer {
serializeTree(tree, builder, 0);
}
+ private static Tree instructionsToTree(List<Instruction> instructions) {
+ return treeListIndented(
+ instructions.stream()
+ .map(instruction -> toTree(instruction))
+ .toList()
+ );
+ }
+
private static Tree toTree(Instruction instruction) {
return switch (instruction) {
case CallInstruction callInstruction ->
@@ -63,11 +67,7 @@ public class InstructionSerializer {
.map(freeVariable -> treeString(freeVariable.name()))
.toList()
)),
- treeNamed("body", treeListIndented(
- defineFunctionInstruction.body().stream()
- .map(bodyInstruction -> toTree(bodyInstruction))
- .toList()
- ))
+ treeNamed("body", instructionsToTree(defineFunctionInstruction.body()))
);
case DiscardInstruction discardInstruction ->
@@ -82,6 +82,13 @@ public class InstructionSerializer {
treeString(fieldLoad.fieldName())
);
+ case IfInstruction if_ ->
+ treeListIndented(
+ treeIdentifier("if"),
+ instructionsToTree(if_.trueBody()),
+ instructionsToTree(if_.falseBody())
+ );
+
case IntAddInstruction intAdd ->
treeList(treeIdentifier("int-add"));
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java
new file mode 100644
index 00000000..df09859f
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/IfInstruction.java
@@ -0,0 +1,18 @@
+package org.shedlang.compiler.stackir.instructions;
+
+
+import org.shedlang.compiler.sources.Source;
+
+import java.util.List;
+
+/**
+ * Pop a value from a stack, and assume it is a Bool. If it is true, execute the
+ * instructions in the "true" body, otherwise execute the instructions in the
+ * "false" body.
+ */
+public record IfInstruction(
+ List<Instruction> trueBody,
+ List<Instruction> falseBody,
+ Source source
+) implements Instruction {
+}
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
index a1ab0a39..80593264 100644
--- a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
@@ -3,7 +3,7 @@ package org.shedlang.compiler.stackir.instructions;
import org.shedlang.compiler.sources.Source;
public sealed interface Instruction
- permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, IntAddInstruction, IntEqualsInstruction, IntNotEqualInstruction, IntSubInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction, StringAddInstruction {
+ permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, IfInstruction, IntAddInstruction, IntEqualsInstruction, IntNotEqualInstruction, IntSubInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction, StringAddInstruction {
Source source();
}
diff --git a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
index 3ce690b2..72056a3e 100644
--- a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
+++ b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java
@@ -76,6 +76,35 @@ public class InstructionSerializerTests {
}
@Test
+ public void canSerializeIf() {
+ var instruction = Instructions.if_(
+ List.of(
+ Instructions.pushUnit()
+ ),
+ List.of(
+ Instructions.localLoad("x"),
+ Instructions.discard(),
+ Instructions.pushBool(true)
+ )
+ );
+
+ var string = serialize(instruction);
+
+ assertThat(string, equalTo("""
+ (
+ if
+ (
+ (push-unit)
+ )
+ (
+ (local-load "x")
+ (discard)
+ (push-bool true)
+ )
+ )"""));
+ }
+
+ @Test
public void canSerializeIntAdd() {
var instruction = Instructions.intAdd();
diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
index df8b193b..131207b8 100644
--- a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
+++ b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java
@@ -22,6 +22,13 @@ public class Instructions {
return new FieldLoadInstruction(namespaceName, fieldName, Sources.NULL);
}
+ public static Instruction if_(
+ List<Instruction> trueBody,
+ List<Instruction> falseBody
+ ) {
+ return new IfInstruction(trueBody, falseBody, Sources.NULL);
+ }
+
public static Instruction intAdd() {
return new IntAddInstruction(Sources.NULL);
}