fix check for routine that returns multiple values but in status bit. Fixes #79

This commit is contained in:
Irmen de Jong 2022-10-19 23:23:49 +02:00
parent 2340760f53
commit 53b0b562e6
3 changed files with 28 additions and 7 deletions

View File

@ -1005,7 +1005,7 @@ internal class AstChecker(private val program: Program,
// It's not (yet) possible to handle these multiple return values because assignments // It's not (yet) possible to handle these multiple return values because assignments
// are only to a single unique target at the same time. // are only to a single unique target at the same time.
// EXCEPTION: // EXCEPTION:
// if the asmsub returns multiple values and one of them is via a status register bit, // if the asmsub returns multiple values and one of them is via a status register bit (such as carry),
// it *is* possible to handle them by just actually assigning the register value and // it *is* possible to handle them by just actually assigning the register value and
// dealing with the status bit as just being that, the status bit after the call. // dealing with the status bit as just being that, the status bit after the call.
val (returnRegisters, _) = stmt.asmReturnvaluesRegisters.partition { rr -> rr.registerOrPair != null } val (returnRegisters, _) = stmt.asmReturnvaluesRegisters.partition { rr -> rr.registerOrPair != null }

View File

@ -91,6 +91,10 @@ internal class VerifyFunctionArgTypes(val program: Program, val errors: IErrorRe
if(target.asmReturnvaluesRegisters.size>1) { if(target.asmReturnvaluesRegisters.size>1) {
// multiple return values will NOT work inside an expression. // multiple return values will NOT work inside an expression.
// they MIGHT work in a regular assignment or just a function call statement. // they MIGHT work in a regular assignment or just a function call statement.
// EXCEPTION:
// if the asmsub returns multiple values and one of them is via a status register bit (such as carry),
// it *is* possible to handle them by just actually assigning the register value and
// dealing with the status bit as just being that, the status bit after the call.
val parent = if(call is Statement) call.parent else if(call is Expression) call.parent else null val parent = if(call is Statement) call.parent else if(call is Expression) call.parent else null
if (call !is FunctionCallStatement) { if (call !is FunctionCallStatement) {
val checkParent = val checkParent =
@ -99,7 +103,10 @@ internal class VerifyFunctionArgTypes(val program: Program, val errors: IErrorRe
else else
parent parent
if (checkParent !is Assignment && checkParent !is VarDecl) { if (checkParent !is Assignment && checkParent !is VarDecl) {
return Pair("can't use subroutine call that returns multiple return values here", call.position) val (returnRegisters, _) = target.asmReturnvaluesRegisters.partition { rr -> rr.registerOrPair != null }
if (returnRegisters.size>1) {
return Pair("can't use subroutine call that returns multiple return values here", call.position)
}
} }
} }
} }

View File

@ -1,9 +1,23 @@
main { main {
sub start() { asmsub multi() -> ubyte @A, ubyte @Pc {
ubyte aa = 42 %asm {{
ubyte bb = 99 lda #42
aa += bb sec
rts
}}
}
%asmbinary "build.gradle" sub start() {
ubyte value
value = multi()
while 0==multi() {
value++
}
if multi() {
value++
}
} }
} }