From 69f6afe420b70d3e5dde5f8fd64954c782aa1f37 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 19 Dec 2023 22:59:01 +0100 Subject: [PATCH] block names in asm now prefixed with p8b_ (instead of p8_) as part of fixing var versus block symbol conflict handling --- codeCore/src/prog8/code/ast/AstBase.kt | 4 ++-- .../src/prog8/codegen/cpu6502/AsmGen.kt | 20 +++++++++++++++---- .../codegen/cpu6502/ProgramAndVarsGen.kt | 14 ++++++------- compilerAst/src/prog8/compiler/CallGraph.kt | 2 +- docs/source/technical.rst | 12 ++++++++--- examples/cx16/chunkedfile/mcf.p8 | 10 +++++----- examples/test.p8 | 15 +++++++------- 7 files changed, 47 insertions(+), 30 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstBase.kt b/codeCore/src/prog8/code/ast/AstBase.kt index 91245efca..fc6a73b56 100644 --- a/codeCore/src/prog8/code/ast/AstBase.kt +++ b/codeCore/src/prog8/code/ast/AstBase.kt @@ -64,9 +64,9 @@ class PtProgram( children.asSequence().filterIsInstance() fun entrypoint(): PtSub? = - allBlocks().firstOrNull { it.name == "main" || it.name=="p8_main" } + allBlocks().firstOrNull { it.name == "main" || it.name=="p8b_main" } ?.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? } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 4d7172a50..8d4cff808 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -33,7 +33,11 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend { val functionCallsToPrefix = mutableListOf>() // parent + index 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) { @@ -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 { - name = name.split('.').map {"p8_$it" }.joinToString(".") + name = prefixScopedName(name) if(value==null) return this @@ -154,7 +166,7 @@ private fun PtJump.prefix(parent: PtNode, st: SymbolTable): PtJump { } 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) call.children.addAll(children) 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) return this - val newName = name.split('.').map { "p8_$it" }.joinToString(".") + val newName = prefixScopedName(name) val node = PtIdentifier(newName, type, position) node.parent = parent return node diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index c1c323cf1..f33ceb785 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -34,8 +34,8 @@ internal class ProgramAndVarsGen( header() val allBlocks = program.allBlocks() - if(allBlocks.first().name != "p8_main" && allBlocks.first().name != "main") - throw AssemblyError("first block should be 'main' or 'p8_main'") + if(allBlocks.first().name != "p8b_main" && allBlocks.first().name != "main") + throw AssemblyError("first block should be 'main' or 'p8b_main'") if(errors.noErrors()) { program.allBlocks().forEach { block2asm(it) } @@ -138,24 +138,24 @@ internal class ProgramAndVarsGen( "cx16" -> { if(options.floats) 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") } "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) asmgen.out(" jmp sys.cleanup_at_exit") else asmgen.out(" rts") } "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) asmgen.out(" jmp sys.cleanup_at_exit") else 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) // 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() if(functioncallAsmGen.optimizeIntArgsViaRegisters(sub)) { diff --git a/compilerAst/src/prog8/compiler/CallGraph.kt b/compilerAst/src/prog8/compiler/CallGraph.kt index fe8446792..62780b81f 100644 --- a/compilerAst/src/prog8/compiler/CallGraph.kt +++ b/compilerAst/src/prog8/compiler/CallGraph.kt @@ -163,7 +163,7 @@ class CallGraph(private val program: Program) : IAstVisitor { 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 diff --git a/docs/source/technical.rst b/docs/source/technical.rst index 6ddaad112..da5cc5ff9 100644 --- a/docs/source/technical.rst +++ b/docs/source/technical.rst @@ -30,12 +30,18 @@ so that more system ram is available for the program code itself. 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. 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. -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:: Symbols from library modules are *not* prefixed and can be used diff --git a/examples/cx16/chunkedfile/mcf.p8 b/examples/cx16/chunkedfile/mcf.p8 index 8bbfcf83b..179485562 100644 --- a/examples/cx16/chunkedfile/mcf.p8 +++ b/examples/cx16/chunkedfile/mcf.p8 @@ -41,12 +41,12 @@ mcf { %asm {{ lda cx16.r0 ldy cx16.r0+1 - sta p8_mcf.p8_stream.getbuffer_call+1 - sty p8_mcf.p8_stream.getbuffer_call+2 + sta p8b_mcf.p8_stream.getbuffer_call+1 + sty p8b_mcf.p8_stream.getbuffer_call+2 lda cx16.r1 ldy cx16.r1+1 - sta p8_mcf.p8_stream.processchunk_call+1 - sty p8_mcf.p8_stream.processchunk_call+2 + sta p8b_mcf.p8_stream.processchunk_call+1 + sty p8b_mcf.p8_stream.processchunk_call+2 rts }} } @@ -113,7 +113,7 @@ mcf { ; custom chunk uword @shared chunksize = peekw(loadlist_ptr+1) %asm {{ - lda (p8_mcf.p8_loadlist_ptr) + lda (p8b_mcf.p8_loadlist_ptr) ldx p8_chunksize ldy p8_chunksize+1 getbuffer_call jsr $ffff ; modified diff --git a/examples/test.p8 b/examples/test.p8 index fd72b6abe..dbb590d7e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,13 +3,12 @@ main { sub start() { - ubyte bank = cx16.search_x16edit() - txt.print_ub(bank) - if bank<255 { - cx16.rombank(bank) - cx16.x16edit_default() - cx16.rombank(0) - } - txt.print("back from editor!\n") + uword module ; TODO shadow warning + module++ + module.test++ ; TODO compiler error } } + +module { + ubyte @shared test +}