diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-10-29 18:17:47 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-10-29 18:17:47 +0000 |
| commit | 3b3040d8e199c9720a16f77dcc8fdedee56ef7cd (patch) | |
| tree | 83097c0f88890f81558db58118637acf0b111b7f /src/main/java | |
| parent | 35a4ef5402fecc3ae37361adb4a817b3beeada31 (diff) | |
Extract typeCheckFunctionReturnValue()
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java | 103 |
1 files changed, 45 insertions, 58 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index a24ca306..0ceca376 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -498,67 +498,37 @@ public class TypeChecker { var typedBody = bodyResult.value(); context = bodyResult.context(); + switch (typedBody.behaviour()) { + case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { + context = typeCheckFunctionReturnValue( + blockReturn.type(), + // TODO: source should be last statement? + typedBody.source(), + context + ); + } + case TypedFunctionStatementBehaviour.Continue continue_ -> { + if (context.returnTypeState() instanceof ReturnTypeState.ImplicitLowerBound implicitLowerBound) { + checkIsSubType(Types.UNIT, implicitLowerBound.type(), untyped.source(), context); + } else { + context = typeCheckFunctionReturnValue(Types.UNIT, untyped.source(), context); + } + } + case TypedFunctionStatementBehaviour.Terminate terminate -> { + } + } + Type returnType; switch (context.returnTypeState()) { case ReturnTypeState.Explicit explicit -> { returnType = explicit.type(); - - switch (typedBody.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - if (!isSubType(blockReturn.type(), explicit.type(), context)) { - throw new UnexpectedTypeError( - TypeSets.type(explicit.type()), - blockReturn.type(), - untyped.source() - ); - } - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - if (!isSubType(Types.UNIT, explicit.type(), context)) { - throw new UnexpectedTypeError( - TypeSets.type(explicit.type()), - Types.UNIT, - untyped.source() - ); - } - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - } - } } case ReturnTypeState.ImplicitLowerBound implicitLowerBound -> { - switch (typedBody.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - throw new UnsupportedOperationException("TODO"); - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - returnType = implicitLowerBound.type(); - - checkIsSubType( - Types.UNIT, - implicitLowerBound.type(), - typedBody.source(), - context - ); - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - returnType = implicitLowerBound.type(); - } - } + returnType = implicitLowerBound.type(); } case ReturnTypeState.ImplicitUnknown implicitUnknown -> { - switch (typedBody.behaviour()) { - case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> { - throw new UnsupportedOperationException("TODO"); - } - case TypedFunctionStatementBehaviour.Continue continue_ -> { - returnType = Types.UNIT; - } - case TypedFunctionStatementBehaviour.Terminate terminate -> { - throw new UnsupportedOperationException("TODO"); - } - } + throw new UnsupportedOperationException("TODO"); } case ReturnTypeState.NotInFunction notInFunction -> { // TODO: better error @@ -690,29 +660,46 @@ public class TypeChecker { var expression = expressionResult.value(); context = expressionResult.context(); + context = typeCheckFunctionReturnValue(expression.type(), expression.source(), context); + + var typed = new TypedFunctionReturnNode(expression, untyped.source()); + + return context.toResult(typed); + } + + private static TypeCheckerContext typeCheckFunctionReturnValue( + Type returnValueType, + Source returnValueSource, + TypeCheckerContext context + ) { switch (context.returnTypeState()) { case ReturnTypeState.Explicit explicit -> { - checkExpressionType(expression, explicit.type(), context); + checkIsSubType(returnValueType, explicit.type(), returnValueSource, context); } case ReturnTypeState.ImplicitUnknown implicitUnknown -> { context = context.updateReturnTypeState( - ReturnTypeState.implicitLowerBound(expression.type()) + ReturnTypeState.implicitLowerBound(returnValueType) ); } case ReturnTypeState.ImplicitLowerBound implicitLowerBound -> { throw new UnsupportedOperationException("TODO"); +// var supertype = Types.commonSupertype(List.of( +// implicitLowerBound.type(), +// returnValueType +// )); +// context = context.updateReturnTypeState( +// ReturnTypeState.implicitLowerBound(supertype) +// ); } case ReturnTypeState.NotInFunction notInFunction -> { // This should be syntactically impossible, but since we only have // one context type, we check for this possibility and throw a // reasonable error. - throw new CannotReturnOutsideOfFunctionError(untyped.source()); + throw new CannotReturnOutsideOfFunctionError(returnValueSource); } }; - var typed = new TypedFunctionReturnNode(expression, untyped.source()); - - return context.toResult(typed); + return context; } static TypedFunctionSignatureNode typeCheckFunctionSignature( |
