mirror of
https://github.com/irmen/prog8.git
synced 2024-11-23 07:32:10 +00:00
removed need to store ast scope on each zp allocated var, now uses scoped name to find them
This commit is contained in:
parent
a03c4c3659
commit
1d740c7c36
@ -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
|
||||||
|
@ -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") }
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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,
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user