From 72ce4e94a08baf5d722582e2914bb2074ef7d1a7 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 2 Dec 2023 23:55:03 +0000 Subject: Type check break statements --- .../compiler/ast/typed/TypedBreakNode.java | 13 ++++++++++ .../ast/typed/TypedFunctionStatementNode.java | 2 +- .../org/shedlang/compiler/shid/ShidCodeGen.java | 3 +++ .../shedlang/compiler/typechecker/TypeChecker.java | 30 +++++++++++++++++++++- ...nnotBreakOutsideOfEffectHandlerMethodError.java | 10 ++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/typed/TypedBreakNode.java create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CannotBreakOutsideOfEffectHandlerMethodError.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedBreakNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedBreakNode.java new file mode 100644 index 00000000..bc7ea34a --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedBreakNode.java @@ -0,0 +1,13 @@ +package org.shedlang.compiler.ast.typed; + +import org.shedlang.compiler.sources.Source; + +public record TypedBreakNode( + TypedExpressionNode expression, + Source source +) implements TypedFunctionStatementNode { + @Override + public TypedFunctionStatementBehaviour behaviour() { + return TypedFunctionStatementBehaviour.TERMINATE; + } +} diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionStatementNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionStatementNode.java index a79437ec..82c90eea 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionStatementNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionStatementNode.java @@ -1,5 +1,5 @@ package org.shedlang.compiler.ast.typed; -public sealed interface TypedFunctionStatementNode extends TypedNode permits TypedAssignNode, TypedBlockReturnNode, TypedExpressionStatementNode, TypedFunctionReturnNode, TypedResumeNode, TypedWhileNode { +public sealed interface TypedFunctionStatementNode extends TypedNode permits TypedAssignNode, TypedBlockReturnNode, TypedBreakNode, TypedExpressionStatementNode, TypedFunctionReturnNode, TypedResumeNode, TypedWhileNode { TypedFunctionStatementBehaviour behaviour(); } diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java index 8c930b29..5ed3ffdb 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -336,6 +336,9 @@ public class ShidCodeGen { case TypedBlockReturnNode blockReturn -> compileBlockReturn(blockReturn, context); + case TypedBreakNode break_ -> + throw new UnsupportedOperationException("TODO"); + case TypedExpressionStatementNode expressionStatement -> compileExpressionStatement(expressionStatement, context); diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index e7052ba3..ae91c3d0 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -280,7 +280,35 @@ public class TypeChecker { UntypedBreakNode untyped, TypeCheckerContext context ) { - throw new UnsupportedOperationException("TODO"); + switch (context.returnTypeState()) { + case ReturnTypeState.Explicit explicit -> { + throw new CannotBreakOutsideOfEffectHandlerMethodError(untyped.source()); + } + case ReturnTypeState.ImplicitUnknown implicitUnknown -> { + throw new CannotBreakOutsideOfEffectHandlerMethodError(untyped.source()); + } + case ReturnTypeState.ImplicitLowerBound implicitLowerBound -> { + throw new CannotBreakOutsideOfEffectHandlerMethodError(untyped.source()); + } + case ReturnTypeState.NotInFunction notInFunction -> { + throw new CannotBreakOutsideOfEffectHandlerMethodError(untyped.source()); + } + case ReturnTypeState.EffectHandler effectHandler -> { + var typedExpressionResult = typeCheckExpressionOptional( + untyped.expression(), + Optional.of(effectHandler.resumeType()), + untyped.source(), + context + ); + var typedExpression = typedExpressionResult.value(); + context = typedExpressionResult.context(); + + return context.toResult(new TypedBreakNode( + typedExpression, + untyped.source() + )); + } + } } private static TypeCheckerResult typeCheckCall( diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotBreakOutsideOfEffectHandlerMethodError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotBreakOutsideOfEffectHandlerMethodError.java new file mode 100644 index 00000000..3a32ecaa --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotBreakOutsideOfEffectHandlerMethodError.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.typechecker.errors; + +import org.shedlang.compiler.errors.SourceError; +import org.shedlang.compiler.sources.Source; + +public class CannotBreakOutsideOfEffectHandlerMethodError extends SourceError { + public CannotBreakOutsideOfEffectHandlerMethodError(Source source) { + super("Cannot break outside of effect handler method", source); + } +} -- cgit v1.2.3