block names in asm now prefixed with p8b_ (instead of p8_)

as part of fixing var versus block symbol conflict handling
This commit is contained in:
Irmen de Jong 2023-12-19 22:59:01 +01:00
parent b7279a3d9e
commit 69f6afe420
7 changed files with 47 additions and 30 deletions

View File

@ -64,9 +64,9 @@ class PtProgram(
children.asSequence().filterIsInstance<PtBlock>() children.asSequence().filterIsInstance<PtBlock>()
fun entrypoint(): PtSub? = fun entrypoint(): PtSub? =
allBlocks().firstOrNull { it.name == "main" || it.name=="p8_main" } allBlocks().firstOrNull { it.name == "main" || it.name=="p8b_main" }
?.children ?.children
?.firstOrNull { it is PtSub && (it.name == "start" || it.name=="main.start" || it.name=="p8_start" || it.name=="p8_main.p8_start") } as PtSub? ?.firstOrNull { it is PtSub && (it.name == "start" || it.name=="main.start" || it.name=="p8_start" || it.name=="p8b_main.p8_start") } as PtSub?
} }

View File

@ -33,7 +33,11 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
val functionCallsToPrefix = mutableListOf<Pair<PtNode, Int>>() // parent + index val functionCallsToPrefix = mutableListOf<Pair<PtNode, Int>>() // parent + index
fun prefixNamedNode(node: PtNamedNode) { fun prefixNamedNode(node: PtNamedNode) {
node.name = "p8_${node.name}" when(node) {
is PtBlock -> node.name = "p8b_${node.name}"
else -> node.name = "p8_${node.name}"
// TODO: more special prefixes for the other node types?
}
} }
fun prefixSymbols(node: PtNode) { fun prefixSymbols(node: PtNode) {
@ -116,8 +120,16 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
} }
} }
private fun prefixScopedName(name: String): String {
if('.' !in name) return "p8_$name"
// fully scoped, first part is block
val parts = name.split('.')
val prefixed = listOf("p8b_${parts[0]}") + parts.drop(1).map{"p8_$it"}
return prefixed.joinToString(".")
}
private fun PtVariable.prefix(st: SymbolTable): PtVariable { private fun PtVariable.prefix(st: SymbolTable): PtVariable {
name = name.split('.').map {"p8_$it" }.joinToString(".") name = prefixScopedName(name)
if(value==null) if(value==null)
return this return this
@ -154,7 +166,7 @@ private fun PtJump.prefix(parent: PtNode, st: SymbolTable): PtJump {
} }
private fun PtFunctionCall.prefix(parent: PtNode): PtFunctionCall { private fun PtFunctionCall.prefix(parent: PtNode): PtFunctionCall {
val newName = name.split('.').map {"p8_$it" }.joinToString(".") val newName = prefixScopedName(name)
val call = PtFunctionCall(newName, void, type, position) val call = PtFunctionCall(newName, void, type, position)
call.children.addAll(children) call.children.addAll(children)
call.children.forEach { it.parent = call } call.children.forEach { it.parent = call }
@ -167,7 +179,7 @@ private fun PtIdentifier.prefix(parent: PtNode, st: SymbolTable): PtIdentifier {
if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true) if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true)
return this return this
val newName = name.split('.').map { "p8_$it" }.joinToString(".") val newName = prefixScopedName(name)
val node = PtIdentifier(newName, type, position) val node = PtIdentifier(newName, type, position)
node.parent = parent node.parent = parent
return node return node

View File

@ -34,8 +34,8 @@ internal class ProgramAndVarsGen(
header() header()
val allBlocks = program.allBlocks() val allBlocks = program.allBlocks()
if(allBlocks.first().name != "p8_main" && allBlocks.first().name != "main") if(allBlocks.first().name != "p8b_main" && allBlocks.first().name != "main")
throw AssemblyError("first block should be 'main' or 'p8_main'") throw AssemblyError("first block should be 'main' or 'p8b_main'")
if(errors.noErrors()) { if(errors.noErrors()) {
program.allBlocks().forEach { block2asm(it) } program.allBlocks().forEach { block2asm(it) }
@ -138,24 +138,24 @@ internal class ProgramAndVarsGen(
"cx16" -> { "cx16" -> {
if(options.floats) if(options.floats)
asmgen.out(" lda #4 | sta $01") // to use floats, make sure Basic rom is banked in asmgen.out(" lda #4 | sta $01") // to use floats, make sure Basic rom is banked in
asmgen.out(" jsr p8_main.p8_start") asmgen.out(" jsr p8b_main.p8_start")
asmgen.out(" jmp sys.cleanup_at_exit") asmgen.out(" jmp sys.cleanup_at_exit")
} }
"c64" -> { "c64" -> {
asmgen.out(" jsr p8_main.p8_start | lda #31 | sta $01") asmgen.out(" jsr p8b_main.p8_start | lda #31 | sta $01")
if(!options.noSysInit) if(!options.noSysInit)
asmgen.out(" jmp sys.cleanup_at_exit") asmgen.out(" jmp sys.cleanup_at_exit")
else else
asmgen.out(" rts") asmgen.out(" rts")
} }
"c128" -> { "c128" -> {
asmgen.out(" jsr p8_main.p8_start | lda #0 | sta ${"$"}ff00") asmgen.out(" jsr p8b_main.p8_start | lda #0 | sta ${"$"}ff00")
if(!options.noSysInit) if(!options.noSysInit)
asmgen.out(" jmp sys.cleanup_at_exit") asmgen.out(" jmp sys.cleanup_at_exit")
else else
asmgen.out(" rts") asmgen.out(" rts")
} }
else -> asmgen.jmp("p8_main.p8_start") else -> asmgen.jmp("p8b_main.p8_start")
} }
} }
@ -331,7 +331,7 @@ internal class ProgramAndVarsGen(
asmsubs2asm(sub.children) asmsubs2asm(sub.children)
// the main.start subroutine is the program's entrypoint and should perform some initialization logic // the main.start subroutine is the program's entrypoint and should perform some initialization logic
if((sub.name=="start" || sub.name=="p8_start") && (sub.definingBlock()!!.name=="main" || sub.definingBlock()!!.name=="p8_main")) if((sub.name=="start" || sub.name=="p8_start") && (sub.definingBlock()!!.name=="main" || sub.definingBlock()!!.name=="p8b_main"))
entrypointInitialization() entrypointInitialization()
if(functioncallAsmGen.optimizeIntArgsViaRegisters(sub)) { if(functioncallAsmGen.optimizeIntArgsViaRegisters(sub)) {

View File

@ -163,7 +163,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
return allIdentifiersAndTargets.filter { decl===it.value }.map{ it.key } return allIdentifiersAndTargets.filter { decl===it.value }.map{ it.key }
} }
private fun nameInAssemblyCode(name: String) = allAssemblyNodes.any { "p8_$name" in it.names || name in it.names } private fun nameInAssemblyCode(name: String) = allAssemblyNodes.any { "p8_$name" in it.names || "p8b_$name" in it.names || name in it.names }
inline fun unused(label: Label) = false // just always output labels inline fun unused(label: Label) = false // just always output labels

View File

@ -30,12 +30,18 @@ so that more system ram is available for the program code itself.
Symbol prefixing in generated Assembly code Symbol prefixing in generated Assembly code
------------------------------------------- -------------------------------------------
*All* symbols in the prog8 program will be prefixed with ``p8_`` in the generated assembly code. *All* symbols in the prog8 program will be prefixed in the generated assembly code:
Block names
will be prefixed with ``p8b_``
All other names
will be prefixed with ``p8_``
This is to avoid naming conflicts with CPU registers, assembly instructions, etc. This is to avoid naming conflicts with CPU registers, assembly instructions, etc.
So if you're referencing symbols from the prog8 program in inlined assembly code, you have to take So if you're referencing symbols from the prog8 program in inlined assembly code, you have to take
this into account. Stick a ``p8_`` in front of everything that you want to reference that is coming this into account. Stick a ``p8_`` in front of everything (``p8b_`` for block names) that you want to reference that is coming
from a prog8 source file. from a prog8 source file.
All elements in scoped names such as ``main.routine.var1`` are prefixed so this becomes ``p8_main.p8_routine.p8_var1``. All elements in scoped names such as ``main.routine.var1`` are prefixed so this becomes ``p8b_main.p8_routine.p8_var1``.
.. attention:: .. attention::
Symbols from library modules are *not* prefixed and can be used Symbols from library modules are *not* prefixed and can be used

View File

@ -41,12 +41,12 @@ mcf {
%asm {{ %asm {{
lda cx16.r0 lda cx16.r0
ldy cx16.r0+1 ldy cx16.r0+1
sta p8_mcf.p8_stream.getbuffer_call+1 sta p8b_mcf.p8_stream.getbuffer_call+1
sty p8_mcf.p8_stream.getbuffer_call+2 sty p8b_mcf.p8_stream.getbuffer_call+2
lda cx16.r1 lda cx16.r1
ldy cx16.r1+1 ldy cx16.r1+1
sta p8_mcf.p8_stream.processchunk_call+1 sta p8b_mcf.p8_stream.processchunk_call+1
sty p8_mcf.p8_stream.processchunk_call+2 sty p8b_mcf.p8_stream.processchunk_call+2
rts rts
}} }}
} }
@ -113,7 +113,7 @@ mcf {
; custom chunk ; custom chunk
uword @shared chunksize = peekw(loadlist_ptr+1) uword @shared chunksize = peekw(loadlist_ptr+1)
%asm {{ %asm {{
lda (p8_mcf.p8_loadlist_ptr) lda (p8b_mcf.p8_loadlist_ptr)
ldx p8_chunksize ldx p8_chunksize
ldy p8_chunksize+1 ldy p8_chunksize+1
getbuffer_call jsr $ffff ; modified getbuffer_call jsr $ffff ; modified

View File

@ -3,13 +3,12 @@
main { main {
sub start() { sub start() {
ubyte bank = cx16.search_x16edit() uword module ; TODO shadow warning
txt.print_ub(bank) module++
if bank<255 { module.test++ ; TODO compiler error
cx16.rombank(bank)
cx16.x16edit_default()
cx16.rombank(0)
}
txt.print("back from editor!\n")
} }
} }
module {
ubyte @shared test
}