diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 869356ca3..50353c880 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1184,9 +1184,6 @@ internal class AstChecker(private val program: Program, defer.scope.accept(s) if(s.count>0) errors.err("defer cannot contain jumps or returns", defer.position) - - if(defer.parent !is Subroutine) - errors.err("currently defer is only supported in subroutine scope, not in nested scopes", defer.position) } override fun visit(expr: BinaryExpression) { diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstPostprocess.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstPostprocess.kt index 5552c53f0..21eeda051 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstPostprocess.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstPostprocess.kt @@ -60,15 +60,16 @@ private fun setDeferMasks(program: PtProgram, errors: IErrorReporter): Map() - val handler = sub.children[7] as PtSub + sub.children[7] shouldBe instanceOf() + val handler = sub.children[8] as PtSub handler.name shouldBe "p8s_prog8_invoke_defers" } } diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 4c7b90236..b3345c046 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -891,9 +891,9 @@ and the logic is declared very close to the spot where the allocation of the res It's possible to write a defer for a block of statements, but the advice is to keep such cleanup code as simple and short as possible. .. caution:: - Defers only work for subroutines that are written as regular Prog8 code. - If a piece of inlined assembly somehow causes the routine to exit, the compiler cannot detect this. - Defers will not be handled in such cases. + Defers only work for subroutines that are written in regular Prog8 code. + If a piece of inlined assembly somehow causes the routine to exit, the compiler cannot detect this, + and defers won't be handled in such cases. Library routines and builtin functions diff --git a/examples/test.p8 b/examples/test.p8 index 844044204..57d845db2 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,13 +1,28 @@ -%import floats +%import textio %option no_sysinit %zeropage basicsafe main { - - extsub $8000 = routine(float xx @FAC1, float yy @FAC2) - sub start() { - @($8000) = $60 - routine(1.234, 2.3445) + defer initial() + if allocate() { + txt.print("1") + defer deallocate() + txt.print("2") + return + } + txt.print("3") + } + + sub allocate() -> bool { + txt.print("allocate\n") + return true + } + + sub initial() { + txt.print("initial\n") + } + sub deallocate() { + txt.print("deallocate\n") } }