From 62ceace9410fc6d00cb65dfa9ce7bea3b97313ee Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 25 Mar 2019 23:31:02 +0100 Subject: [PATCH] block names are global (unscoped) --- compiler/src/prog8/ast/AST.kt | 13 ++++++------- .../src/prog8/ast/AstIdentifiersChecker.kt | 8 +++++--- compiler/src/prog8/compiler/Compiler.kt | 4 ++-- .../intermediate/IntermediateProgram.kt | 9 ++++----- .../src/prog8/compiler/target/c64/AsmGen.kt | 19 +++++++++---------- examples/test.p8 | 2 +- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 188488ee6..614b70581 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -325,8 +325,8 @@ inline fun findParentNode(node: Node): T? { interface IStatement : Node { fun process(processor: IAstProcessor) : IStatement - fun makeScopedName(name: String): List { - // this is usually cached in a lazy property on the statement object itself + fun makeScopedName(name: String): String { + // this is usually cached in a lazy property on the statement object itself (label, subroutine, vardecl) val scope = mutableListOf() var statementScope = this.parent while(statementScope !is ParentSentinel && statementScope !is Module) { @@ -336,7 +336,7 @@ interface IStatement : Node { statementScope = statementScope.parent } scope.add(name) - return scope + return scope.joinToString(".") } } @@ -507,7 +507,6 @@ class Block(override val name: String, val isInLibrary: Boolean, override val position: Position) : IStatement, INameScope { override lateinit var parent: Node - val scopedname: String by lazy { makeScopedName(name).joinToString(".") } override fun linkParents(parent: Node) { this.parent = parent @@ -547,7 +546,7 @@ data class DirectiveArg(val str: String?, val name: String?, val int: Int?, over data class Label(val name: String, override val position: Position) : IStatement { override lateinit var parent: Node - val scopedname: String by lazy { makeScopedName(name).joinToString(".") } + val scopedname: String by lazy { makeScopedName(name) } override fun linkParents(parent: Node) { this.parent = parent @@ -685,7 +684,7 @@ class VarDecl(val type: VarDeclType, override fun process(processor: IAstProcessor) = processor.process(this) - val scopedname: String by lazy { makeScopedName(name).joinToString(".") } + val scopedname: String by lazy { makeScopedName(name) } override fun toString(): String { return "VarDecl(name=$name, vartype=$type, datatype=$datatype, value=$value, pos=$position)" @@ -1625,7 +1624,7 @@ class Subroutine(override val name: String, override var statements: MutableList, override val position: Position) : IStatement, INameScope { override lateinit var parent: Node - val scopedname: String by lazy { makeScopedName(name).joinToString(".") } + val scopedname: String by lazy { makeScopedName(name) } override fun linkParents(parent: Node) { this.parent = parent diff --git a/compiler/src/prog8/ast/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/AstIdentifiersChecker.kt index 33adf3e6c..9bbad3400 100644 --- a/compiler/src/prog8/ast/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/AstIdentifiersChecker.kt @@ -62,12 +62,11 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor { } override fun process(block: Block): IStatement { - val scopedName = block.scopedname - val existing = symbols[scopedName] + val existing = symbols[block.name] if(existing!=null) { nameError(block.name, block.position, existing) } else { - symbols[scopedName] = block + symbols[block.name] = block } return super.process(block) } @@ -91,6 +90,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor { // the builtin functions can't be redefined checkResult.add(NameError("builtin function cannot be redefined", decl.position)) + // TODO: check for name conflict only has to be done within the same scope, no need to get the full scoped name val scopedName = decl.scopedname val existing = symbols[scopedName] if(existing!=null) { @@ -109,6 +109,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor { if (subroutine.parameters.any { it.name in BuiltinFunctions }) checkResult.add(NameError("builtin function name cannot be used as parameter", subroutine.position)) + // TODO: check for name conflict only has to be done within the same scope, no need to get the full scoped name val scopedName = subroutine.scopedname val existing = symbols[scopedName] if (existing != null) { @@ -152,6 +153,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor { // the builtin functions can't be redefined checkResult.add(NameError("builtin function cannot be redefined", label.position)) } else { + // TODO: check for name conflict only has to be done within the same scope, no need to get the full scoped name val scopedName = label.scopedname val existing = symbols[scopedName] if (existing != null) { diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index af620a548..23dd827c5 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -157,9 +157,9 @@ internal class Compiler(private val rootModule: Module, } override fun process(block: Block): IStatement { - prog.newBlock(block.scopedname, block.name, block.address, block.options()) + prog.newBlock(block.name, block.address, block.options()) processVariables(block) - prog.label("block."+block.scopedname, false) + prog.label("block."+block.name, false) prog.line(block.position) translate(block.statements) return super.process(block) diff --git a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt index de7255258..77fd5f7a9 100644 --- a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt +++ b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt @@ -11,8 +11,7 @@ import java.nio.file.Path class IntermediateProgram(val name: String, var loadAddress: Int, val heap: HeapValues, val importedFrom: Path) { - class ProgramBlock(val scopedname: String, - val shortname: String, + class ProgramBlock(val name: String, var address: Int?, val instructions: MutableList = mutableListOf(), val variables: MutableMap = mutableMapOf(), @@ -447,8 +446,8 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap currentBlock.memoryPointers[name] = Pair(address, datatype) } - fun newBlock(scopedname: String, shortname: String, address: Int?, options: Set) { - currentBlock = ProgramBlock(scopedname, shortname, address, force_output="force_output" in options) + fun newBlock(name: String, address: Int?, options: Set) { + currentBlock = ProgramBlock(name, address, force_output="force_output" in options) blocks.add(currentBlock) } @@ -472,7 +471,7 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap } out.println("%end_heap") for(blk in blocks) { - out.println("\n%block ${blk.scopedname} ${blk.address?.toString(16) ?: ""}") + out.println("\n%block ${blk.name} ${blk.address?.toString(16) ?: ""}") out.println("%variables") for(variable in blk.variables) { diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index f64cd819b..f344af551 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -44,8 +44,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, }.toMutableList() val newConstants = block.memoryPointers.map { symname(it.key, block) to it.value }.toMap().toMutableMap() val newblock = IntermediateProgram.ProgramBlock( - block.scopedname, - block.shortname, + block.name, block.address, newinstructions, newvars, @@ -115,9 +114,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, blockLocal=true scoped } - scoped.startsWith("${block.shortname}.") -> { + scoped.startsWith("${block.name}.") -> { // TODO DOES THIS EVER OCCUR? blockLocal = true - scoped.substring(block.shortname.length+1) + scoped.substring(block.name.length+1) } scoped.startsWith("block.") -> { blockLocal = false @@ -199,7 +198,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, for(block in program.blocks) { val initVarsLabel = block.instructions.firstOrNull { it is LabelInstr && it.name==initvarsSubName } as? LabelInstr if(initVarsLabel!=null) - out(" jsr ${block.scopedname}.${initVarsLabel.name}") + out(" jsr ${block.name}.${initVarsLabel.name}") } out(" clc") when(zeropage.exitProgramStrategy) { @@ -222,9 +221,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, private fun block2asm(blk: IntermediateProgram.ProgramBlock) { block = blk - out("\n; ---- block: '${block.shortname}' ----") + out("\n; ---- block: '${block.name}' ----") if(!blk.force_output) - out("${block.shortname}\t.proc\n") + out("${block.name}\t.proc\n") if(block.address!=null) { out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'") out("* = ${block.address?.toHex()}") @@ -232,7 +231,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, // deal with zeropage variables for(variable in blk.variables) { - val sym = symname(blk.scopedname+"."+variable.key, null) + val sym = symname(blk.name+"."+variable.key, null) val zpVar = program.allocatedZeropageVariables[sym] if(zpVar==null) { // This var is not on the ZP yet. Attempt to move it there (if it's not a float, those take up too much space) @@ -431,8 +430,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, return "" val labelresult = - if(ins.name.startsWith("${block.shortname}.")) - ins.name.substring(block.shortname.length+1) + if(ins.name.startsWith("${block.name}.")) + ins.name.substring(block.name.length+1) else ins.name return if(ins.asmProc) labelresult+"\t\t.proc" else labelresult diff --git a/examples/test.p8 b/examples/test.p8 index 5a288f94a..fcf8d87dc 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,6 +1,6 @@ %zeropage basicsafe -; @todo fix this (issue #11 on github): it generates invalid asm due to improper label names +; @todo fix this loop labeling problem (issue #11 on github): it generates invalid asm due to improper label names ~ main {