diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-14 21:27:24 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-14 21:27:24 +0100 |
| commit | 76fc235449f03fd76ab9a5bd96d9e8f2aec025c3 (patch) | |
| tree | 34370080396a17fdf6f0e6f92b4e1e431fb20217 /src | |
| parent | e1c58cd188df9ba3c5db1ea43e9ec922cc38e2b7 (diff) | |
Add if instruction
Diffstat (limited to 'src')
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); } |
