fix compiler crash when using a gosub/subroutinecall in a branch statement

This commit is contained in:
Irmen de Jong 2021-12-11 14:51:06 +01:00
parent 02010170ce
commit a7b5949e6a
3 changed files with 27 additions and 8 deletions

View File

@ -1340,9 +1340,7 @@ $repeatLabel lda $counterVar
throw AssemblyError("only else part contains code, shoud have been switched already")
val jump = stmt.truepart.statements.first() as? Jump
if(jump!=null) {
if(jump.isGosub)
throw FatalAstException("didn't expect GoSub here")
if(jump!=null && !jump.isGosub) {
// branch with only a jump (goto)
val instruction = branchInstruction(stmt.condition, false)
out(" $instruction ${getJumpTarget(jump)}")

View File

@ -279,7 +279,19 @@ class StatementOptimizer(private val program: Program,
}
override fun after(jump: Jump, parent: Node): Iterable<IAstModification> {
if(!jump.isGosub) {
if(jump.isGosub) {
// if the next statement is return with no returnvalue, change into a regular jump if there are no parameters as well.
val subroutineParams = jump.identifier?.targetSubroutine(program)?.parameters
if(subroutineParams!=null && subroutineParams.isEmpty()) {
val returnstmt = jump.nextSibling() as? Return
if(returnstmt!=null && returnstmt.value==null) {
return listOf(
IAstModification.Remove(returnstmt, parent as IStatementContainer),
IAstModification.ReplaceNode(jump, Jump(jump.address, jump.identifier, jump.generatedLabel, jump.position), parent)
)
}
}
} else {
// if the jump is to the next statement, remove the jump
val scope = jump.parent as IStatementContainer
val label = jump.identifier?.targetStatement(program)

View File

@ -3,9 +3,18 @@
main {
sub start() {
uword foobar
foobar()
ubyte @shared yy
yy = foobar()
}
sub foobar() -> ubyte {
if_mi {
foobar2()
foobar2()
return true
}
return 22
}
sub foobar2() {
main.start.yy++
}
}