removed need to store ast scope on each zp allocated var, now uses scoped name to find them

This commit is contained in:
Irmen de Jong 2022-03-04 22:56:25 +01:00
parent a03c4c3659
commit 1d740c7c36
10 changed files with 66 additions and 70 deletions

View File

@ -758,7 +758,7 @@ $repeatLabel lda $counterVar
val counterVar = makeLabel("counter") val counterVar = makeLabel("counter")
when(dt) { when(dt) {
DataType.UBYTE, DataType.UWORD -> { DataType.UBYTE, DataType.UWORD -> {
val result = zeropage.allocate(listOf(counterVar), dt, scope,null, null, stmt.position, errors) val result = zeropage.allocate(listOf(counterVar), dt, null, null, stmt.position, errors)
result.fold( result.fold(
success = { (address, _) -> asmInfo.extraVars.add(Triple(dt, counterVar, address)) }, success = { (address, _) -> asmInfo.extraVars.add(Triple(dt, counterVar, address)) },
failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally

View File

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

View File

@ -1,6 +1,5 @@
package prog8.codegen.cpu6502 package prog8.codegen.cpu6502
import prog8.ast.INameScope
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.antlr.escape import prog8.ast.antlr.escape
import prog8.ast.base.* import prog8.ast.base.*
@ -383,8 +382,18 @@ internal class ProgramAndVarsGen(
clc""") clc""")
} }
private fun zeropagevars2asm(scope: INameScope) { private fun zeropagevars2asm(block: Block) {
val zpVariables = allocator.zeropageVars.filter { it.value.originalScope==scope } val varnames = variables.blockVars.getOrDefault(block, emptySet()).map { it.scopedname }.toSet()
zeropagevars2asm(varnames)
}
private fun zeropagevars2asm(sub: Subroutine) {
val varnames = variables.subroutineVars.getOrDefault(sub, emptySet()).map { it.scopedname }.toSet()
zeropagevars2asm(varnames)
}
private fun zeropagevars2asm(varNames: Set<List<String>>) {
val zpVariables = allocator.zeropageVars.filter { it.key in varNames }
for ((scopedName, zpvar) in zpVariables) { for ((scopedName, zpvar) in zpVariables) {
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit()) if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped

View File

@ -55,7 +55,6 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
val result = zeropage.allocate( val result = zeropage.allocate(
variable.scopedname, variable.scopedname,
variable.type, variable.type,
variable.scope,
numElements, numElements,
variable.initialValue, variable.initialValue,
variable.position, variable.position,
@ -77,7 +76,6 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
val result = zeropage.allocate( val result = zeropage.allocate(
variable.scopedname, variable.scopedname,
variable.type, variable.type,
variable.scope,
numElements, numElements,
variable.initialValue, variable.initialValue,
variable.position, variable.position,
@ -99,7 +97,6 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
val result = zeropage.allocate( val result = zeropage.allocate(
variable.scopedname, variable.scopedname,
variable.type, variable.type,
variable.scope,
numElements, numElements,
variable.initialValue, variable.initialValue,
variable.position, variable.position,

View File

@ -1,6 +1,5 @@
package prog8.codegen.target.cx16 package prog8.codegen.target.cx16
import prog8.ast.GlobalNamespace
import prog8.ast.base.DataType import prog8.ast.base.DataType
import prog8.compilerinterface.CompilationOptions import prog8.compilerinterface.CompilationOptions
import prog8.compilerinterface.InternalCompilerException import prog8.compilerinterface.InternalCompilerException
@ -43,14 +42,13 @@ class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
// note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses. // note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses.
// however, to be able for the compiler to "see" them as zero page variables, we have to register them here as well. // however, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
val dummyscope = GlobalNamespace(emptyList())
for(reg in 0..15) { for(reg in 0..15) {
allocatedVariables[listOf("cx16", "r${reg}")] = ZpAllocation((2+reg*2).toUInt(), DataType.UWORD, 2, dummyscope, null, null) // cx16.r0 .. cx16.r15 allocatedVariables[listOf("cx16", "r${reg}")] = ZpAllocation((2+reg*2).toUInt(), DataType.UWORD, 2, null, null) // cx16.r0 .. cx16.r15
allocatedVariables[listOf("cx16", "r${reg}s")] = ZpAllocation((2+reg*2).toUInt(), DataType.WORD, 2, dummyscope, null, null) // cx16.r0s .. cx16.r15s allocatedVariables[listOf("cx16", "r${reg}s")] = ZpAllocation((2+reg*2).toUInt(), DataType.WORD, 2, null, null) // cx16.r0s .. cx16.r15s
allocatedVariables[listOf("cx16", "r${reg}L")] = ZpAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1, dummyscope, null, null) // cx16.r0L .. cx16.r15L allocatedVariables[listOf("cx16", "r${reg}L")] = ZpAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1, null, null) // cx16.r0L .. cx16.r15L
allocatedVariables[listOf("cx16", "r${reg}H")] = ZpAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1, dummyscope, null, null) // cx16.r0H .. cx16.r15H allocatedVariables[listOf("cx16", "r${reg}H")] = ZpAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1, null, null) // cx16.r0H .. cx16.r15H
allocatedVariables[listOf("cx16", "r${reg}sL")] = ZpAllocation((2+reg*2).toUInt(), DataType.BYTE, 1, dummyscope, null, null) // cx16.r0sL .. cx16.r15sL allocatedVariables[listOf("cx16", "r${reg}sL")] = ZpAllocation((2+reg*2).toUInt(), DataType.BYTE, 1, null, null) // cx16.r0sL .. cx16.r15sL
allocatedVariables[listOf("cx16", "r${reg}sH")] = ZpAllocation((3+reg*2).toUInt(), DataType.BYTE, 1, dummyscope, null, null) // cx16.r0sH .. cx16.r15sH allocatedVariables[listOf("cx16", "r${reg}sH")] = ZpAllocation((3+reg*2).toUInt(), DataType.BYTE, 1, null, null) // cx16.r0sH .. cx16.r15sH
} }
} }
} }

View File

@ -178,7 +178,7 @@ internal class VariablesAndConsts (
} }
private fun toStatic(decl: VarDecl) = private fun toStatic(decl: VarDecl) =
IVariablesAndConsts.StaticVariable(decl.datatype, decl.scopedName, decl.definingScope, decl.value, decl.arraysize?.constIndex(), decl.zeropage, decl.position) IVariablesAndConsts.StaticVariable(decl.datatype, decl.scopedName, decl.value, decl.arraysize?.constIndex(), decl.zeropage, decl.position)
override fun addIfUnknown(definingBlock: Block, variable: VarDecl) { override fun addIfUnknown(definingBlock: Block, variable: VarDecl) {
var blockvars = bv[definingBlock] var blockvars = bv[definingBlock]

View File

@ -12,7 +12,6 @@ import io.kotest.matchers.collections.shouldNotBeIn
import io.kotest.matchers.comparables.shouldBeGreaterThan import io.kotest.matchers.comparables.shouldBeGreaterThan
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe import io.kotest.matchers.shouldNotBe
import prog8.ast.GlobalNamespace
import prog8.ast.base.DataType import prog8.ast.base.DataType
import prog8.codegen.target.C64Target import prog8.codegen.target.C64Target
import prog8.codegen.target.Cx16Target import prog8.codegen.target.Cx16Target
@ -61,31 +60,30 @@ class TestC64Zeropage: FunSpec({
val errors = ErrorReporterForTests() val errors = ErrorReporterForTests()
val c64target = C64Target() val c64target = C64Target()
val zpdummyscope = GlobalNamespace(emptyList())
test("testNames") { test("testNames") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target))
var result = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) var result = zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
result.onFailure { fail(it.toString()) } result.onFailure { fail(it.toString()) }
result = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) result = zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
result.onFailure { fail(it.toString()) } result.onFailure { fail(it.toString()) }
result = zp.allocate(listOf("varname"), DataType.UBYTE, zpdummyscope, null, null, null, errors) result = zp.allocate(listOf("varname"), DataType.UBYTE, null, null, null, errors)
result.onFailure { fail(it.toString()) } result.onFailure { fail(it.toString()) }
shouldThrow<IllegalArgumentException> { zp.allocate(listOf("varname"), DataType.UBYTE, zpdummyscope,null, null, null, errors) } shouldThrow<IllegalArgumentException> { zp.allocate(listOf("varname"), DataType.UBYTE,null, null, null, errors) }
result = zp.allocate(listOf("varname2"), DataType.UBYTE, zpdummyscope, null, null, null, errors) result = zp.allocate(listOf("varname2"), DataType.UBYTE, null, null, null, errors)
result.onFailure { fail(it.toString()) } result.onFailure { fail(it.toString()) }
} }
test("testZpFloatEnable") { test("testZpFloatEnable") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target))
var result = zp.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, null, errors)
result.expectError { "should be allocation error due to disabled floats" } result.expectError { "should be allocation error due to disabled floats" }
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target)) val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target))
result = zp2.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) result = zp2.allocate(emptyList(), DataType.FLOAT, null, null, null, errors)
result.expectError { "should be allocation error due to disabled ZP use" } result.expectError { "should be allocation error due to disabled ZP use" }
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target)) val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target))
zp3.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) zp3.allocate(emptyList(), DataType.FLOAT, null, null, null, errors)
} }
test("testZpModesWithFloats") { test("testZpModesWithFloats") {
@ -107,7 +105,7 @@ class TestC64Zeropage: FunSpec({
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target)) val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target))
println(zp.free) println(zp.free)
zp.availableBytes() shouldBe 0 zp.availableBytes() shouldBe 0
val result = zp.allocate(emptyList(), DataType.BYTE, zpdummyscope, null, null, null, errors) val result = zp.allocate(emptyList(), DataType.BYTE, null, null, null, errors)
result.expectError { "expected error due to disabled ZP use" } result.expectError { "expected error due to disabled ZP use" }
} }
@ -120,9 +118,9 @@ class TestC64Zeropage: FunSpec({
zp3.availableBytes() shouldBe 125 zp3.availableBytes() shouldBe 125
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target))
zp4.availableBytes() shouldBe 239 zp4.availableBytes() shouldBe 239
zp4.allocate(listOf("test"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp4.allocate(listOf("test"), DataType.UBYTE, null, null, null, errors)
zp4.availableBytes() shouldBe 238 zp4.availableBytes() shouldBe 238
zp4.allocate(listOf("test2"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp4.allocate(listOf("test2"), DataType.UBYTE, null, null, null, errors)
zp4.availableBytes() shouldBe 237 zp4.availableBytes() shouldBe 237
} }
@ -153,19 +151,19 @@ class TestC64Zeropage: FunSpec({
zp.hasByteAvailable() shouldBe true zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true zp.hasWordAvailable() shouldBe true
var result = zp.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, null, errors)
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" } result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
for (i in 0 until zp.availableBytes()) { for (i in 0 until zp.availableBytes()) {
val alloc = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) val alloc = zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
alloc.getOrElse { throw it } alloc.getOrElse { throw it }
} }
zp.availableBytes() shouldBe 0 zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false zp.hasWordAvailable() shouldBe false
result = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) result = zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
result.expectError { "expected allocation error" } result.expectError { "expected allocation error" }
result = zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors) result = zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors)
result.expectError { "expected allocation error" } result.expectError { "expected allocation error" }
} }
@ -174,47 +172,47 @@ class TestC64Zeropage: FunSpec({
zp.availableBytes() shouldBe 239 zp.availableBytes() shouldBe 239
zp.hasByteAvailable() shouldBe true zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true zp.hasWordAvailable() shouldBe true
var result = zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors) var result = zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors)
val loc = result.getOrElse { throw it } .first val loc = result.getOrElse { throw it } .first
loc shouldBeGreaterThan 3u loc shouldBeGreaterThan 3u
loc shouldNotBeIn zp.free loc shouldNotBeIn zp.free
val num = zp.availableBytes() / 2 val num = zp.availableBytes() / 2
for(i in 0..num-3) { for(i in 0..num-3) {
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors) zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors)
} }
zp.availableBytes() shouldBe 5 zp.availableBytes() shouldBe 5
// can't allocate because no more sequential bytes, only fragmented // can't allocate because no more sequential bytes, only fragmented
result = zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors) result = zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors)
result.expectError { "should give allocation error" } result.expectError { "should give allocation error" }
for(i in 0..4) { for(i in 0..4) {
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
} }
zp.availableBytes() shouldBe 0 zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false zp.hasWordAvailable() shouldBe false
result = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) result = zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors)
result.expectError { "should give allocation error" } result.expectError { "should give allocation error" }
} }
test("testEfficientAllocation") { test("testEfficientAllocation") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target))
zp.availableBytes() shouldBe 18 zp.availableBytes() shouldBe 18
zp.allocate(emptyList(), DataType.WORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x04u zp.allocate(emptyList(), DataType.WORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x04u
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x06u zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x06u
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x0au zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x0au
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x9bu zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x9bu
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x9eu zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x9eu
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xa5u zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xa5u
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xb0u zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xb0u
zp.allocate(emptyList(), DataType.UWORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xbeu zp.allocate(emptyList(), DataType.UWORD, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xbeu
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x0eu zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x0eu
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x92u zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x92u
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x96u zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x96u
zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xf9u zp.allocate(emptyList(), DataType.UBYTE, null, null, null, errors).getOrElse{throw it}.first shouldBe 0xf9u
zp.availableBytes() shouldBe 0 zp.availableBytes() shouldBe 0
} }
@ -230,7 +228,6 @@ class TestC64Zeropage: FunSpec({
class TestCx16Zeropage: FunSpec({ class TestCx16Zeropage: FunSpec({
val errors = ErrorReporterForTests() val errors = ErrorReporterForTests()
val cx16target = Cx16Target() val cx16target = Cx16Target()
val zpdummyscope = GlobalNamespace(emptyList())
test("testReservedLocations") { test("testReservedLocations") {
val zp = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, cx16target)) val zp = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, cx16target))
@ -246,9 +243,9 @@ class TestCx16Zeropage: FunSpec({
zp2.availableBytes() shouldBe 175 zp2.availableBytes() shouldBe 175
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target))
zp3.availableBytes() shouldBe 216 zp3.availableBytes() shouldBe 216
zp3.allocate(listOf("test"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp3.allocate(listOf("test"), DataType.UBYTE, null, null, null, errors)
zp3.availableBytes() shouldBe 215 zp3.availableBytes() shouldBe 215
zp3.allocate(listOf("test2"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp3.allocate(listOf("test2"), DataType.UBYTE, null, null, null, errors)
zp3.availableBytes() shouldBe 214 zp3.availableBytes() shouldBe 214
} }

View File

@ -83,13 +83,13 @@ class TestAsmGenSymbols: StringSpec({
init { init {
blockVars = mutableMapOf() blockVars = mutableMapOf()
blockVars[block] = mutableSetOf(IVariablesAndConsts.StaticVariable(varInBlock.datatype, varInBlock.scopedName, varInBlock.definingScope, varInBlock.value, varInBlock.arraysize?.constIndex(), varInBlock.zeropage, varInBlock.position)) blockVars[block] = mutableSetOf(IVariablesAndConsts.StaticVariable(varInBlock.datatype, varInBlock.scopedName, varInBlock.value, varInBlock.arraysize?.constIndex(), varInBlock.zeropage, varInBlock.position))
blockConsts = mutableMapOf() blockConsts = mutableMapOf()
blockMemvars = mutableMapOf() blockMemvars = mutableMapOf()
subroutineVars = mutableMapOf() subroutineVars = mutableMapOf()
subroutineVars[subroutine] = mutableSetOf( subroutineVars[subroutine] = mutableSetOf(
IVariablesAndConsts.StaticVariable(varInSub.datatype, varInSub.scopedName, varInSub.definingScope, varInSub.value, varInSub.arraysize?.constIndex(), varInSub.zeropage, varInSub.position), IVariablesAndConsts.StaticVariable(varInSub.datatype, varInSub.scopedName, varInSub.value, varInSub.arraysize?.constIndex(), varInSub.zeropage, varInSub.position),
IVariablesAndConsts.StaticVariable(var2InSub.datatype, var2InSub.scopedName, var2InSub.definingScope, var2InSub.value, var2InSub.arraysize?.constIndex(), var2InSub.zeropage, var2InSub.position) IVariablesAndConsts.StaticVariable(var2InSub.datatype, var2InSub.scopedName, var2InSub.value, var2InSub.arraysize?.constIndex(), var2InSub.zeropage, var2InSub.position)
) )
subroutineConsts = mutableMapOf() subroutineConsts = mutableMapOf()
subroutineMemvars = mutableMapOf() subroutineMemvars = mutableMapOf()

View File

@ -1,6 +1,5 @@
package prog8.compilerinterface package prog8.compilerinterface
import prog8.ast.INameScope
import prog8.ast.base.DataType import prog8.ast.base.DataType
import prog8.ast.base.Position import prog8.ast.base.Position
import prog8.ast.expressions.Expression import prog8.ast.expressions.Expression
@ -20,7 +19,6 @@ interface IVariablesAndConsts {
data class MemoryMappedVariable(val type: DataType, val scopedname: List<String>, val address: UInt, val position: Position) data class MemoryMappedVariable(val type: DataType, val scopedname: List<String>, val address: UInt, val position: Position)
data class StaticVariable(val type: DataType, data class StaticVariable(val type: DataType,
val scopedname: List<String>, val scopedname: List<String>,
val scope: INameScope,
val initialValue: Expression?, val initialValue: Expression?,
val arraysize: Int?, val arraysize: Int?,
val zp: ZeropageWish, val zp: ZeropageWish,

View File

@ -3,7 +3,6 @@ package prog8.compilerinterface
import com.github.michaelbull.result.Err import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result import com.github.michaelbull.result.Result
import prog8.ast.INameScope
import prog8.ast.base.* import prog8.ast.base.*
import prog8.ast.expressions.ArrayLiteral import prog8.ast.expressions.ArrayLiteral
import prog8.ast.expressions.Expression import prog8.ast.expressions.Expression
@ -23,7 +22,6 @@ abstract class Zeropage(protected val options: CompilationOptions) {
data class ZpAllocation(val address: UInt, data class ZpAllocation(val address: UInt,
val dt: DataType, val dt: DataType,
val size: Int, val size: Int,
val originalScope: INameScope, // TODO try to get rid of this reference
val initialStringValue: StringLiteral?, val initialStringValue: StringLiteral?,
val initialArrayValue: ArrayLiteral?) val initialArrayValue: ArrayLiteral?)
@ -53,7 +51,6 @@ abstract class Zeropage(protected val options: CompilationOptions) {
fun allocate(name: List<String>, fun allocate(name: List<String>,
datatype: DataType, datatype: DataType,
originalScope: INameScope,
numElements: Int?, numElements: Int?,
initValue: Expression?, initValue: Expression?,
position: Position?, position: Position?,
@ -93,13 +90,13 @@ abstract class Zeropage(protected val options: CompilationOptions) {
if(size==1) { if(size==1) {
for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) { for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) {
if(oneSeparateByteFree(candidate)) if(oneSeparateByteFree(candidate))
return Ok(Pair(makeAllocation(candidate, 1, datatype, name, initValue, originalScope), 1)) return Ok(Pair(makeAllocation(candidate, 1, datatype, name, initValue), 1))
} }
return Ok(Pair(makeAllocation(free[0], 1, datatype, name, initValue, originalScope), 1)) return Ok(Pair(makeAllocation(free[0], 1, datatype, name, initValue), 1))
} }
for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) { for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) {
if (sequentialFree(candidate, size)) if (sequentialFree(candidate, size))
return Ok(Pair(makeAllocation(candidate, size, datatype, name, initValue, originalScope), size)) return Ok(Pair(makeAllocation(candidate, size, datatype, name, initValue), size))
} }
} }
} }
@ -109,14 +106,14 @@ abstract class Zeropage(protected val options: CompilationOptions) {
private fun reserve(range: UIntRange) = free.removeAll(range) private fun reserve(range: UIntRange) = free.removeAll(range)
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>, initValue: Expression?, originalScope: INameScope): UInt { private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>, initValue: Expression?): UInt {
require(size>=0) require(size>=0)
free.removeAll(address until address+size.toUInt()) free.removeAll(address until address+size.toUInt())
if(name.isNotEmpty()) { if(name.isNotEmpty()) {
allocatedVariables[name] = when(datatype) { allocatedVariables[name] = when(datatype) {
in NumericDatatypes -> ZpAllocation(address, datatype, size, originalScope, null, null) // numerical variables in zeropage never have an initial value here because they are set in separate initializer assignments in NumericDatatypes -> ZpAllocation(address, datatype, size, null, null) // numerical variables in zeropage never have an initial value here because they are set in separate initializer assignments
DataType.STR -> ZpAllocation(address, datatype, size, originalScope, initValue as? StringLiteral, null) DataType.STR -> ZpAllocation(address, datatype, size, initValue as? StringLiteral, null)
in ArrayDatatypes -> ZpAllocation(address, datatype, size, originalScope, null, initValue as? ArrayLiteral) in ArrayDatatypes -> ZpAllocation(address, datatype, size, null, initValue as? ArrayLiteral)
else -> throw AssemblyError("invalid dt") else -> throw AssemblyError("invalid dt")
} }
} }