From ee1c43ca919521a8a6b27fee0e9739d0e8e86a55 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 21 Apr 2021 20:22:16 +0200 Subject: [PATCH] improved scanning for return statement in routines that should return a value. --- compiler/res/prog8lib/string.p8 | 2 +- .../compiler/astprocessing/AstChecker.kt | 24 ++++++++++++++++++- examples/test.p8 | 24 ++++++++++++------- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/compiler/res/prog8lib/string.p8 b/compiler/res/prog8lib/string.p8 index d5fc170bf..e54a1aa30 100644 --- a/compiler/res/prog8lib/string.p8 +++ b/compiler/res/prog8lib/string.p8 @@ -178,7 +178,7 @@ _found sty P8ZP_SCRATCH_B1 asmsub compare(uword string1 @R0, uword string2 @AY) clobbers(Y) -> byte @A { ; Compares two strings for sorting. - ; Returns -1 (255), 0 or 1 depeding on wether string1 sorts before, equal or after string2. + ; Returns -1 (255), 0 or 1 depending on wether string1 sorts before, equal or after string2. ; Note that you can also directly compare strings and string values with eachother using ; comparison operators ==, < etcetera (it will use strcmp for you under water automatically). %asm {{ diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 9c5c8dcba..d7f97a0c5 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -196,6 +196,28 @@ internal class AstChecker(private val program: Program, super.visit(label) } + private fun hasReturnOrJump(scope: INameScope): Boolean { + class Searcher: IAstVisitor + { + var count=0 + + override fun visit(returnStmt: Return) { + count++ + } + override fun visit(jump: Jump) { + count++ + } + } + + val s=Searcher() + for(stmt in scope.statements) { + stmt.accept(s) + if(s.count>0) + return true + } + return s.count > 0 + } + override fun visit(subroutine: Subroutine) { fun err(msg: String) = errors.err(msg, subroutine.position) @@ -218,7 +240,7 @@ internal class AstChecker(private val program: Program, // subroutine must contain at least one 'return' or 'goto' // (or if it has an asm block, that must contain a 'rts' or 'jmp' or 'bra') - if(subroutine.statements.count { it is Return || it is Jump } == 0) { + if(!hasReturnOrJump(subroutine)) { if (subroutine.amountOfRtsInAsm() == 0) { if (subroutine.returntypes.isNotEmpty()) { // for asm subroutines with an address, no statement check is possible. diff --git a/examples/test.p8 b/examples/test.p8 index 22c25dc38..5a5a8a92f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,16 +7,22 @@ main { sub start() { - ubyte xx=existing_entry(1,2) + ubyte num_entries + + num_entries = 10 + ubyte ix + for ix in (num_entries-1)*2 downto 0 step -2 { + txt.print_ub(ix) + txt.spc() + } + + txt.nl() + num_entries = 10 + for ix in num_entries-1 downto 0 { + txt.print_ub(ix*2) + txt.spc() + } } - ; TODO FIX COMPILER ERROR ABOUT MISSING RETURN - - sub existing_entry(ubyte hash, uword symbol) -> ubyte { - if hash>10 - return 44 - else - return false - } }