mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 03:54:27 +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 {
|
interface IStatement : Node {
|
||||||
fun process(processor: IAstProcessor) : IStatement
|
fun process(processor: IAstProcessor) : IStatement
|
||||||
fun makeScopedName(name: String): List<String> {
|
fun makeScopedName(name: String): String {
|
||||||
// this is usually cached in a lazy property on the statement object itself
|
// this is usually cached in a lazy property on the statement object itself (label, subroutine, vardecl)
|
||||||
val scope = mutableListOf<String>()
|
val scope = mutableListOf<String>()
|
||||||
var statementScope = this.parent
|
var statementScope = this.parent
|
||||||
while(statementScope !is ParentSentinel && statementScope !is Module) {
|
while(statementScope !is ParentSentinel && statementScope !is Module) {
|
||||||
@ -336,7 +336,7 @@ interface IStatement : Node {
|
|||||||
statementScope = statementScope.parent
|
statementScope = statementScope.parent
|
||||||
}
|
}
|
||||||
scope.add(name)
|
scope.add(name)
|
||||||
return scope
|
return scope.joinToString(".")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +507,6 @@ class Block(override val name: String,
|
|||||||
val isInLibrary: Boolean,
|
val isInLibrary: Boolean,
|
||||||
override val position: Position) : IStatement, INameScope {
|
override val position: Position) : IStatement, INameScope {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
val scopedname: String by lazy { makeScopedName(name).joinToString(".") }
|
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
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 {
|
data class Label(val name: String, override val position: Position) : IStatement {
|
||||||
override lateinit var parent: Node
|
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) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
@ -685,7 +684,7 @@ class VarDecl(val type: VarDeclType,
|
|||||||
|
|
||||||
override fun process(processor: IAstProcessor) = processor.process(this)
|
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 {
|
override fun toString(): String {
|
||||||
return "VarDecl(name=$name, vartype=$type, datatype=$datatype, value=$value, pos=$position)"
|
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 var statements: MutableList<IStatement>,
|
||||||
override val position: Position) : IStatement, INameScope {
|
override val position: Position) : IStatement, INameScope {
|
||||||
override lateinit var parent: Node
|
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) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
|
@ -62,12 +62,11 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun process(block: Block): IStatement {
|
override fun process(block: Block): IStatement {
|
||||||
val scopedName = block.scopedname
|
val existing = symbols[block.name]
|
||||||
val existing = symbols[scopedName]
|
|
||||||
if(existing!=null) {
|
if(existing!=null) {
|
||||||
nameError(block.name, block.position, existing)
|
nameError(block.name, block.position, existing)
|
||||||
} else {
|
} else {
|
||||||
symbols[scopedName] = block
|
symbols[block.name] = block
|
||||||
}
|
}
|
||||||
return super.process(block)
|
return super.process(block)
|
||||||
}
|
}
|
||||||
@ -91,6 +90,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
|||||||
// the builtin functions can't be redefined
|
// the builtin functions can't be redefined
|
||||||
checkResult.add(NameError("builtin function cannot be redefined", decl.position))
|
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 scopedName = decl.scopedname
|
||||||
val existing = symbols[scopedName]
|
val existing = symbols[scopedName]
|
||||||
if(existing!=null) {
|
if(existing!=null) {
|
||||||
@ -109,6 +109,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
|||||||
if (subroutine.parameters.any { it.name in BuiltinFunctions })
|
if (subroutine.parameters.any { it.name in BuiltinFunctions })
|
||||||
checkResult.add(NameError("builtin function name cannot be used as parameter", subroutine.position))
|
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 scopedName = subroutine.scopedname
|
||||||
val existing = symbols[scopedName]
|
val existing = symbols[scopedName]
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
@ -152,6 +153,7 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
|||||||
// the builtin functions can't be redefined
|
// the builtin functions can't be redefined
|
||||||
checkResult.add(NameError("builtin function cannot be redefined", label.position))
|
checkResult.add(NameError("builtin function cannot be redefined", label.position))
|
||||||
} else {
|
} 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 scopedName = label.scopedname
|
||||||
val existing = symbols[scopedName]
|
val existing = symbols[scopedName]
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
|
@ -157,9 +157,9 @@ internal class Compiler(private val rootModule: Module,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun process(block: Block): IStatement {
|
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)
|
processVariables(block)
|
||||||
prog.label("block."+block.scopedname, false)
|
prog.label("block."+block.name, false)
|
||||||
prog.line(block.position)
|
prog.line(block.position)
|
||||||
translate(block.statements)
|
translate(block.statements)
|
||||||
return super.process(block)
|
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 IntermediateProgram(val name: String, var loadAddress: Int, val heap: HeapValues, val importedFrom: Path) {
|
||||||
|
|
||||||
class ProgramBlock(val scopedname: String,
|
class ProgramBlock(val name: String,
|
||||||
val shortname: String,
|
|
||||||
var address: Int?,
|
var address: Int?,
|
||||||
val instructions: MutableList<Instruction> = mutableListOf(),
|
val instructions: MutableList<Instruction> = mutableListOf(),
|
||||||
val variables: MutableMap<String, Value> = mutableMapOf(),
|
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)
|
currentBlock.memoryPointers[name] = Pair(address, datatype)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newBlock(scopedname: String, shortname: String, address: Int?, options: Set<String>) {
|
fun newBlock(name: String, address: Int?, options: Set<String>) {
|
||||||
currentBlock = ProgramBlock(scopedname, shortname, address, force_output="force_output" in options)
|
currentBlock = ProgramBlock(name, address, force_output="force_output" in options)
|
||||||
blocks.add(currentBlock)
|
blocks.add(currentBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +471,7 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
|||||||
}
|
}
|
||||||
out.println("%end_heap")
|
out.println("%end_heap")
|
||||||
for(blk in blocks) {
|
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")
|
out.println("%variables")
|
||||||
for(variable in blk.variables) {
|
for(variable in blk.variables) {
|
||||||
|
@ -44,8 +44,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
val newConstants = block.memoryPointers.map { symname(it.key, block) to it.value }.toMap().toMutableMap()
|
val newConstants = block.memoryPointers.map { symname(it.key, block) to it.value }.toMap().toMutableMap()
|
||||||
val newblock = IntermediateProgram.ProgramBlock(
|
val newblock = IntermediateProgram.ProgramBlock(
|
||||||
block.scopedname,
|
block.name,
|
||||||
block.shortname,
|
|
||||||
block.address,
|
block.address,
|
||||||
newinstructions,
|
newinstructions,
|
||||||
newvars,
|
newvars,
|
||||||
@ -115,9 +114,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
blockLocal=true
|
blockLocal=true
|
||||||
scoped
|
scoped
|
||||||
}
|
}
|
||||||
scoped.startsWith("${block.shortname}.") -> {
|
scoped.startsWith("${block.name}.") -> { // TODO DOES THIS EVER OCCUR?
|
||||||
blockLocal = true
|
blockLocal = true
|
||||||
scoped.substring(block.shortname.length+1)
|
scoped.substring(block.name.length+1)
|
||||||
}
|
}
|
||||||
scoped.startsWith("block.") -> {
|
scoped.startsWith("block.") -> {
|
||||||
blockLocal = false
|
blockLocal = false
|
||||||
@ -199,7 +198,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
for(block in program.blocks) {
|
for(block in program.blocks) {
|
||||||
val initVarsLabel = block.instructions.firstOrNull { it is LabelInstr && it.name==initvarsSubName } as? LabelInstr
|
val initVarsLabel = block.instructions.firstOrNull { it is LabelInstr && it.name==initvarsSubName } as? LabelInstr
|
||||||
if(initVarsLabel!=null)
|
if(initVarsLabel!=null)
|
||||||
out(" jsr ${block.scopedname}.${initVarsLabel.name}")
|
out(" jsr ${block.name}.${initVarsLabel.name}")
|
||||||
}
|
}
|
||||||
out(" clc")
|
out(" clc")
|
||||||
when(zeropage.exitProgramStrategy) {
|
when(zeropage.exitProgramStrategy) {
|
||||||
@ -222,9 +221,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
|
|
||||||
private fun block2asm(blk: IntermediateProgram.ProgramBlock) {
|
private fun block2asm(blk: IntermediateProgram.ProgramBlock) {
|
||||||
block = blk
|
block = blk
|
||||||
out("\n; ---- block: '${block.shortname}' ----")
|
out("\n; ---- block: '${block.name}' ----")
|
||||||
if(!blk.force_output)
|
if(!blk.force_output)
|
||||||
out("${block.shortname}\t.proc\n")
|
out("${block.name}\t.proc\n")
|
||||||
if(block.address!=null) {
|
if(block.address!=null) {
|
||||||
out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'")
|
out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'")
|
||||||
out("* = ${block.address?.toHex()}")
|
out("* = ${block.address?.toHex()}")
|
||||||
@ -232,7 +231,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
|
|
||||||
// deal with zeropage variables
|
// deal with zeropage variables
|
||||||
for(variable in blk.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]
|
val zpVar = program.allocatedZeropageVariables[sym]
|
||||||
if(zpVar==null) {
|
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)
|
// 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 ""
|
return ""
|
||||||
|
|
||||||
val labelresult =
|
val labelresult =
|
||||||
if(ins.name.startsWith("${block.shortname}."))
|
if(ins.name.startsWith("${block.name}."))
|
||||||
ins.name.substring(block.shortname.length+1)
|
ins.name.substring(block.name.length+1)
|
||||||
else
|
else
|
||||||
ins.name
|
ins.name
|
||||||
return if(ins.asmProc) labelresult+"\t\t.proc" else labelresult
|
return if(ins.asmProc) labelresult+"\t\t.proc" else labelresult
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
%zeropage basicsafe
|
%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 {
|
~ main {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user