mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
block names are global (unscoped)
This commit is contained in:
parent
7114d3193c
commit
62ceace941
@ -325,8 +325,8 @@ inline fun <reified T> findParentNode(node: Node): T? {
|
||||
|
||||
interface IStatement : Node {
|
||||
fun process(processor: IAstProcessor) : IStatement
|
||||
fun makeScopedName(name: String): List<String> {
|
||||
// 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<String>()
|
||||
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<IStatement>,
|
||||
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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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<Instruction> = mutableListOf(),
|
||||
val variables: MutableMap<String, Value> = 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<String>) {
|
||||
currentBlock = ProgramBlock(scopedname, shortname, address, force_output="force_output" in options)
|
||||
fun newBlock(name: String, address: Int?, options: Set<String>) {
|
||||
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) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user