From a8e9e00313a07442d05523ea4c189ac61d77a34f Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 22 Nov 2023 22:58:23 +0000 Subject: Add throw and try instructions to Patio --- .../compiler/backends/llvm/LlvmPatioCodeGen.java | 8 ++++++- .../compiler/backends/wasm/WasmPatioCodeGen.java | 6 ++++++ .../compiler/patio/ast/PatioSerializer.java | 24 +++++++++++++++++++++ .../patio/ast/instructions/PatioCatchClause.java | 17 +++++++++++++++ .../compiler/patio/ast/instructions/PatioIf.java | 4 ++-- .../patio/ast/instructions/PatioInstruction.java | 2 +- .../patio/ast/instructions/PatioThrow.java | 16 ++++++++++++++ .../compiler/patio/ast/instructions/PatioTry.java | 25 ++++++++++++++++++++++ 8 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioCatchClause.java create mode 100644 src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioThrow.java create mode 100644 src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioTry.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 114922e4..651f7aff 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java @@ -72,7 +72,7 @@ public class LlvmPatioCodeGen { case PatioDataElementMutable patioDataElementMutable -> generateDataElementMutable(patioDataElementMutable, context); - + case PatioExceptionTypeDefinition patioExceptionTypeDefinition -> throw new UnsupportedOperationException("TODO"); @@ -566,6 +566,12 @@ public class LlvmPatioCodeGen { yield context; } + case PatioThrow throw_ -> + throw new UnsupportedOperationException("TODO"); + + case PatioTry try_ -> + 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 3436ef1b..8beac54d 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java @@ -337,6 +337,12 @@ public class WasmPatioCodeGen { yield context; } + case PatioThrow throw_ -> + throw new UnsupportedOperationException("TODO"); + + case PatioTry try_ -> + 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 c333ea80..aba2a732 100644 --- a/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java +++ b/src/main/java/org/shedlang/compiler/patio/ast/PatioSerializer.java @@ -312,6 +312,30 @@ public class PatioSerializer { blockToTree(switch_.defaultBody()) ); + case PatioTry try_ -> + treeListIndented( + treeIdentifier("try"), + operandsToTree(try_.targets()), + treeListIndented( + try_.catchClauses().stream() + .map(catchClause -> treeListIndented( + treeIdentifier("catch"), + treeString(catchClause.exceptionTypeName()), + operandToTree(catchClause.target()), + blockToTree(catchClause.body()) + )) + .toList() + ), + blockToTree(try_.body()) + ); + + case PatioThrow throw_ -> + treeList( + treeIdentifier("throw"), + treeString(throw_.exceptionTypeName()), + operandToTree(throw_.value()) + ); + case PatioUnreachable unreachable -> treeList(treeIdentifier("unreachable")); diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioCatchClause.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioCatchClause.java new file mode 100644 index 00000000..05af2450 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioCatchClause.java @@ -0,0 +1,17 @@ +package org.shedlang.compiler.patio.ast.instructions; + +import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; +import org.shedlang.compiler.sources.Source; + +/** + * A catch clause can accept an exception of a given type. If executed, it will + * stored the value of the exception in the given target, and then execute the + * body. + */ +public record PatioCatchClause( + String exceptionTypeName, + PatioLocalRef target, + PatioBlock body, + Source source +) { +} diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioIf.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioIf.java index 7e8cc59f..16e2e9b3 100644 --- a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioIf.java +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioIf.java @@ -10,8 +10,8 @@ import java.util.List; * If the condition is true, execute the instructions in the "true" body, * otherwise execute the instructions in the "false" body. *

- * Each block must have the same number of results as targets. Each result - * is assigned to the target with the same index. + * Each block must have the same number of results as targets. Each result is + * assigned to the target with the same index. */ public record PatioIf( List targets, 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 842063ab..3230b622 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, PatioAllocStack, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioReturn, PatioSwitch, PatioUnreachable, PatioVarLoad, PatioVarStore { +public sealed interface PatioInstruction permits PatioAllocHeap, PatioAllocStack, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioReturn, PatioSwitch, PatioThrow, PatioTry, PatioUnreachable, PatioVarLoad, PatioVarStore { Source source(); } diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioThrow.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioThrow.java new file mode 100644 index 00000000..f7ed97a4 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioThrow.java @@ -0,0 +1,16 @@ +package org.shedlang.compiler.patio.ast.instructions; + +import org.shedlang.compiler.patio.ast.operands.PatioOperand; +import org.shedlang.compiler.sources.Source; + +/** + * Search the stack for an exception handler with a catch clause matching the + * thrown exception type. Unwind the stack up to and including this exception + * handler, and run the body of the catch clause. + */ +public record PatioThrow( + String exceptionTypeName, + PatioOperand value, + Source source +) implements PatioInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioTry.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioTry.java new file mode 100644 index 00000000..ebd1ca95 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioTry.java @@ -0,0 +1,25 @@ +package org.shedlang.compiler.patio.ast.instructions; + +import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Push an exception handler with the given catch clauses onto the control flow + * stack, and then execute the instructions in its body. + *

+ * If the exception handler catches an exception, the body of the corresponding + * is executed instead. + *

+ * Each block (that is, the body of the try and the body of each catch clause) + * must have the same number of results as targets. Each result is assigned to + * the target with the same index. + */ +public record PatioTry( + List targets, + List catchClauses, + PatioBlock body, + Source source +) implements PatioInstruction { +} -- cgit v1.2.3