mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
make name a var in new ast to allow cheap renames
This commit is contained in:
parent
44fa309d20
commit
6ee270d9d8
@ -44,7 +44,9 @@ class PtNodeGroup : PtNode(Position.DUMMY) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sealed class PtNamedNode(val name: String, position: Position): PtNode(position) {
|
sealed class PtNamedNode(var name: String, position: Position): PtNode(position) {
|
||||||
|
// Note that as an exception, the 'name' is not read-only
|
||||||
|
// but a var. This is to allow for cheap node renames.
|
||||||
val scopedName: String by lazy {
|
val scopedName: String by lazy {
|
||||||
var namedParent: PtNode = this.parent
|
var namedParent: PtNode = this.parent
|
||||||
if(namedParent is PtProgram)
|
if(namedParent is PtProgram)
|
||||||
|
@ -27,6 +27,8 @@ class IRCodeGen(
|
|||||||
flattenLabelNames()
|
flattenLabelNames()
|
||||||
flattenNestedSubroutines()
|
flattenNestedSubroutines()
|
||||||
|
|
||||||
|
// TODO: validateNames(program)
|
||||||
|
|
||||||
val irProg = IRProgram(program.name, IRSymbolTable(symbolTable), options, program.encoding)
|
val irProg = IRProgram(program.name, IRSymbolTable(symbolTable), options, program.encoding)
|
||||||
|
|
||||||
if(options.evalStackBaseAddress!=null)
|
if(options.evalStackBaseAddress!=null)
|
||||||
@ -71,6 +73,25 @@ class IRCodeGen(
|
|||||||
return irProg
|
return irProg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validateNames(node: PtNode) {
|
||||||
|
when(node) {
|
||||||
|
is PtBuiltinFunctionCall -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtFunctionCall -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtIdentifier -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtAsmSub -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtBlock -> require('.' !in node.name) { "block name should not be scoped: ${node.name}"}
|
||||||
|
is PtConstant -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtLabel -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtMemMapped -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtSub -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtVariable -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
is PtProgram -> require('.' !in node.name) { "program name should not be scoped: ${node.name}"}
|
||||||
|
is PtSubroutineParameter -> require('.' in node.name) { "node $node name is not scoped: ${node.name}"}
|
||||||
|
else -> { /* node has no name */ }
|
||||||
|
}
|
||||||
|
node.children.forEach{ validateNames(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun ensureFirstChunkLabels(irProg: IRProgram) {
|
private fun ensureFirstChunkLabels(irProg: IRProgram) {
|
||||||
// make sure that first chunks in Blocks and Subroutines share the name of the block/sub as label.
|
// make sure that first chunks in Blocks and Subroutines share the name of the block/sub as label.
|
||||||
|
|
||||||
@ -169,12 +190,7 @@ class IRCodeGen(
|
|||||||
|
|
||||||
flattenRecurse(program)
|
flattenRecurse(program)
|
||||||
|
|
||||||
renameLabels.forEach { (parent, label) ->
|
renameLabels.forEach { (_, label) -> label.name = label.scopedName }
|
||||||
val renamedLabel = PtLabel(label.scopedName, label.position)
|
|
||||||
val idx = parent.children.indexOf(label)
|
|
||||||
parent.children.removeAt(idx)
|
|
||||||
parent.children.add(idx, renamedLabel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun flattenNestedSubroutines() {
|
private fun flattenNestedSubroutines() {
|
||||||
@ -231,27 +247,8 @@ class IRCodeGen(
|
|||||||
removalsAsmSubs.forEach { (parent, asmsub) -> parent.children.remove(asmsub) }
|
removalsAsmSubs.forEach { (parent, asmsub) -> parent.children.remove(asmsub) }
|
||||||
flattenedSubs.forEach { (block, sub) -> block.add(sub) }
|
flattenedSubs.forEach { (block, sub) -> block.add(sub) }
|
||||||
flattenedAsmSubs.forEach { (block, asmsub) -> block.add(asmsub) }
|
flattenedAsmSubs.forEach { (block, asmsub) -> block.add(asmsub) }
|
||||||
renameSubs.forEach { (parent, sub) ->
|
renameSubs.forEach { (_, sub) -> sub.name = sub.scopedName }
|
||||||
val renamedSub = PtSub(sub.scopedName, sub.parameters, sub.returntype, sub.inline, sub.position)
|
renameAsmSubs.forEach { (_, sub) -> sub.name = sub.scopedName }
|
||||||
sub.children.forEach { renamedSub.add(it) }
|
|
||||||
val subindex = parent.children.indexOf(sub)
|
|
||||||
parent.children[subindex] = renamedSub // keep the order of nodes the same
|
|
||||||
}
|
|
||||||
renameAsmSubs.forEach { (parent, sub) ->
|
|
||||||
val renamedSub = PtAsmSub(sub.scopedName,
|
|
||||||
sub.address,
|
|
||||||
sub.clobbers,
|
|
||||||
sub.parameters,
|
|
||||||
sub.returnTypes,
|
|
||||||
sub.retvalRegisters,
|
|
||||||
sub.inline,
|
|
||||||
sub.position)
|
|
||||||
|
|
||||||
if(sub.children.isNotEmpty())
|
|
||||||
renamedSub.add(sub.children.single())
|
|
||||||
val subindex = parent.children.indexOf(sub)
|
|
||||||
parent.children[subindex] = renamedSub // keep the order of nodes the same
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translateNode(node: PtNode): IRCodeChunks {
|
internal fun translateNode(node: PtNode): IRCodeChunks {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user