mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
fix nested label lookups in anon scopes (partly)
This commit is contained in:
112
compiler/test/TestScoping.kt
Normal file
112
compiler/test/TestScoping.kt
Normal file
@@ -0,0 +1,112 @@
|
||||
package prog8tests
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import prog8.ast.expressions.NumericLiteralValue
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compiler.target.C64Target
|
||||
import prog8tests.helpers.assertSuccess
|
||||
import prog8tests.helpers.compileText
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class TestScoping {
|
||||
|
||||
@Test
|
||||
fun testAnonScopeVarsMovedIntoSubroutineScope() {
|
||||
val src = """
|
||||
main {
|
||||
sub start() {
|
||||
repeat {
|
||||
ubyte xx = 99
|
||||
xx++
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
val result = compileText(C64Target, false, src, writeAssembly = false).assertSuccess()
|
||||
val module = result.programAst.toplevelModule
|
||||
val mainBlock = module.statements.single() as Block
|
||||
val start = mainBlock.statements.single() as Subroutine
|
||||
val repeatbody = start.statements.filterIsInstance<RepeatLoop>().single().body
|
||||
assertFalse(mainBlock.statements.any { it is VarDecl }, "no vars moved to main block")
|
||||
val subroutineVars = start.statements.filterIsInstance<VarDecl>()
|
||||
assertEquals(1, subroutineVars.size, "var from repeat anonscope must be moved up to subroutine")
|
||||
assertEquals("xx", subroutineVars[0].name)
|
||||
assertFalse(repeatbody.statements.any { it is VarDecl }, "var should have been removed from repeat anonscope")
|
||||
val initassign = repeatbody.statements[0] as? Assignment
|
||||
assertEquals(listOf("xx"), initassign?.target?.identifier?.nameInSource, "vardecl in repeat should be replaced by init assignment")
|
||||
assertEquals(99, (initassign?.value as? NumericLiteralValue)?.number?.toInt(), "vardecl in repeat should be replaced by init assignment")
|
||||
assertTrue(repeatbody.statements[1] is PostIncrDecr)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLabelsWithAnonScopes() {
|
||||
val src = """
|
||||
main {
|
||||
sub start() {
|
||||
uword addr
|
||||
goto labeloutside
|
||||
|
||||
if true {
|
||||
if true {
|
||||
addr = &iflabel
|
||||
addr = &labelinside
|
||||
addr = &labeloutside
|
||||
addr = &main.start.nested.nestedlabel
|
||||
; addr = &nested.nestedlabel ; TODO should also work!!
|
||||
goto labeloutside
|
||||
goto iflabel
|
||||
goto main.start.nested.nestedlabel
|
||||
; goto nested.nestedlabel ; TODO should also work!!
|
||||
}
|
||||
iflabel:
|
||||
}
|
||||
|
||||
repeat {
|
||||
addr = &iflabel
|
||||
addr = &labelinside
|
||||
addr = &labeloutside
|
||||
addr = &main.start.nested.nestedlabel
|
||||
; addr = &nested.nestedlabel ; TODO should also work!!
|
||||
goto iflabel
|
||||
goto labelinside
|
||||
goto main.start.nested.nestedlabel
|
||||
; goto nested.nestedlabel ; TODO should also work!!
|
||||
labelinside:
|
||||
}
|
||||
|
||||
sub nested () {
|
||||
nestedlabel:
|
||||
addr = &nestedlabel
|
||||
goto nestedlabel
|
||||
goto main.start.nested.nestedlabel
|
||||
}
|
||||
|
||||
labeloutside:
|
||||
addr = &iflabel
|
||||
addr = &labelinside
|
||||
addr = &labeloutside
|
||||
addr = &main.start.nested.nestedlabel
|
||||
; addr = &nested.nestedlabel ; TODO should also work!!
|
||||
goto main.start.nested.nestedlabel
|
||||
; goto nested.nestedlabel ; TODO should also work!!
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
val result = compileText(C64Target, false, src, writeAssembly = true).assertSuccess()
|
||||
val module = result.programAst.toplevelModule
|
||||
val mainBlock = module.statements.single() as Block
|
||||
val start = mainBlock.statements.single() as Subroutine
|
||||
val labels = start.statements.filterIsInstance<Label>()
|
||||
assertEquals(1, labels.size, "only one label in subroutine scope")
|
||||
|
||||
TODO("fix the partial scoped lookups above as well")
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user