From 74163c2028e8d09b66cc1bb8d8002aba1a14ffed Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 8 Oct 2023 11:30:37 +0100 Subject: Add Patio switch instruction --- .../compiler/backends/llvm/LlvmPatioCodeGen.java | 4 ++ .../compiler/backends/wasm/WasmPatioCodeGen.java | 4 ++ .../compiler/patio/ast/PatioSerializer.java | 43 ++++++++++++++-------- .../patio/ast/instructions/PatioInstruction.java | 2 +- .../patio/ast/instructions/PatioSwitch.java | 26 +++++++++++++ 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioSwitch.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java index b055e1e2..45745796 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java @@ -506,6 +506,10 @@ public class LlvmPatioCodeGen { patioOperandToLlvmOperand(patioReturn.value(), context) )); + case PatioSwitch patioSwitch -> { + throw new UnsupportedOperationException("TODO"); + } + case PatioUnreachable patioUnreachable -> context.addTerminatorInstruction(new LlvmUnreachable()); diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java index 47ce14e3..fe01d9c5 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java @@ -306,6 +306,10 @@ public class WasmPatioCodeGen { yield context; } + case PatioSwitch patioSwitch -> { + throw new UnsupportedOperationException("TODO"); + } + case PatioUnreachable patioUnreachable -> context.addInstruction(new WasmUnreachable()); diff --git a/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java b/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java index c581e180..f329e679 100644 --- a/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java +++ b/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java @@ -152,11 +152,7 @@ public class PatioSerializer { treeIdentifier("call"), optionalOperandToTree(call.target()), treeString(call.functionName()), - treeList( - call.args().stream() - .map(arg -> operandToTree(arg)) - .toList() - ) + operandsToTree(call.args()) ); case PatioCallPointer callPointer -> @@ -164,11 +160,7 @@ public class PatioSerializer { treeIdentifier("call-pointer"), operandToTree(callPointer.target()), operandToTree(callPointer.functionPointer()), - treeList( - callPointer.args().stream() - .map(arg -> operandToTree(arg)) - .toList() - ) + operandsToTree(callPointer.args()) ); case PatioDataPtrToInt dataPtrToInt -> @@ -181,11 +173,7 @@ public class PatioSerializer { case PatioIf if_ -> treeListIndented( treeIdentifier("if"), - treeList( - if_.targets().stream() - .map(target -> operandToTree(target)) - .toList() - ), + operandsToTree(if_.targets()), operandToTree(if_.condition()), blockToTree(if_.trueBody()), blockToTree(if_.falseBody()) @@ -293,6 +281,23 @@ public class PatioSerializer { operandToTree(return_.value()) ); + case PatioSwitch switch_ -> + treeListIndented( + treeIdentifier("switch"), + operandsToTree(switch_.targets()), + operandToTree(switch_.value()), + treeListIndented( + switch_.cases().stream() + .map(switchCase -> treeListIndented( + treeIdentifier("case"), + treeInt(switchCase.value()), + blockToTree(switchCase.body()) + )) + .toList() + ), + blockToTree(switch_.defaultBody()) + ); + case PatioUnreachable unreachable -> treeList(treeIdentifier("unreachable")); @@ -354,6 +359,14 @@ public class PatioSerializer { } } + private static Tree operandsToTree(List operands) { + return treeList( + operands.stream() + .map(target -> operandToTree(target)) + .toList() + ); + } + private static Tree operandToTree(PatioOperand operand) { return switch (operand) { case PatioBool bool -> diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioInstruction.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioInstruction.java index 8b11d25b..f473afdd 100644 --- a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioInstruction.java +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioInstruction.java @@ -2,6 +2,6 @@ package org.shedlang.compiler.patio.ast.instructions; import org.shedlang.compiler.sources.Source; -public sealed interface PatioInstruction permits PatioAllocHeap, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioReturn, PatioUnreachable, PatioVarLoad, PatioVarStore { +public sealed interface PatioInstruction permits PatioAllocHeap, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioReturn, PatioSwitch, PatioUnreachable, PatioVarLoad, PatioVarStore { Source source(); } diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioSwitch.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioSwitch.java new file mode 100644 index 00000000..d68b44a3 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioSwitch.java @@ -0,0 +1,26 @@ +package org.shedlang.compiler.patio.ast.instructions; + +import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; +import org.shedlang.compiler.patio.ast.operands.PatioOperand; +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Find a case with a value matching that of the instruction's value. If such a + * case is found, execute the body of that case, otherwise execute the default + * body. + *

+ * Each block must have the same number of results as targets. Each result + * is assigned to the target with the same index. + */ +public record PatioSwitch( + List targets, + PatioOperand value, + List cases, + PatioBlock defaultBody, + Source source +) implements PatioInstruction { + public record Case(int value, PatioBlock body, Source source) { + } +} -- cgit v1.2.3