mirror of
https://github.com/irmen/prog8.git
synced 2025-02-26 11:29:24 +00:00
don't fall-through into nested subroutine
This commit is contained in:
parent
1cc1f2d91d
commit
c495f54bbb
@ -1,7 +1,6 @@
|
|||||||
package prog8.ast.processing
|
package prog8.ast.processing
|
||||||
|
|
||||||
import prog8.ast.Module
|
import prog8.ast.*
|
||||||
import prog8.ast.Program
|
|
||||||
import prog8.ast.base.DataType
|
import prog8.ast.base.DataType
|
||||||
import prog8.ast.base.FatalAstException
|
import prog8.ast.base.FatalAstException
|
||||||
import prog8.ast.base.initvarsSubName
|
import prog8.ast.base.initvarsSubName
|
||||||
@ -64,7 +63,10 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
|
|||||||
|
|
||||||
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
|
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
|
||||||
|
|
||||||
|
private val addReturns = mutableListOf<Pair<INameScope, Int>>()
|
||||||
|
|
||||||
override fun visit(module: Module) {
|
override fun visit(module: Module) {
|
||||||
|
addReturns.clear()
|
||||||
super.visit(module)
|
super.visit(module)
|
||||||
|
|
||||||
val (blocks, other) = module.statements.partition { it is Block }
|
val (blocks, other) = module.statements.partition { it is Block }
|
||||||
@ -92,6 +94,13 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
|
|||||||
val directives = module.statements.filter {it is Directive && it.directive in directivesToMove}
|
val directives = module.statements.filter {it is Directive && it.directive in directivesToMove}
|
||||||
module.statements.removeAll(directives)
|
module.statements.removeAll(directives)
|
||||||
module.statements.addAll(0, directives)
|
module.statements.addAll(0, directives)
|
||||||
|
|
||||||
|
for(pos in addReturns) {
|
||||||
|
println(pos)
|
||||||
|
val returnStmt = Return(null, pos.first.position)
|
||||||
|
returnStmt.linkParents(pos.first as Node)
|
||||||
|
pos.first.statements.add(pos.second, returnStmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(block: Block): Statement {
|
override fun visit(block: Block): Statement {
|
||||||
@ -161,6 +170,19 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
|
|||||||
override fun visit(subroutine: Subroutine): Statement {
|
override fun visit(subroutine: Subroutine): Statement {
|
||||||
super.visit(subroutine)
|
super.visit(subroutine)
|
||||||
|
|
||||||
|
val scope = subroutine.definingScope()
|
||||||
|
if(scope is Subroutine) {
|
||||||
|
for(stmt in scope.statements.withIndex()) {
|
||||||
|
if(stmt.index>0 && stmt.value===subroutine) {
|
||||||
|
val precedingStmt = scope.statements[stmt.index-1]
|
||||||
|
if(precedingStmt !is Jump && precedingStmt !is Subroutine) {
|
||||||
|
// insert a return statement before a nested subroutine, to avoid falling trough inside the subroutine
|
||||||
|
addReturns.add(Pair(scope, stmt.index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val varDecls = subroutine.statements.filterIsInstance<VarDecl>()
|
val varDecls = subroutine.statements.filterIsInstance<VarDecl>()
|
||||||
subroutine.statements.removeAll(varDecls)
|
subroutine.statements.removeAll(varDecls)
|
||||||
subroutine.statements.addAll(0, varDecls)
|
subroutine.statements.addAll(0, varDecls)
|
||||||
|
@ -96,7 +96,7 @@ fun compileProgram(filepath: Path,
|
|||||||
programAst.checkValid(compilerOptions) // check if final tree is valid
|
programAst.checkValid(compilerOptions) // check if final tree is valid
|
||||||
programAst.checkRecursion() // check if there are recursive subroutine calls
|
programAst.checkRecursion() // check if there are recursive subroutine calls
|
||||||
|
|
||||||
// printAst(programAst)
|
printAst(programAst)
|
||||||
|
|
||||||
if(writeAssembly) {
|
if(writeAssembly) {
|
||||||
// asm generation directly from the Ast, no need for intermediate code
|
// asm generation directly from the Ast, no need for intermediate code
|
||||||
|
179
examples/test.p8
179
examples/test.p8
@ -6,99 +6,104 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
ubyte[] uba = [10,0,2,8,5,4,3,9]
|
print_name()
|
||||||
uword[] uwa = [1000,0,200,8000,50,40000,3,900]
|
|
||||||
byte[] ba = [-10,0,-2,8,5,4,-3,9,-99]
|
|
||||||
word[] wa = [-1000,0,-200,8000,50,31111,3,-900]
|
|
||||||
|
|
||||||
for ubyte ub in uba {
|
sub print_name() {
|
||||||
c64scr.print_ub(ub)
|
c64scr.print("irmen\n")
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
for uword uw in uwa {
|
; ubyte[] uba = [10,0,2,8,5,4,3,9]
|
||||||
c64scr.print_uw(uw)
|
; uword[] uwa = [1000,0,200,8000,50,40000,3,900]
|
||||||
c64.CHROUT(',')
|
; byte[] ba = [-10,0,-2,8,5,4,-3,9,-99]
|
||||||
}
|
; word[] wa = [-1000,0,-200,8000,50,31111,3,-900]
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for ubyte ub in uba {
|
||||||
for byte bb in ba {
|
; c64scr.print_ub(ub)
|
||||||
c64scr.print_b(bb)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for uword uw in uwa {
|
||||||
for word ww in wa {
|
; c64scr.print_uw(uw)
|
||||||
c64scr.print_w(ww)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
c64.CHROUT('\n')
|
; for byte bb in ba {
|
||||||
|
; c64scr.print_b(bb)
|
||||||
sort(uba)
|
; c64.CHROUT(',')
|
||||||
sort(uwa)
|
; }
|
||||||
sort(ba)
|
; c64.CHROUT('\n')
|
||||||
sort(wa)
|
;
|
||||||
|
; for word ww in wa {
|
||||||
for ubyte ub2 in uba {
|
; c64scr.print_w(ww)
|
||||||
c64scr.print_ub(ub2)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
; c64.CHROUT('\n')
|
||||||
|
;
|
||||||
for uword uw2 in uwa {
|
; sort(uba)
|
||||||
c64scr.print_uw(uw2)
|
; sort(uwa)
|
||||||
c64.CHROUT(',')
|
; sort(ba)
|
||||||
}
|
; sort(wa)
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for ubyte ub2 in uba {
|
||||||
for byte bb2 in ba {
|
; c64scr.print_ub(ub2)
|
||||||
c64scr.print_b(bb2)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for uword uw2 in uwa {
|
||||||
for word ww2 in wa {
|
; c64scr.print_uw(uw2)
|
||||||
c64scr.print_w(ww2)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
c64.CHROUT('\n')
|
; for byte bb2 in ba {
|
||||||
|
; c64scr.print_b(bb2)
|
||||||
reverse(uba)
|
; c64.CHROUT(',')
|
||||||
reverse(uwa)
|
; }
|
||||||
reverse(ba)
|
; c64.CHROUT('\n')
|
||||||
reverse(wa)
|
;
|
||||||
|
; for word ww2 in wa {
|
||||||
for ubyte ub3 in uba {
|
; c64scr.print_w(ww2)
|
||||||
c64scr.print_ub(ub3)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
; c64.CHROUT('\n')
|
||||||
|
;
|
||||||
for uword uw3 in uwa {
|
; reverse(uba)
|
||||||
c64scr.print_uw(uw3)
|
; reverse(uwa)
|
||||||
c64.CHROUT(',')
|
; reverse(ba)
|
||||||
}
|
; reverse(wa)
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for ubyte ub3 in uba {
|
||||||
for byte bb3 in ba {
|
; c64scr.print_ub(ub3)
|
||||||
c64scr.print_b(bb3)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
|
; for uword uw3 in uwa {
|
||||||
for word ww3 in wa {
|
; c64scr.print_uw(uw3)
|
||||||
c64scr.print_w(ww3)
|
; c64.CHROUT(',')
|
||||||
c64.CHROUT(',')
|
; }
|
||||||
}
|
; c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
;
|
||||||
c64.CHROUT('\n')
|
; for byte bb3 in ba {
|
||||||
|
; c64scr.print_b(bb3)
|
||||||
|
; c64.CHROUT(',')
|
||||||
|
; }
|
||||||
|
; c64.CHROUT('\n')
|
||||||
|
;
|
||||||
|
; for word ww3 in wa {
|
||||||
|
; c64scr.print_w(ww3)
|
||||||
|
; c64.CHROUT(',')
|
||||||
|
; }
|
||||||
|
; c64.CHROUT('\n')
|
||||||
|
; c64.CHROUT('\n')
|
||||||
|
|
||||||
|
|
||||||
; TODO 2 for loops that both define the same loopvar -> double definition -> fix second for -> 'unknown symbol' ????
|
; TODO 2 for loops that both define the same loopvar -> double definition -> fix second for -> 'unknown symbol' ????
|
||||||
; TODO code runs into a subroutine that follows it instead of inserting an implicit return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user