mirror of
https://github.com/irmen/prog8.git
synced 2024-07-19 04:28:56 +00:00
introducing IVariableAllocation (WIP)
This commit is contained in:
parent
6bdd81623f
commit
d2309b8114
@ -10,7 +10,6 @@ import prog8.ast.statements.*
|
|||||||
import prog8.codegen.cpu6502.assignment.*
|
import prog8.codegen.cpu6502.assignment.*
|
||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import java.nio.file.Path
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -330,7 +329,7 @@ class AsmGen6502(internal val program: Program,
|
|||||||
if(blockname=="prog8_lib" && variable.name.startsWith("P8ZP_SCRATCH_"))
|
if(blockname=="prog8_lib" && variable.name.startsWith("P8ZP_SCRATCH_"))
|
||||||
continue // the "hooks" to the temp vars are not generated as new variables
|
continue // the "hooks" to the temp vars are not generated as new variables
|
||||||
val scopedName = variable.scopedName
|
val scopedName = variable.scopedName
|
||||||
val zpAlloc = zeropage.allocatedZeropageVariable(scopedName)
|
val zpAlloc = zeropage.variables[scopedName]
|
||||||
if (zpAlloc == null) {
|
if (zpAlloc == null) {
|
||||||
// This var is not on the ZP yet. Attempt to move it there if it's an integer type
|
// 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 &&
|
if(variable.zeropage != ZeropageWish.NOT_IN_ZEROPAGE &&
|
||||||
@ -482,7 +481,7 @@ class AsmGen6502(internal val program: Program,
|
|||||||
.filter {
|
.filter {
|
||||||
it.type==VarDeclType.VAR
|
it.type==VarDeclType.VAR
|
||||||
&& it.zeropage!=ZeropageWish.REQUIRE_ZEROPAGE
|
&& it.zeropage!=ZeropageWish.REQUIRE_ZEROPAGE
|
||||||
&& zeropage.allocatedZeropageVariable(it.scopedName)==null
|
&& it.scopedName !in zeropage.variables
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.filter { it.datatype == DataType.STR && shouldActuallyOutputStringVar(it) }
|
vars.filter { it.datatype == DataType.STR && shouldActuallyOutputStringVar(it) }
|
||||||
@ -1742,12 +1741,11 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isZpVar(scopedName: List<String>): Boolean =
|
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.variables
|
||||||
zeropage.allocatedZeropageVariable(scopedName)!=null
|
|
||||||
|
|
||||||
internal fun isZpVar(variable: IdentifierReference): Boolean {
|
internal fun isZpVar(variable: IdentifierReference): Boolean {
|
||||||
val vardecl = variable.targetVarDecl(program)!!
|
val vardecl = variable.targetVarDecl(program)!!
|
||||||
return zeropage.allocatedZeropageVariable(vardecl.scopedName)!=null
|
return vardecl.scopedName in zeropage.variables
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
|
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
|
||||||
|
@ -343,13 +343,14 @@ private fun writeAssembly(program: Program,
|
|||||||
compilerOptions: CompilationOptions
|
compilerOptions: CompilationOptions
|
||||||
): WriteAssemblyResult {
|
): WriteAssemblyResult {
|
||||||
// asm generation directly from the Ast
|
// asm generation directly from the Ast
|
||||||
|
compilerOptions.compTarget.machine.initializeZeropage(compilerOptions)
|
||||||
program.processAstBeforeAsmGeneration(compilerOptions, errors)
|
program.processAstBeforeAsmGeneration(compilerOptions, errors)
|
||||||
errors.report()
|
errors.report()
|
||||||
|
// TODO do something with the VariableAllocation, pass it to the asmgenerator
|
||||||
|
|
||||||
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
|
|
||||||
compilerOptions.compTarget.machine.initializeZeropage(compilerOptions)
|
|
||||||
val assembly = asmGeneratorFor(program, errors, compilerOptions).compileToAssembly()
|
val assembly = asmGeneratorFor(program, errors, compilerOptions).compileToAssembly()
|
||||||
errors.report()
|
errors.report()
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package prog8.compiler.astprocessing
|
package prog8.compiler.astprocessing
|
||||||
|
|
||||||
import prog8.ast.IFunctionCall
|
import prog8.ast.*
|
||||||
import prog8.ast.IStatementContainer
|
|
||||||
import prog8.ast.Node
|
|
||||||
import prog8.ast.Program
|
|
||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
@ -18,14 +15,22 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
|||||||
) : AstWalker() {
|
) : AstWalker() {
|
||||||
|
|
||||||
private val allBlockVars = mutableMapOf<Block, MutableSet<VarDecl>>()
|
private val allBlockVars = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||||
|
private val allBlockConsts = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||||
|
private val allBlockMemoryvars = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||||
private val allSubroutineVars = mutableMapOf<Subroutine, MutableSet<VarDecl>>()
|
private val allSubroutineVars = mutableMapOf<Subroutine, MutableSet<VarDecl>>()
|
||||||
// internal lateinit var allocation: IVariableAllocation
|
private val allSubroutineConsts = mutableMapOf<Subroutine, MutableSet<VarDecl>>()
|
||||||
//
|
private val allSubroutineMemoryvars = mutableMapOf<Subroutine, MutableSet<VarDecl>>()
|
||||||
// override fun after(program: Program): Iterable<IAstModification> {
|
internal lateinit var allocation: IVariableAllocation
|
||||||
// allocation = VariableAllocation(allBlockVars, allSubroutineVars)
|
|
||||||
// allocation.dump(program.memsizer)
|
/* TODO complete the use of VariableAllocation and get rid of it from the AsmGen (and that should no longer use vardecl either):
|
||||||
// return super.after(program)
|
override fun after(program: Program): Iterable<IAstModification> {
|
||||||
// }
|
allocation = VariableAllocation(options,
|
||||||
|
allBlockVars, allBlockConsts, allBlockMemoryvars,
|
||||||
|
allSubroutineVars, allSubroutineConsts, allSubroutineMemoryvars)
|
||||||
|
allocation.dump(program.memsizer)
|
||||||
|
return super.after(program)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
||||||
throw FatalAstException("break should have been replaced by goto $breakStmt")
|
throw FatalAstException("break should have been replaced by goto $breakStmt")
|
||||||
@ -66,24 +71,66 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
|||||||
throw FatalAstException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
throw FatalAstException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decl.type==VarDeclType.VAR) {
|
val scope=decl.definingScope
|
||||||
when(val scope=decl.definingScope) {
|
when (decl.type) {
|
||||||
is Block -> {
|
VarDeclType.VAR -> {
|
||||||
val blockVars = allBlockVars[scope] ?: mutableSetOf()
|
when(scope) {
|
||||||
blockVars.add(decl)
|
is Block -> {
|
||||||
allBlockVars[scope] = blockVars
|
val decls = allBlockVars[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allBlockVars[scope] = decls
|
||||||
|
}
|
||||||
|
is Subroutine -> {
|
||||||
|
val decls = allSubroutineVars[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allSubroutineVars[scope] = decls
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw FatalAstException("var can only occur in subroutine or block scope")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is Subroutine -> {
|
}
|
||||||
val subroutineVars = allSubroutineVars[scope] ?: mutableSetOf()
|
VarDeclType.CONST -> {
|
||||||
subroutineVars.add(decl)
|
when(scope) {
|
||||||
allSubroutineVars[scope] = subroutineVars
|
is Block -> {
|
||||||
|
val decls = allBlockConsts[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allBlockConsts[scope] = decls
|
||||||
|
}
|
||||||
|
is Subroutine -> {
|
||||||
|
val decls = allSubroutineConsts[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allSubroutineConsts[scope] = decls
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw FatalAstException("var can only occur in subroutine or block scope")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
}
|
||||||
throw FatalAstException("var can only occur in subroutine or block scope")
|
VarDeclType.MEMORY -> {
|
||||||
|
when(scope) {
|
||||||
|
is Block -> {
|
||||||
|
val decls = allBlockMemoryvars[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allBlockMemoryvars[scope] = decls
|
||||||
|
}
|
||||||
|
is Subroutine -> {
|
||||||
|
val decls = allSubroutineMemoryvars[scope] ?: mutableSetOf()
|
||||||
|
decls.add(decl)
|
||||||
|
allSubroutineMemoryvars[scope] = decls
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw FatalAstException("var can only occur in subroutine or block scope")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else -> {
|
||||||
|
throw FatalAstException("invalid var type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO get rid of the vardecl inside the ast - codegen should depend on the IVariableAllocation object
|
||||||
|
// return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,25 +446,154 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal class VariableAllocation(
|
internal class VariableAllocation (
|
||||||
override val blockVars: Map<Block, Set<VarDecl>>,
|
options: CompilationOptions,
|
||||||
override val subroutineVars: Map<Subroutine, Set<VarDecl>>) : IVariableAllocation
|
astBlockVars: Map<Block, Set<VarDecl>>,
|
||||||
|
astBlockConsts: Map<Block, Set<VarDecl>>,
|
||||||
|
astBlockMemvars: Map<Block, Set<VarDecl>>,
|
||||||
|
astSubroutineVars: Map<Subroutine, Set<VarDecl>>,
|
||||||
|
astSubroutineConsts: Map<Subroutine, Set<VarDecl>>,
|
||||||
|
astSubroutineMemvars: Map<Subroutine, Set<VarDecl>>
|
||||||
|
) : IVariableAllocation
|
||||||
{
|
{
|
||||||
|
override val zeropageVars: Set<IVariableAllocation.ZeropageVariable>
|
||||||
|
override val blockVars: Map<Block, Set<IVariableAllocation.StaticBlockVariable>>
|
||||||
|
override val blockConsts: Map<Block, Set<IVariableAllocation.ConstantNumberSymbol>>
|
||||||
|
override val blockMemvars: Map<Block, Set<IVariableAllocation.MemoryMappedSymbol>>
|
||||||
|
override val subroutineVars: Map<Subroutine, Set<IVariableAllocation.StaticSubroutineVariable>>
|
||||||
|
override val subroutineConsts: Map<Subroutine, Set<IVariableAllocation.ConstantNumberSymbol>>
|
||||||
|
override val subroutineMemvars: Map<Subroutine, Set<IVariableAllocation.MemoryMappedSymbol>>
|
||||||
|
|
||||||
|
init {
|
||||||
|
if(options.zeropage!=ZeropageType.DONTUSE)
|
||||||
|
allocateVarsInZeropage(options.compTarget.machine.zeropage)
|
||||||
|
|
||||||
|
val zpv = mutableSetOf<IVariableAllocation.ZeropageVariable>()
|
||||||
|
val bv = astBlockVars.keys.associateWith { mutableSetOf<IVariableAllocation.StaticBlockVariable>() }
|
||||||
|
val bc = astBlockConsts.keys.associateWith { mutableSetOf<IVariableAllocation.ConstantNumberSymbol>() }
|
||||||
|
val bmv = astBlockMemvars.keys.associateWith { mutableSetOf<IVariableAllocation.MemoryMappedSymbol>() }
|
||||||
|
val sv = astSubroutineVars.keys.associateWith { mutableSetOf<IVariableAllocation.StaticSubroutineVariable>() }
|
||||||
|
val sc = astSubroutineConsts.keys.associateWith { mutableSetOf<IVariableAllocation.ConstantNumberSymbol>() }
|
||||||
|
val smv = astSubroutineMemvars.keys.associateWith { mutableSetOf<IVariableAllocation.MemoryMappedSymbol>() }
|
||||||
|
astBlockVars.forEach { (block, decls) ->
|
||||||
|
val vars = bv.getValue(block)
|
||||||
|
vars.addAll(decls.map {
|
||||||
|
// TODO make sure the zp-allocated variables are not added here
|
||||||
|
IVariableAllocation.StaticBlockVariable(it.datatype, it.name, it.value, it.position, it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
astBlockConsts.forEach { (block, decls) ->
|
||||||
|
bc.getValue(block).addAll(
|
||||||
|
decls.map {
|
||||||
|
IVariableAllocation.ConstantNumberSymbol(
|
||||||
|
it.datatype,
|
||||||
|
it.name,
|
||||||
|
(it.value as NumericLiteralValue).number,
|
||||||
|
it.position
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
astBlockMemvars.forEach { (block, decls) ->
|
||||||
|
bmv.getValue(block).addAll(
|
||||||
|
decls.map {
|
||||||
|
IVariableAllocation.MemoryMappedSymbol(
|
||||||
|
it.datatype,
|
||||||
|
it.name,
|
||||||
|
(it.value as NumericLiteralValue).number.toUInt(),
|
||||||
|
it.position
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
astSubroutineVars.forEach { (sub, decls) ->
|
||||||
|
val vars = sv.getValue(sub)
|
||||||
|
vars.addAll(decls.map {
|
||||||
|
// TODO make sure the zp-allocated variables are not added here
|
||||||
|
IVariableAllocation.StaticSubroutineVariable(it.datatype, it.name, it.position, it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
astSubroutineConsts.forEach { (sub, decls) ->
|
||||||
|
sc.getValue(sub).addAll(
|
||||||
|
decls.map {
|
||||||
|
IVariableAllocation.ConstantNumberSymbol(
|
||||||
|
it.datatype,
|
||||||
|
it.name,
|
||||||
|
(it.value as NumericLiteralValue).number,
|
||||||
|
it.position
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
astSubroutineMemvars.forEach { (sub, decls) ->
|
||||||
|
smv.getValue(sub).addAll(
|
||||||
|
decls.map {
|
||||||
|
IVariableAllocation.MemoryMappedSymbol(
|
||||||
|
it.datatype,
|
||||||
|
it.name,
|
||||||
|
(it.value as NumericLiteralValue).number.toUInt(),
|
||||||
|
it.position
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
zeropageVars = zpv
|
||||||
|
blockVars = bv
|
||||||
|
blockConsts = bc
|
||||||
|
blockMemvars = bmv
|
||||||
|
subroutineVars = sv
|
||||||
|
subroutineConsts = sc
|
||||||
|
subroutineMemvars = smv
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun allocateVarsInZeropage(zeropage: Zeropage) {
|
||||||
|
println("TODO: allocate vars on zeropage") // TODO
|
||||||
|
}
|
||||||
|
|
||||||
override fun dump(memsizer: IMemSizer) {
|
override fun dump(memsizer: IMemSizer) {
|
||||||
println("ALL BLOCK VARS:")
|
println("\nALL ZEROPAGE VARS:")
|
||||||
|
zeropageVars.forEach {
|
||||||
|
println(" ${it.type} ${it.scopedname} ${it.position}")
|
||||||
|
}
|
||||||
|
println("\nALL BLOCK VARS:")
|
||||||
blockVars.forEach { (block, vars) ->
|
blockVars.forEach { (block, vars) ->
|
||||||
val totalsize = vars.sumOf { memsizer.memorySize(it) }
|
val totalsize = vars.sumOf { memsizer.memorySize(it.origVar) }
|
||||||
println("BLOCK: ${block.name} total size: $totalsize")
|
println("BLOCK: ${block.name} total size: $totalsize")
|
||||||
vars.forEach {
|
vars.forEach {
|
||||||
println(" ${it.datatype} ${it.name} ${it.position}")
|
println(" ${it.type} ${it.name} = ${it.initialValue} ${it.position}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println("ALL SUBROUTINE VARS:")
|
println("\nALL BLOCK CONSTS:")
|
||||||
|
blockConsts.forEach { (block, vars) ->
|
||||||
|
println("BLOCK: ${block.name}")
|
||||||
|
vars.forEach {
|
||||||
|
println(" ${it.type} ${it.name} = ${it.value} ${it.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("\nALL BLOCK MEMORYVARS:")
|
||||||
|
blockMemvars.forEach { (block, vars) ->
|
||||||
|
println("BLOCK: ${block.name}")
|
||||||
|
vars.forEach {
|
||||||
|
println(" ${it.type} ${it.name} = ${it.address.toHex()} ${it.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("\nALL SUBROUTINE VARS:")
|
||||||
subroutineVars.forEach { (sub, vars) ->
|
subroutineVars.forEach { (sub, vars) ->
|
||||||
val totalsize = vars.sumOf { memsizer.memorySize(it) }
|
val totalsize = vars.sumOf { memsizer.memorySize(it.origVar) }
|
||||||
println("SUBROUTINE: ${sub.name} total size: $totalsize")
|
println("SUBROUTINE: ${sub.name} total size: $totalsize")
|
||||||
vars.forEach {
|
vars.forEach {
|
||||||
println(" ${it.datatype} ${it.name} ${it.position}")
|
println(" ${it.type} ${it.name} ${it.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("\nALL SUBROUTINE CONSTS:")
|
||||||
|
subroutineConsts.forEach { (sub, vars) ->
|
||||||
|
println("SUBROUTINE: ${sub.name}")
|
||||||
|
vars.forEach {
|
||||||
|
println(" ${it.type} ${it.name} = ${it.value} ${it.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("\nALL SUBROUTINE MEMORYVARS:")
|
||||||
|
subroutineMemvars.forEach { (sub, vars) ->
|
||||||
|
println("SUBROUTINE: ${sub.name}")
|
||||||
|
vars.forEach {
|
||||||
|
println(" ${it.type} ${it.name} = ${it.address.toHex()} ${it.position}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,12 +259,12 @@ class TestCx16Zeropage: FunSpec({
|
|||||||
|
|
||||||
test("preallocated zp vars") {
|
test("preallocated zp vars") {
|
||||||
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, Cx16Target))
|
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, Cx16Target))
|
||||||
zp1.allocatedZeropageVariable(listOf("test")) shouldBe null
|
zp1.variables[listOf("test")] shouldBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r0")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r0")] shouldNotBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r15")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r15")] shouldNotBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r0L")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r0L")] shouldNotBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r15L")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r15L")] shouldNotBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r0sH")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r0sH")] shouldNotBe null
|
||||||
zp1.allocatedZeropageVariable(listOf("cx16", "r15sH")) shouldNotBe null
|
zp1.variables[listOf("cx16", "r15sH")] shouldNotBe null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
package prog8.compilerinterface
|
package prog8.compilerinterface
|
||||||
|
|
||||||
|
import prog8.ast.base.DataType
|
||||||
|
import prog8.ast.base.Position
|
||||||
|
import prog8.ast.expressions.Expression
|
||||||
import prog8.ast.statements.Block
|
import prog8.ast.statements.Block
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
|
|
||||||
|
|
||||||
interface IVariableAllocation {
|
interface IVariableAllocation {
|
||||||
|
data class ConstantNumberSymbol(val type: DataType, val name: String, val value: Double, val position: Position)
|
||||||
|
data class MemoryMappedSymbol(val type: DataType, val name: String, val address: UInt, val position: Position)
|
||||||
|
data class StaticBlockVariable(val type: DataType, val name: String, val initialValue: Expression?, val position: Position, val origVar: VarDecl) // TODO should get rid of origVar altogether
|
||||||
|
data class StaticSubroutineVariable(val type: DataType, val name: String, val position: Position, val origVar: VarDecl) // TODO should get rid of origVar altogether
|
||||||
|
data class ZeropageVariable(val type: DataType, val scopedname: List<String>, val position: Position)
|
||||||
|
|
||||||
fun dump(memsizer: IMemSizer)
|
fun dump(memsizer: IMemSizer)
|
||||||
|
|
||||||
val blockVars: Map<Block, Set<VarDecl>>
|
val zeropageVars: Set<ZeropageVariable> // also present in the Zeropage object after this allocation
|
||||||
val subroutineVars: Map<Subroutine, Set<VarDecl>>
|
val blockVars: Map<Block, Set<StaticBlockVariable>>
|
||||||
|
val blockConsts: Map<Block, Set<ConstantNumberSymbol>>
|
||||||
|
val blockMemvars: Map<Block, Set<MemoryMappedSymbol>>
|
||||||
|
val subroutineVars: Map<Subroutine, Set<StaticSubroutineVariable>>
|
||||||
|
val subroutineConsts: Map<Subroutine, Set<ConstantNumberSymbol>>
|
||||||
|
val subroutineMemvars: Map<Subroutine, Set<MemoryMappedSymbol>>
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
|||||||
// name (scoped) ==> pair of address to (Datatype + bytesize)
|
// name (scoped) ==> pair of address to (Datatype + bytesize)
|
||||||
protected val allocatedVariables = mutableMapOf<List<String>, Pair<UInt, Pair<DataType, Int>>>()
|
protected val allocatedVariables = mutableMapOf<List<String>, Pair<UInt, Pair<DataType, Int>>>()
|
||||||
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
|
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
|
||||||
|
public val variables: Map<List<String>, Pair<UInt, Pair<DataType, Int>>> = allocatedVariables
|
||||||
|
|
||||||
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
|
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
|
||||||
|
|
||||||
@ -107,6 +108,4 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
|||||||
require(size>0)
|
require(size>0)
|
||||||
return free.containsAll((address until address+size.toUInt()).toList())
|
return free.containsAll((address until address+size.toUInt()).toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allocatedZeropageVariable(name: List<String>): Pair<UInt, Pair<DataType, Int>>? = allocatedVariables[name]
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user