diff --git a/compiler/res/prog8lib/cx16/palette.p8 b/compiler/res/prog8lib/cx16/palette.p8 index 52efbe991..c3fba336d 100644 --- a/compiler/res/prog8lib/cx16/palette.p8 +++ b/compiler/res/prog8lib/cx16/palette.p8 @@ -152,27 +152,26 @@ palette { set_rgb(colors, len(colors)) } - uword[] default_colors_16 = [ - $000, ; 0 = black - $fff, ; 1 = white - $800, ; 2 = red - $afe, ; 3 = cyan - $c4c, ; 4 = purple - $0c5, ; 5 = green - $00a, ; 6 = blue - $ee7, ; 7 = yellow - $d85, ; 8 = orange - $640, ; 9 = brown - $f77, ; 10 = light red - $333, ; 11 = dark grey - $777, ; 12 = medium grey - $af6, ; 13 = light green - $08f, ; 14 = light blue - $bbb ; 15 = light grey - ] - sub set_default16() { ; set first 16 colors to the defaults on the X16 - set_rgb(default_colors_16, len(default_colors_16)) + uword[] colors = [ + $000, ; 0 = black + $fff, ; 1 = white + $800, ; 2 = red + $afe, ; 3 = cyan + $c4c, ; 4 = purple + $0c5, ; 5 = green + $00a, ; 6 = blue + $ee7, ; 7 = yellow + $d85, ; 8 = orange + $640, ; 9 = brown + $f77, ; 10 = light red + $333, ; 11 = dark grey + $777, ; 12 = medium grey + $af6, ; 13 = light green + $08f, ; 14 = light blue + $bbb ; 15 = light grey + ] + set_rgb(colors, len(colors)) } } diff --git a/compiler/test/TestCallgraph.kt b/compiler/test/TestCallgraph.kt index fff7830da..a4ff1706f 100644 --- a/compiler/test/TestCallgraph.kt +++ b/compiler/test/TestCallgraph.kt @@ -2,6 +2,7 @@ package prog8tests import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldContain import io.kotest.matchers.ints.shouldBeGreaterThanOrEqual import io.kotest.matchers.maps.shouldNotContainKey import io.kotest.matchers.shouldBe @@ -11,6 +12,7 @@ import prog8.ast.statements.Block import prog8.ast.statements.Subroutine import prog8.code.core.SourceCode import prog8.code.target.C64Target +import prog8.code.target.VMTarget import prog8.compiler.CallGraph import prog8.parser.Prog8Parser.parseModule import prog8tests.helpers.* @@ -222,4 +224,28 @@ class TestCallgraph: FunSpec({ errors.errors.size shouldBe 0 errors.warnings.size shouldBe 0 } + + test("subs that aren't called but only used as scope aren't unused") { + val src=""" +main { + sub start() { + cx16.r0L = main.scopesub.variable + cx16.r0L = main.scopesub.array[1] + cx16.r0++ + } + + sub scopesub() { + ubyte variable + ubyte[] array = [1,2,3] + + cx16.r0++ + } +}""" + val result = compileText(VMTarget(), true, src)!! + val callgraph = CallGraph(result.compilerAst) + val scopeSub = result.compilerAst.entrypoint.lookup(listOf("main", "scopesub")) as Subroutine + scopeSub.name shouldBe "scopesub" + callgraph.notCalledButReferenced shouldContain scopeSub + callgraph.unused(scopeSub) shouldBe false + } }) diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 1ee854741..926324614 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -709,7 +709,7 @@ main { ubyte counter counter++ } - test2(main.test.nested.counter) ; shouldn't crash but just give nice error + test2(main.test.nested.counter) } sub test2(ubyte value) { @@ -717,8 +717,7 @@ main { } }""" val errors = ErrorReporterForTests() - compileText(Cx16Target(), true, src, writeAssembly = false, errors = errors) shouldBe null - errors.errors.single() shouldContain "undefined symbol" + compileText(Cx16Target(), true, src, writeAssembly = false, errors = errors) shouldNotBe null } test("var to const") { diff --git a/compilerAst/src/prog8/compiler/CallGraph.kt b/compilerAst/src/prog8/compiler/CallGraph.kt index 7628ba97a..4c6cb234c 100644 --- a/compilerAst/src/prog8/compiler/CallGraph.kt +++ b/compilerAst/src/prog8/compiler/CallGraph.kt @@ -100,6 +100,16 @@ class CallGraph(private val program: Program) : IAstVisitor { val target = identifier.targetStatement(program) if(target!=null) allIdentifiersAndTargets[identifier] = target + + // if it's a scoped identifier, the subroutines in the name are also referenced! + val scope = identifier.definingScope + val name = identifier.nameInSource.toMutableList() + while(name.size>1) { + name.removeLast() + val scopeTarget = scope.lookup(name) + if(scopeTarget is Subroutine) + notCalledButReferenced += scopeTarget + } } override fun visit(inlineAssembly: InlineAssembly) { diff --git a/examples/test.p8 b/examples/test.p8 index a4bf0ed77..99f2b47ad 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,26 +1,19 @@ %import textio +%import palette %zeropage basicsafe %option no_sysinit main { sub start() { - ubyte xx = wobwob() - txt.print_ub(xx) - uword yy = wobwob2() - txt.print_uw(yy) + cx16.r0L = main.dummy.variable + cx16.r0L = main.dummy.array[1] + cx16.r0++ + } - asmsub wobwob() -> bool @Pc { - %asm {{ - sec - rts - }} - } + sub dummy() { + ubyte variable + ubyte[] array = [1,2,3] - asmsub wobwob2() -> bool @Pc { - %asm {{ - clc - rts - }} - } + cx16.r0++ } }