aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-03 18:13:30 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-03 18:13:30 +0000
commit8decaba8f75d16550d5f0e6caf9ddaff18dad38a (patch)
tree281c39b4933542b69c6189f087d472dfb76bb918 /src/main/java
parent0bcd3fbadef087b2b3ed6e4f398f6e6c36f11209 (diff)
Support exception handler method break
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java3
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java25
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java6
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java64
-rw-r--r--src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioBlock.java8
5 files changed, 97 insertions, 9 deletions
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 37cda648..097eb2d8 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java
@@ -633,6 +633,9 @@ public class LlvmPatioCodeGen {
)
));
+ // TODO: construct a test for this in PatioExampleTests
+ context = context.addTerminatorInstruction(new LlvmUnreachable());
+
yield context;
}
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index 733152b4..a555d181 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -309,7 +309,18 @@ public class PatioCodeGen {
}
case ShedEffectHandlerBreak effectHandlerBreak -> {
- throw new UnsupportedOperationException("TODO");
+ var valueResult = context.temporaryPop();
+ var value = valueResult.value();
+ context = valueResult.context();
+
+ context = PatioCodeGenEffects.break_(
+ effectHandlerBreak.effect(),
+ value,
+ effectHandlerBreak.source(),
+ context
+ );
+
+ yield context;
}
case ShidFieldLoad fieldLoad -> {
@@ -668,15 +679,25 @@ public class PatioCodeGen {
handlerMethodsByName.put(handlerMethodName, handlerMethod);
}
+ var targetResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TEMPORARY,
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var target = targetResult.value();
+ context = targetResult.context();
+
context = PatioCodeGenEffects.try_(
+ target,
try_.handledEffect(),
handlerMethodsByName,
bodyContext ->
- generateInstructions(try_.body(), bodyContext),
+ generateBlock(1, try_.body(), try_.source(), bodyContext),
try_.source(),
context
);
+ context = context.temporaryPush(target);
+
yield context;
}
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
index 219f9ec1..5dcd91eb 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
@@ -709,6 +709,12 @@ public record PatioCodeGenContext(
}
@CheckReturnValue
+ public String exceptionTypeName(UserDefinedEffect effect) {
+ // TODO: Allocate properly
+ return "shed__effect__exception__" + String.join("_", effect.namespaceName().parts()) + "__" + effect.name();
+ }
+
+ @CheckReturnValue
private PatioCodeGenContext withCompilationUnitContext(CompilationUnitContext compilationUnitContext) {
return new PatioCodeGenContext(this.globalContext, compilationUnitContext, this.blockStack, this.functionContext);
}
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
index 74073b2f..4dbb7438 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
@@ -1,6 +1,7 @@
package org.shedlang.compiler.patio;
import org.shedlang.compiler.ast.typed.FreeVariables;
+import org.shedlang.compiler.patio.ast.PatioExceptionTypeDefinition;
import org.shedlang.compiler.patio.ast.PatioFunctionDeclaration;
import org.shedlang.compiler.patio.ast.PatioLocal;
import org.shedlang.compiler.patio.ast.PatioVisibility;
@@ -13,9 +14,9 @@ import org.shedlang.compiler.patio.ast.types.PatioDataLayout;
import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
import org.shedlang.compiler.patio.ast.types.PatioType;
import org.shedlang.compiler.patio.ast.types.PatioTypes;
+import org.shedlang.compiler.shid.instructions.ShidDefineFunction;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.sources.Sources;
-import org.shedlang.compiler.shid.instructions.ShidDefineFunction;
import org.shedlang.compiler.types.UserDefinedEffect;
import org.shedlang.compiler.util.Lists;
@@ -116,6 +117,12 @@ public class PatioCodeGenEffects {
Source source,
PatioCodeGenContext context
) {
+ context = context.addCompilationUnitElement(new PatioExceptionTypeDefinition(
+ context.exceptionTypeName(effect),
+ PatioCodeGenTypes.VALUE_TYPE,
+ source
+ ));
+
var effectPointerResult = context.allocateVal(
PatioCodeGenLocalSpace.USER_DEFINED_EFFECT_POINTER,
effect.name(),
@@ -264,9 +271,10 @@ public class PatioCodeGenEffects {
}
public static PatioCodeGenContext try_(
+ PatioLocalRef target,
UserDefinedEffect effect,
Map<String, PatioOperand> handlerMethodsByName,
- Function<PatioCodeGenContext, PatioCodeGenContext> generateBody,
+ Function<PatioCodeGenContext, PatioCodeGenResult<PatioBlock>> generateBody,
Source source,
PatioCodeGenContext context
) {
@@ -307,12 +315,37 @@ public class PatioCodeGenEffects {
));
}
- context = generateBody.apply(context);
+ var bodyResult = generateBody.apply(context);
+ var body = bodyResult.value();
+ context = bodyResult.context();
- context = context.addInstruction(new PatioCall(
- Optional.empty(),
- POP_HANDLER_DECLARATION.name(),
- List.of(),
+ var exceptionValueResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TEMPORARY,
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var exceptionValue = exceptionValueResult.value();
+ context = exceptionValueResult.context();
+
+ context = context.addInstruction(new PatioTry(
+ List.of(target),
+ List.of(
+ new PatioCatchClause(
+ context.exceptionTypeName(effect),
+ exceptionValue,
+ new PatioBlock(
+ List.of(),
+ List.of(exceptionValue),
+ source
+ ),
+ source
+ )
+ ),
+ body.addInstruction(new PatioCall(
+ Optional.empty(),
+ POP_HANDLER_DECLARATION.name(),
+ List.of(),
+ source
+ )),
source
));
@@ -472,6 +505,23 @@ public class PatioCodeGenEffects {
return context;
}
+ public static PatioCodeGenContext break_(
+ UserDefinedEffect effect,
+ PatioOperand value,
+ Source source,
+ PatioCodeGenContext context
+ ) {
+ var exceptionTypeName = context.exceptionTypeName(effect);
+
+ context = context.addInstruction(new PatioThrow(
+ exceptionTypeName,
+ value,
+ source
+ ));
+
+ return context;
+ }
+
private static PatioCodeGenContext getCurrentEffectHandler(
PatioLocalRef target,
Source source,
diff --git a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioBlock.java b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioBlock.java
index 8eecfa84..50c59fbf 100644
--- a/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioBlock.java
+++ b/src/main/java/org/shedlang/compiler/patio/ast/instructions/PatioBlock.java
@@ -2,6 +2,7 @@ package org.shedlang.compiler.patio.ast.instructions;
import org.shedlang.compiler.patio.ast.operands.PatioOperand;
import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.util.Lists;
import java.util.List;
@@ -10,4 +11,11 @@ public record PatioBlock(
List<PatioOperand> results,
Source source
) {
+ public PatioBlock addInstruction(PatioInstruction instruction) {
+ return new PatioBlock(
+ Lists.concat(this.body, List.of(instruction)),
+ this.results,
+ this.source
+ );
+ }
}