mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
tweak how zp varnames are stored
This commit is contained in:
parent
0f0f40bff3
commit
fe51698579
@ -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) {
|
||||
|
@ -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") }
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
|
@ -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]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user