Skip to content

Commit

Permalink
fix symbol prefixing bug triggered by certain usage of %option no_sym…
Browse files Browse the repository at this point in the history
…bol_prefixing
  • Loading branch information
irmen committed Mar 3, 2025
1 parent 2b6510d commit 5b63590
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 40 deletions.
26 changes: 26 additions & 0 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,35 @@ class AsmGen6502(val prefixSymbols: Boolean, private val lastGeneratedLabelSeque
node.children.forEach { prefixSymbols(it) }
}

fun maybePrefixFunctionCallsAndIdentifierReferences(node: PtNode) {
if(node is PtFunctionCall) {
// function calls to subroutines defined in a block that does NOT have NoSymbolPrefixing, still have to be prefixed at the call site
val stNode = st.lookup(node.name)!!
if(stNode.astNode!!.definingBlock()?.options?.noSymbolPrefixing!=true) {
val index = node.parent.children.indexOf(node)
functionCallsToPrefix += node.parent to index
}
}
else if (node is PtIdentifier) {
// identifier references to things defined in a block that does NOT have NoSymbolPrefixing, still have to be prefixed at the referencing point
var lookupName = node.name
if(node.type.isSplitWordArray && (lookupName.endsWith("_lsb") || lookupName.endsWith("_msb"))) {
lookupName = lookupName.dropLast(4)
}
val stNode = st.lookup(lookupName) ?: throw AssemblyError("unknown identifier $node")
if(stNode.astNode!!.definingBlock()?.options?.noSymbolPrefixing!=true) {
val index = node.parent.children.indexOf(node)
nodesToPrefix += node.parent to index
}
}
node.children.forEach { maybePrefixFunctionCallsAndIdentifierReferences(it) }
}

program.allBlocks().forEach { block ->
if (!block.options.noSymbolPrefixing) {
prefixSymbols(block)
} else {
maybePrefixFunctionCallsAndIdentifierReferences(block)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
// NOTE: does NOT output code to save/restore the X register for this call! Every caller should deal with this in their own way!!
// (you can use subroutine.shouldSaveX() and saveX()/restoreX() routines as a help for this)

val symbol = asmgen.symbolTable.lookup(call.name)
val sub = symbol?.astNode as IPtSubroutine
val symbol = asmgen.symbolTable.lookup(call.name)!!
val sub = symbol.astNode as IPtSubroutine
val subAsmName = asmgen.asmSymbolName(call.name)

if(sub is PtAsmSub) {
Expand Down
29 changes: 29 additions & 0 deletions compiler/test/TestScoping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,33 @@ WARN name 'var1Warn' shadows occurrence at...
errors.errors[3] shouldContain "internalOk"
errors.errors[3] shouldContain "line 11"
}

test("ast node linkage and lookups ok even with no symbol prefixing") {
val src="""
main {
sub start() {
thing.routine()
}
}
thing {
%option no_symbol_prefixing
sub routine() {
other.something()
other.counter++
}
}
other {
sub something() {
}
uword @shared counter
}
"""

compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
}

})
2 changes: 0 additions & 2 deletions docs/source/todo.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
TODO
====

- fix scoping bug

- Look at github PR for improved romability (see github issue 149) Also search for "TODO: Romable"
- Sorting module gnomesort_uw could be optimized more by fully rewriting it in asm? Shellshort seems consistently faster even if most of the words are already sorted.

Expand Down
43 changes: 7 additions & 36 deletions examples/test.p8
Original file line number Diff line number Diff line change
@@ -1,52 +1,23 @@
%import textio
%option no_sysinit
%zeropage basicsafe
; scoping bug:

main {
const ubyte VALUE = 123

sub start() {
uword @shared @nozp location = $4000

@($3fff) = 55
@($4000) = 56
@($4001) = 57

txt.print_ub(@($3fff))
txt.spc()
txt.print_ub(@($4000))
txt.spc()
txt.print_ub(@($4001))
txt.nl()

for location in $4000 to $4002 {
@(location-1) = VALUE
txt.print_ub(@($3fff))
txt.spc()
txt.print_ub(@($4000))
txt.spc()
txt.print_ub(@($4001))
txt.nl()
}
thing.routine()
}
}


/** TODO scoping bug
; scoping bug:
main {
thing {
%option no_symbol_prefixing

sub start() {
sub routine() {
other.something()
other.counter++
}
}

other {
sub something() {
}

uword @shared counter
}
**/

0 comments on commit 5b63590

Please sign in to comment.