aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-11-19 15:11:27 +0000
committerMichael Williamson <mike@zwobble.org>2023-11-19 15:11:27 +0000
commitaf335486c659fb6f5d065eb61014074045e4e81d (patch)
tree47f34b5fd17739e4a74e004de4a47d8b6b61bdcb /src/main/java
parent84f3a53ac9a784d13aa74f88993847beadd5904f (diff)
Generate Patio code for try statements
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java26
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java89
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java1
3 files changed, 109 insertions, 7 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index d97eeeff..dc4733f4 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -13,10 +13,7 @@ import org.shedlang.compiler.stackir.StackIrNamespace;
import org.shedlang.compiler.stackir.instructions.*;
import org.shedlang.compiler.types.NamespaceName;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class PatioCodeGen {
private PatioCodeGen() {}
@@ -607,7 +604,26 @@ public class PatioCodeGen {
}
case TryInstruction try_ -> {
- throw new UnsupportedOperationException("TODO");
+ var handlerMethodsByName = new HashMap<String, PatioOperand>();
+
+ for (var handlerMethodName : try_.handlerMethodNames().reversed()) {
+ var handlerMethodResult = context.temporaryPop();
+ var handlerMethod = handlerMethodResult.value();
+ context = handlerMethodResult.context();
+
+ handlerMethodsByName.put(handlerMethodName, handlerMethod);
+ }
+
+ context = PatioCodeGenEffects.try_(
+ try_.handledEffect(),
+ handlerMethodsByName,
+ bodyContext ->
+ generateInstructions(try_.body(), bodyContext),
+ try_.source(),
+ context
+ );
+
+ yield context;
}
case TupleCreateInstruction tupleCreate -> {
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
index fa83c187..2ade62ee 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java
@@ -6,6 +6,7 @@ import org.shedlang.compiler.patio.ast.PatioLocal;
import org.shedlang.compiler.patio.ast.instructions.*;
import org.shedlang.compiler.patio.ast.operands.PatioInt;
import org.shedlang.compiler.patio.ast.operands.PatioLocalRef;
+import org.shedlang.compiler.patio.ast.operands.PatioOperand;
import org.shedlang.compiler.patio.ast.types.PatioDataLayout;
import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
import org.shedlang.compiler.patio.ast.types.PatioType;
@@ -19,11 +20,14 @@ import org.shedlang.compiler.util.Lists;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.function.Function;
import java.util.stream.IntStream;
public class PatioCodeGenEffects {
private static final PatioType EFFECT_TAG_TYPE = PatioTypes.INT;
private static final PatioType EFFECT_METHOD_INDEX_TYPE = PatioTypes.INT;
+ private static final PatioType EFFECT_HANDLER_TYPE = PatioTypes.DATA_POINTER;
+ private static final PatioType EFFECT_HANDLER_METHOD_TYPE = PatioCodeGenClosures.CLOSURE_TYPE;
private static final PatioFunctionDeclaration FIND_HANDLER_METHOD_DECLARATION = new PatioFunctionDeclaration(
"shed__runtime__effects_find_handler_method",
@@ -31,7 +35,34 @@ public class PatioCodeGenEffects {
new PatioLocal.Param("effectTag", EFFECT_TAG_TYPE),
new PatioLocal.Param("methodIndex", EFFECT_METHOD_INDEX_TYPE)
),
- PatioCodeGenTypes.VALUE_TYPE,
+ EFFECT_HANDLER_METHOD_TYPE,
+ Sources.RUNTIME
+ );
+
+ private static final PatioFunctionDeclaration PUSH_HANDLER_DECLARATION = new PatioFunctionDeclaration(
+ "shed__runtime__effects_push_handler",
+ List.of(
+ new PatioLocal.Param("effectTag", EFFECT_TAG_TYPE)
+ ),
+ EFFECT_HANDLER_TYPE,
+ Sources.RUNTIME
+ );
+
+ private static final PatioFunctionDeclaration SET_HANDLER_METHOD_DECLARATION = new PatioFunctionDeclaration(
+ "shed__runtime__effects_set_handler_method",
+ List.of(
+ new PatioLocal.Param("handler", EFFECT_HANDLER_TYPE),
+ new PatioLocal.Param("methodIndex", EFFECT_METHOD_INDEX_TYPE),
+ new PatioLocal.Param("handlerMethod", EFFECT_HANDLER_METHOD_TYPE)
+ ),
+ PatioTypes.VOID,
+ Sources.RUNTIME
+ );
+
+ private static final PatioFunctionDeclaration POP_HANDLER_DECLARATION = new PatioFunctionDeclaration(
+ "shed__runtime__effects_pop_handler",
+ List.of(),
+ PatioTypes.VOID,
Sources.RUNTIME
);
@@ -88,7 +119,7 @@ public class PatioCodeGenEffects {
var handlerMethodResult = bodyContext.allocateVal(
PatioCodeGenLocalSpace.EFFECT_HANDLER_METHOD,
- PatioCodeGenClosures.CLOSURE_TYPE
+ EFFECT_HANDLER_METHOD_TYPE
);
var handlerMethod = handlerMethodResult.value();
bodyContext = handlerMethodResult.context();
@@ -191,6 +222,60 @@ public class PatioCodeGenEffects {
return context;
}
+ public static PatioCodeGenContext try_(
+ UserDefinedEffect effect,
+ Map<String, PatioOperand> handlerMethodsByName,
+ Function<PatioCodeGenContext, PatioCodeGenContext> generateBody,
+ Source source,
+ PatioCodeGenContext context
+ ) {
+ context = context
+ .ensureCompilationUnitElement(PUSH_HANDLER_DECLARATION)
+ .ensureCompilationUnitElement(SET_HANDLER_METHOD_DECLARATION)
+ .ensureCompilationUnitElement(POP_HANDLER_DECLARATION);
+
+ var effectHandlerResult = context.allocateVal(
+ PatioCodeGenLocalSpace.EFFECT_HANDLER,
+ EFFECT_HANDLER_TYPE
+ );
+ var effectHandler = effectHandlerResult.value();
+ context = effectHandlerResult.context();
+
+ context = context.addInstruction(new PatioCall(
+ Optional.of(effectHandler),
+ PUSH_HANDLER_DECLARATION.name(),
+ List.of(
+ new PatioInt(context.effectTag(effect))
+ ),
+ source
+ ));
+
+ var effectInfo = context.userDefinedEffectInfo(effect);
+ for (var handlerMethodInfo : effectInfo.methods()) {
+ context = context.addInstruction(new PatioCall(
+ Optional.empty(),
+ SET_HANDLER_METHOD_DECLARATION.name(),
+ List.of(
+ effectHandler,
+ new PatioInt(handlerMethodInfo.fieldIndex()),
+ handlerMethodsByName.get(handlerMethodInfo.name())
+ ),
+ source
+ ));
+ }
+
+ context = generateBody.apply(context);
+
+ context = context.addInstruction(new PatioCall(
+ Optional.of(effectHandler),
+ POP_HANDLER_DECLARATION.name(),
+ List.of(),
+ source
+ ));
+
+ return context;
+ }
+
private static PatioDataLayout userDefinedEffectLayout(
UserDefinedEffect effect,
PatioCodeGenContext context
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
index 255a69c5..14ba666c 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
@@ -7,6 +7,7 @@ public enum PatioCodeGenLocalSpace {
CLOSURE("closure"),
CLOSURE_POINTER("closurePointer"),
CLOSURE_FUNCTION_POINTER("closureFunctionPointer"),
+ EFFECT_HANDLER("effectHandler"),
EFFECT_HANDLER_METHOD("effectHandlerMethod"),
MAIN("main"),
NAMESPACE_IS_INITED_POINTER("namespaceIsInitedPointer"),