diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-11-19 15:11:27 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-11-19 15:11:27 +0000 |
| commit | af335486c659fb6f5d065eb61014074045e4e81d (patch) | |
| tree | 47f34b5fd17739e4a74e004de4a47d8b6b61bdcb /src/main/java | |
| parent | 84f3a53ac9a784d13aa74f88993847beadd5904f (diff) | |
Generate Patio code for try statements
Diffstat (limited to 'src/main/java')
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"), |
