tweak how zp varnames are stored

This commit is contained in:
Irmen de Jong 2022-01-15 17:05:34 +01:00
parent 0f0f40bff3
commit fe51698579
5 changed files with 80 additions and 80 deletions

View File

@ -110,7 +110,7 @@ class AsmGen(private val program: Program,
.filterIsInstance<VarDecl>()
.filter { it.type==VarDeclType.VAR }
.toSet()
.map { it to it.scopedName.joinToString(".") }
.map { it to it.scopedName }
val varsRequiringZp = allVariables.filter { it.first.zeropage==ZeropageWish.REQUIRE_ZEROPAGE }
val varsPreferringZp = allVariables
.filter { it.first.zeropage==ZeropageWish.PREFER_ZEROPAGE }
@ -332,14 +332,14 @@ class AsmGen(private val program: Program,
for(variable in variables) {
if(blockname=="prog8_lib" && variable.name.startsWith("P8ZP_SCRATCH_"))
continue // the "hooks" to the temp vars are not generated as new variables
val fullName = variable.scopedName.joinToString(".")
val zpAlloc = zeropage.allocatedZeropageVariable(fullName)
val scopedName = variable.scopedName
val zpAlloc = zeropage.allocatedZeropageVariable(scopedName)
if (zpAlloc == null) {
// This var is not on the ZP yet. Attempt to move it there if it's an integer type
if(variable.zeropage != ZeropageWish.NOT_IN_ZEROPAGE &&
variable.datatype in IntegerDatatypes
&& options.zeropage != ZeropageType.DONTUSE) {
val result = zeropage.allocate(fullName, variable.datatype, null, null, errors)
val result = zeropage.allocate(scopedName, variable.datatype, null, null, errors)
errors.report()
result.fold(
success = { address -> out("${variable.name} = $address\t; zp ${variable.datatype}") },
@ -483,7 +483,7 @@ class AsmGen(private val program: Program,
val vars = statements.asSequence()
.filterIsInstance<VarDecl>()
.filter {
it.type==VarDeclType.VAR && zeropage.allocatedZeropageVariable(it.scopedName.joinToString("."))==null
it.type==VarDeclType.VAR && zeropage.allocatedZeropageVariable(it.scopedName)==null
}
val encodedstringVars = vars
@ -500,8 +500,7 @@ class AsmGen(private val program: Program,
val blockname = inBlock?.name
vars.filter{ it.datatype != DataType.STR }.sortedBy { it.datatype }.forEach {
val scopedname = it.scopedName.joinToString(".")
if(!isZpVar(scopedname)) {
if(!isZpVar(it.scopedName)) {
if(blockname!="prog8_lib" || !it.name.startsWith("P8ZP_SCRATCH_")) // the "hooks" to the temp vars are not generated as new variables
vardecl2asm(it)
}
@ -689,9 +688,8 @@ class AsmGen(private val program: Program,
}
is VarDecl -> {
val sourceName = asmVariableName(pointervar)
val scopedName = target.scopedName.joinToString(".")
if (isTargetCpu(CpuType.CPU65c02)) {
return if (isZpVar(scopedName)) {
return if (isZpVar(target.scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" lda ($sourceName)")
sourceName
@ -705,7 +703,7 @@ class AsmGen(private val program: Program,
"P8ZP_SCRATCH_W1"
}
} else {
return if (isZpVar(scopedName)) {
return if (isZpVar(target.scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
sourceName
@ -728,9 +726,8 @@ class AsmGen(private val program: Program,
internal fun storeAIntoPointerVar(pointervar: IdentifierReference) {
val sourceName = asmVariableName(pointervar)
val vardecl = pointervar.targetVarDecl(program)!!
val scopedName = vardecl.scopedName.joinToString(".")
if (isTargetCpu(CpuType.CPU65c02)) {
if (isZpVar(scopedName)) {
if (isZpVar(vardecl.scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" sta ($sourceName)")
} else {
@ -742,7 +739,7 @@ class AsmGen(private val program: Program,
sta (P8ZP_SCRATCH_W2)""")
}
} else {
if (isZpVar(scopedName)) {
if (isZpVar(vardecl.scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | sta ($sourceName),y")
} else {
@ -1464,7 +1461,7 @@ $repeatLabel lda $counterVar
val counterVar = makeLabel("counter")
when(dt) {
DataType.UBYTE, DataType.UWORD -> {
val result = zeropage.allocate(counterVar, dt, null, stmt.position, errors)
val result = zeropage.allocate(listOf(counterVar), dt, null, stmt.position, errors)
result.fold(
success = { zpvar -> asmInfo.extraVars.add(Triple(dt, counterVar, zpvar.first)) },
failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally
@ -1726,12 +1723,12 @@ $label nop""")
}
}
internal fun isZpVar(scopedName: String): Boolean =
internal fun isZpVar(scopedName: List<String>): Boolean =
zeropage.allocatedZeropageVariable(scopedName)!=null
internal fun isZpVar(variable: IdentifierReference): Boolean {
val vardecl = variable.targetVarDecl(program)!!
return zeropage.allocatedZeropageVariable(vardecl.scopedName.joinToString("."))!=null
return zeropage.allocatedZeropageVariable(vardecl.scopedName)!=null
}
internal fun jmp(asmLabel: String) {

View File

@ -291,7 +291,7 @@ $loopLabel sty $indexVar
}
if(length>=16) {
// allocate index var on ZP if possible
val result = asmgen.zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
val result = asmgen.zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { zpAddr-> asmgen.out("""$indexVar = $zpAddr ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }
@ -332,7 +332,7 @@ $loopLabel sty $indexVar
}
if(length>=16) {
// allocate index var on ZP if possible
val result = asmgen.zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
val result = asmgen.zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { zpAddr-> asmgen.out("""$indexVar = $zpAddr ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }

View File

@ -40,12 +40,12 @@ class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
removeReservedFromFreePool()
for(reg in 0..15) {
allocatedVariables["cx16.r${reg}"] = ((2+reg*2).toUInt() to 2) to DataType.UWORD // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = ((2+reg*2).toUInt() to 2) to DataType.WORD // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = ((2+reg*2).toUInt() to 1) to DataType.UBYTE // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = ((3+reg*2).toUInt() to 1) to DataType.UBYTE // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = ((2+reg*2).toUInt() to 1) to DataType.BYTE // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = ((3+reg*2).toUInt() to 1) to DataType.BYTE // cx16.r0sH .. cx16.r15sH
allocatedVariables[listOf("cx16", "r${reg}")] = ((2+reg*2).toUInt() to 2) to DataType.UWORD // cx16.r0 .. cx16.r15
allocatedVariables[listOf("cx16", "r${reg}s")] = ((2+reg*2).toUInt() to 2) to DataType.WORD // cx16.r0s .. cx16.r15s
allocatedVariables[listOf("cx16", "r${reg}L")] = ((2+reg*2).toUInt() to 1) to DataType.UBYTE // cx16.r0L .. cx16.r15L
allocatedVariables[listOf("cx16", "r${reg}H")] = ((3+reg*2).toUInt() to 1) to DataType.UBYTE // cx16.r0H .. cx16.r15H
allocatedVariables[listOf("cx16", "r${reg}sL")] = ((2+reg*2).toUInt() to 1) to DataType.BYTE // cx16.r0sL .. cx16.r15sL
allocatedVariables[listOf("cx16", "r${reg}sH")] = ((3+reg*2).toUInt() to 1) to DataType.BYTE // cx16.r0sH .. cx16.r15sH
}
}

View File

@ -95,26 +95,26 @@ class TestC64Zeropage: FunSpec({
test("testNames") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, C64Target))
var result = zp.allocate("", DataType.UBYTE, null, null, errors)
var result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate("varname", DataType.UBYTE, null, null, errors)
result = zp.allocate(listOf("varname"), DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
shouldThrow<IllegalArgumentException> { zp.allocate("varname", DataType.UBYTE, null, null, errors) }
result = zp.allocate("varname2", DataType.UBYTE, null, null, errors)
shouldThrow<IllegalArgumentException> { zp.allocate(listOf("varname"), DataType.UBYTE, null, null, errors) }
result = zp.allocate(listOf("varname2"), DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
}
test("testZpFloatEnable") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target))
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled floats" }
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, C64Target))
result = zp2.allocate("", DataType.FLOAT, null, null, errors)
result = zp2.allocate(emptyList(), DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled ZP use" }
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, C64Target))
zp3.allocate("", DataType.FLOAT, null, null, errors)
zp3.allocate(emptyList(), DataType.FLOAT, null, null, errors)
}
test("testZpModesWithFloats") {
@ -136,7 +136,7 @@ class TestC64Zeropage: FunSpec({
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, C64Target))
println(zp.free)
zp.availableBytes() shouldBe 0
val result = zp.allocate("", DataType.BYTE, null, null, errors)
val result = zp.allocate(emptyList(), DataType.BYTE, null, null, errors)
result.expectError { "expected error due to disabled ZP use" }
}
@ -149,9 +149,9 @@ class TestC64Zeropage: FunSpec({
zp3.availableBytes() shouldBe 125
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target))
zp4.availableBytes() shouldBe 239
zp4.allocate("test", DataType.UBYTE, null, null, errors)
zp4.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 238
zp4.allocate("test2", DataType.UBYTE, null, null, errors)
zp4.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 237
}
@ -182,19 +182,19 @@ class TestC64Zeropage: FunSpec({
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
for (i in 0 until zp.availableBytes()) {
val result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.getOrElse { throw it }
val alloc = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
alloc.getOrElse { throw it }
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result.expectError { "expected allocation error" }
result = zp.allocate("", DataType.UWORD, null, null, errors)
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
result.expectError { "expected allocation error" }
}
@ -203,47 +203,47 @@ class TestC64Zeropage: FunSpec({
zp.availableBytes() shouldBe 239
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate("", DataType.UWORD, null, null, errors)
var result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
val loc = result.getOrElse { throw it } .first
loc shouldBeGreaterThan 3u
loc shouldNotBeIn zp.free
val num = zp.availableBytes() / 2
for(i in 0..num-3) {
zp.allocate("", DataType.UWORD, null, null, errors)
zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
}
zp.availableBytes() shouldBe 5
// can't allocate because no more sequential bytes, only fragmented
result = zp.allocate("", DataType.UWORD, null, null, errors)
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
result.expectError { "should give allocation error" }
for(i in 0..4) {
zp.allocate("", DataType.UBYTE, null, null, errors)
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result.expectError { "should give allocation error" }
}
test("testEfficientAllocation") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, C64Target))
zp.availableBytes() shouldBe 18
zp.allocate("", DataType.WORD, null, null, errors ).getOrElse{throw it}.first shouldBe 0x04u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x06u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x0au
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0x9bu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0x9eu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xa5u
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xb0u
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xbeu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x0eu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x92u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x96u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0xf9u
zp.allocate(emptyList(), DataType.WORD, null, null, errors ).getOrElse{throw it}.first shouldBe 0x04u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x06u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x0au
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0x9bu
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0x9eu
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xa5u
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xb0u
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.first shouldBe 0xbeu
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x0eu
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x92u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0x96u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.first shouldBe 0xf9u
zp.availableBytes() shouldBe 0
}
@ -273,9 +273,9 @@ class TestCx16Zeropage: FunSpec({
zp2.availableBytes() shouldBe 175
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, Cx16Target))
zp3.availableBytes() shouldBe 216
zp3.allocate("test", DataType.UBYTE, null, null, errors)
zp3.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 215
zp3.allocate("test2", DataType.UBYTE, null, null, errors)
zp3.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 214
}
@ -291,12 +291,12 @@ class TestCx16Zeropage: FunSpec({
test("preallocated zp vars") {
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, Cx16Target))
zp1.allocatedZeropageVariable("test") shouldBe null
zp1.allocatedZeropageVariable("cx16.r0") shouldNotBe null
zp1.allocatedZeropageVariable("cx16.r15") shouldNotBe null
zp1.allocatedZeropageVariable("cx16.r0L") shouldNotBe null
zp1.allocatedZeropageVariable("cx16.r15L") shouldNotBe null
zp1.allocatedZeropageVariable("cx16.r0sH") shouldNotBe null
zp1.allocatedZeropageVariable("cx16.r15sH") shouldNotBe null
zp1.allocatedZeropageVariable(listOf("test")) shouldBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r0")) shouldNotBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r15")) shouldNotBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r0L")) shouldNotBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r15L")) shouldNotBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r0sH")) shouldNotBe null
zp1.allocatedZeropageVariable(listOf("cx16", "r15sH")) shouldNotBe null
}
})

View File

@ -17,7 +17,12 @@ abstract class Zeropage(protected val options: CompilationOptions) {
abstract val SCRATCH_W2 : UInt // temp storage 2 for a word $fb+$fc
private val allocations = mutableMapOf<UInt, Pair<String, DataType>>()
// the variables allocated into Zeropage.
// name (scoped) ==> pair of (address and bytesize) and DataType
// TODO switch the pair around
protected val allocatedVariables = mutableMapOf<List<String>, Pair<Pair<UInt, Int>, DataType>>()
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
fun removeReservedFromFreePool() {
@ -36,8 +41,8 @@ abstract class Zeropage(protected val options: CompilationOptions) {
return free.windowed(2).any { it[0] == it[1] - 1u }
}
fun allocate(scopedname: String, datatype: DataType, arraySize: Int?, position: Position?, errors: IErrorReporter): Result<Pair<UInt, Int>, ZeropageAllocationError> {
require(scopedname.isEmpty() || !allocations.values.any { it.first==scopedname } ) {"scopedname can't be allocated twice"}
fun allocate(name: List<String>, datatype: DataType, arraySize: Int?, position: Position?, errors: IErrorReporter): Result<Pair<UInt, Int>, ZeropageAllocationError> {
require(name.isEmpty() || !allocations.values.any { it.first==name } ) {"name can't be allocated twice"}
if(options.zeropage== ZeropageType.DONTUSE)
return Err(ZeropageAllocationError("zero page usage has been disabled"))
@ -50,7 +55,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
if(position!=null)
errors.warn("allocating a large value in zeropage; str/array $memsize bytes", position)
else
errors.warn("$scopedname: allocating a large value in zeropage; str/array $memsize bytes", Position.DUMMY)
errors.warn("$name: allocating a large value in zeropage; str/array $memsize bytes", Position.DUMMY)
memsize
}
DataType.FLOAT -> {
@ -59,7 +64,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
if(position!=null)
errors.warn("allocating a large value in zeropage; float $memsize bytes", position)
else
errors.warn("$scopedname: allocating a large value in zeropage; float $memsize bytes", Position.DUMMY)
errors.warn("$name: allocating a large value in zeropage; float $memsize bytes", Position.DUMMY)
memsize
} else return Err(ZeropageAllocationError("floating point option not enabled"))
}
@ -71,13 +76,13 @@ abstract class Zeropage(protected val options: CompilationOptions) {
if(size==1) {
for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) {
if(oneSeparateByteFree(candidate))
return Ok(Pair(makeAllocation(candidate, 1, datatype, scopedname), 1))
return Ok(Pair(makeAllocation(candidate, 1, datatype, name), 1))
}
return Ok(Pair(makeAllocation(free[0], 1, datatype, scopedname), 1))
return Ok(Pair(makeAllocation(free[0], 1, datatype, name), 1))
}
for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) {
if (sequentialFree(candidate, size))
return Ok(Pair(makeAllocation(candidate, size, datatype, scopedname), size))
return Ok(Pair(makeAllocation(candidate, size, datatype, name), size))
}
}
}
@ -87,11 +92,11 @@ abstract class Zeropage(protected val options: CompilationOptions) {
private fun reserve(range: UIntRange) = free.removeAll(range)
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: String?): UInt {
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>): UInt {
require(size>=0)
free.removeAll(address until address+size.toUInt())
allocations[address] = (name ?: "<unnamed>") to datatype
if(name!=null)
allocations[address] = name to datatype
if(name.isNotEmpty())
allocatedVariables[name] = (address to size) to datatype
return address
}
@ -102,7 +107,5 @@ abstract class Zeropage(protected val options: CompilationOptions) {
return free.containsAll((address until address+size.toUInt()).toList())
}
fun allocatedZeropageVariable(scopedname: String): Pair<Pair<UInt, Int>, DataType>? = allocatedVariables[scopedname]
protected val allocatedVariables = mutableMapOf<String, Pair<Pair<UInt, Int>, DataType>>()
fun allocatedZeropageVariable(name: List<String>): Pair<Pair<UInt, Int>, DataType>? = allocatedVariables[name]
}