mirror of
https://github.com/irmen/prog8.git
synced 2024-10-25 00:24:16 +00:00
getting rid of old IVariablesAndConsts object
This commit is contained in:
parent
496245c801
commit
cf362c4a61
@ -31,14 +31,14 @@ class AsmGen(internal val program: Program,
|
|||||||
internal val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40,50,80,100,320,640)
|
internal val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40,50,80,100,320,640)
|
||||||
internal val loopEndLabels = ArrayDeque<String>()
|
internal val loopEndLabels = ArrayDeque<String>()
|
||||||
private val zeropage = options.compTarget.machine.zeropage
|
private val zeropage = options.compTarget.machine.zeropage
|
||||||
private val allocator = VariableAllocator(variables, options, errors)
|
private val allocator = VariableAllocator(variables, symbolTable, options, errors)
|
||||||
private val assemblyLines = mutableListOf<String>()
|
private val assemblyLines = mutableListOf<String>()
|
||||||
private val breakpointLabels = mutableListOf<String>()
|
private val breakpointLabels = mutableListOf<String>()
|
||||||
private val forloopsAsmGen = ForLoopsAsmGen(program, this, zeropage)
|
private val forloopsAsmGen = ForLoopsAsmGen(program, this, zeropage)
|
||||||
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
||||||
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
||||||
private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator)
|
private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator)
|
||||||
private val programGen = ProgramAndVarsGen(program, variables, symbolTable, options, errors, functioncallAsmGen, this, allocator, zeropage)
|
private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage)
|
||||||
private val assignmentAsmGen = AssignmentAsmGen(program, this, allocator)
|
private val assignmentAsmGen = AssignmentAsmGen(program, this, allocator)
|
||||||
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen, allocator)
|
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen, allocator)
|
||||||
|
|
||||||
|
@ -23,10 +23,9 @@ import kotlin.math.absoluteValue
|
|||||||
*/
|
*/
|
||||||
internal class ProgramAndVarsGen(
|
internal class ProgramAndVarsGen(
|
||||||
val program: Program,
|
val program: Program,
|
||||||
val variables: IVariablesAndConsts,
|
|
||||||
val symboltable: SymbolTable,
|
|
||||||
val options: CompilationOptions,
|
val options: CompilationOptions,
|
||||||
val errors: IErrorReporter,
|
val errors: IErrorReporter,
|
||||||
|
private val symboltable: SymbolTable, // TODO stick this in Program
|
||||||
private val functioncallAsmGen: FunctionCallAsmGen,
|
private val functioncallAsmGen: FunctionCallAsmGen,
|
||||||
private val asmgen: AsmGen,
|
private val asmgen: AsmGen,
|
||||||
private val allocator: VariableAllocator,
|
private val allocator: VariableAllocator,
|
||||||
@ -383,15 +382,19 @@ internal class ProgramAndVarsGen(
|
|||||||
clc""")
|
clc""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
private fun zeropagevars2asm(block: Block) {
|
private fun zeropagevars2asm(block: Block) {
|
||||||
//val scope = symboltable.lookupOrElse(block.name) { throw AssemblyError("lookup fail") }
|
val scope = symboltable.lookupOrElse(block.name) { throw AssemblyError("lookup") }
|
||||||
//require(scope.type==StNodeType.BLOCK)
|
require(scope.type==StNodeType.BLOCK)
|
||||||
val varnames = variables.blockVars.getOrDefault(block, emptySet()).map { it.scopedname }.toSet()
|
val varnames = scope.children.filter { it.value.type==StNodeType.STATICVAR }.map { it.value.scopedName }.toSet()
|
||||||
zeropagevars2asm(varnames)
|
zeropagevars2asm(varnames)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
private fun zeropagevars2asm(sub: Subroutine) {
|
private fun zeropagevars2asm(sub: Subroutine) {
|
||||||
val varnames = variables.subroutineVars.getOrDefault(sub, emptySet()).map { it.scopedname }.toSet()
|
val scope = symboltable.lookupOrElse(sub.scopedName) { throw AssemblyError("lookup") }
|
||||||
|
require(scope.type==StNodeType.SUBROUTINE)
|
||||||
|
val varnames = scope.children.filter { it.value.type==StNodeType.STATICVAR }.map { it.value.scopedName }.toSet()
|
||||||
zeropagevars2asm(varnames)
|
zeropagevars2asm(varnames)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,32 +407,44 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
|
// TODO don't have this as a separate loop, use a partition over the variables in the block; ZP<->NonZP
|
||||||
private fun nonZpVariables2asm(block: Block) {
|
private fun nonZpVariables2asm(block: Block) {
|
||||||
val variables = variables.blockVars[block]?.filter { !allocator.isZpVar(it.scopedname) } ?: emptyList()
|
val scope = symboltable.lookupOrElse(block.name) { throw AssemblyError("lookup") }
|
||||||
|
require(scope.type==StNodeType.BLOCK)
|
||||||
|
val variables = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
|
||||||
|
.map { it.value as StStaticVariable }
|
||||||
nonZpVariables2asm(variables)
|
nonZpVariables2asm(variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
|
// TODO don't have this as a separate loop, use a partition over the variables in the subroutine; ZP<->NonZP
|
||||||
private fun nonZpVariables2asm(sub: Subroutine) {
|
private fun nonZpVariables2asm(sub: Subroutine) {
|
||||||
val variables = variables.subroutineVars[sub]?.filter { !allocator.isZpVar(it.scopedname) } ?: emptyList()
|
val scope = symboltable.lookupOrElse(sub.scopedName) { throw AssemblyError("lookup") }
|
||||||
|
require(scope.type==StNodeType.SUBROUTINE)
|
||||||
|
val variables = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
|
||||||
|
.map { it.value as StStaticVariable }
|
||||||
nonZpVariables2asm(variables)
|
nonZpVariables2asm(variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun nonZpVariables2asm(variables: List<IVariablesAndConsts.StaticVariable>) {
|
private fun nonZpVariables2asm(variables: List<StStaticVariable>) {
|
||||||
asmgen.out("")
|
asmgen.out("")
|
||||||
asmgen.out("; non-zeropage variables")
|
asmgen.out("; non-zeropage variables")
|
||||||
val (stringvars, othervars) = variables.partition { it.type==DataType.STR }
|
val (stringvars, othervars) = variables.partition { it.dt==DataType.STR }
|
||||||
stringvars.forEach {
|
stringvars.forEach {
|
||||||
val stringvalue = it.initialValue as StringLiteral
|
val stringvalue = it.initialvalue as StringLiteral
|
||||||
outputStringvar(it.scopedname.last(), it.type, stringvalue.encoding, stringvalue.value)
|
outputStringvar(it.name, it.dt, stringvalue.encoding, stringvalue.value)
|
||||||
}
|
}
|
||||||
othervars.sortedBy { it.type }.forEach {
|
othervars.sortedBy { it.type }.forEach {
|
||||||
staticVariable2asm(it)
|
staticVariable2asm(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun staticVariable2asm(variable: IVariablesAndConsts.StaticVariable) {
|
private fun staticVariable2asm(variable: StStaticVariable) {
|
||||||
val name = variable.scopedname.last()
|
val name = variable.name
|
||||||
val value = variable.initialValue
|
val value = variable.initialvalue
|
||||||
val staticValue: Number =
|
val staticValue: Number =
|
||||||
if(value!=null) {
|
if(value!=null) {
|
||||||
if(value is NumericLiteral) {
|
if(value is NumericLiteral) {
|
||||||
@ -438,13 +453,13 @@ internal class ProgramAndVarsGen(
|
|||||||
else
|
else
|
||||||
value.number.toInt()
|
value.number.toInt()
|
||||||
} else {
|
} else {
|
||||||
if(variable.type in NumericDatatypes)
|
if(variable.dt in NumericDatatypes)
|
||||||
throw AssemblyError("can only deal with constant numeric values for global vars")
|
throw AssemblyError("can only deal with constant numeric values for global vars")
|
||||||
else 0
|
else 0
|
||||||
}
|
}
|
||||||
} else 0
|
} else 0
|
||||||
|
|
||||||
when (variable.type) {
|
when (variable.dt) {
|
||||||
DataType.UBYTE -> asmgen.out("$name\t.byte ${staticValue.toHex()}")
|
DataType.UBYTE -> asmgen.out("$name\t.byte ${staticValue.toHex()}")
|
||||||
DataType.BYTE -> asmgen.out("$name\t.char $staticValue")
|
DataType.BYTE -> asmgen.out("$name\t.char $staticValue")
|
||||||
DataType.UWORD -> asmgen.out("$name\t.word ${staticValue.toHex()}")
|
DataType.UWORD -> asmgen.out("$name\t.word ${staticValue.toHex()}")
|
||||||
@ -460,7 +475,7 @@ internal class ProgramAndVarsGen(
|
|||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
throw AssemblyError("all string vars should have been interned into prog")
|
throw AssemblyError("all string vars should have been interned into prog")
|
||||||
}
|
}
|
||||||
in ArrayDatatypes -> arrayVariable2asm(name, variable.type, value as? ArrayLiteral, variable.arraysize)
|
in ArrayDatatypes -> arrayVariable2asm(name, variable.dt, value as? ArrayLiteral, variable.arraysize)
|
||||||
else -> {
|
else -> {
|
||||||
throw AssemblyError("weird dt")
|
throw AssemblyError("weird dt")
|
||||||
}
|
}
|
||||||
@ -524,30 +539,41 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
private fun memdefsAndConsts2asm(block: Block) {
|
private fun memdefsAndConsts2asm(block: Block) {
|
||||||
val mvs = variables.blockMemvars[block] ?: emptySet()
|
val scope = symboltable.lookupOrElse(block.name) { throw AssemblyError("lookup") }
|
||||||
val consts = variables.blockConsts[block] ?: emptySet()
|
require(scope.type==StNodeType.BLOCK)
|
||||||
|
val mvs = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.MEMVAR }
|
||||||
|
.map { it.value as StMemVar }
|
||||||
|
val consts = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.CONSTANT }
|
||||||
|
.map { it.value as StConstant }
|
||||||
memdefsAndConsts2asm(mvs, consts)
|
memdefsAndConsts2asm(mvs, consts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO avoid looking up the variables multiple times because the Ast node is used as an anchor
|
||||||
private fun memdefsAndConsts2asm(sub: Subroutine) {
|
private fun memdefsAndConsts2asm(sub: Subroutine) {
|
||||||
val mvs = variables.subroutineMemvars[sub] ?: emptySet()
|
val scope = symboltable.lookupOrElse(sub.scopedName) { throw AssemblyError("lookup") }
|
||||||
val consts = variables.subroutineConsts[sub] ?: emptySet()
|
require(scope.type==StNodeType.SUBROUTINE)
|
||||||
|
val mvs = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.MEMVAR }
|
||||||
|
.map { it.value as StMemVar }
|
||||||
|
val consts = scope.children
|
||||||
|
.filter { it.value.type==StNodeType.CONSTANT }
|
||||||
|
.map { it.value as StConstant }
|
||||||
memdefsAndConsts2asm(mvs, consts)
|
memdefsAndConsts2asm(mvs, consts)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun memdefsAndConsts2asm(
|
private fun memdefsAndConsts2asm(memvars: Collection<StMemVar>, consts: Collection<StConstant>) {
|
||||||
memvars: Set<IVariablesAndConsts.MemoryMappedVariable>,
|
|
||||||
consts: Set<IVariablesAndConsts.ConstantNumberSymbol>
|
|
||||||
) {
|
|
||||||
memvars.forEach {
|
memvars.forEach {
|
||||||
asmgen.out(" ${it.scopedname.last()} = ${it.address.toHex()}")
|
asmgen.out(" ${it.name} = ${it.address.toHex()}")
|
||||||
}
|
}
|
||||||
consts.forEach {
|
consts.forEach {
|
||||||
if(it.type==DataType.FLOAT)
|
if(it.dt==DataType.FLOAT)
|
||||||
asmgen.out(" ${it.scopedname.last()} = ${it.value}")
|
asmgen.out(" ${it.name} = ${it.value}")
|
||||||
else
|
else
|
||||||
asmgen.out(" ${it.scopedname.last()} = ${it.value.toHex()}")
|
asmgen.out(" ${it.name} = ${it.value.toHex()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import prog8.compilerinterface.*
|
|||||||
|
|
||||||
|
|
||||||
internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||||
|
private val symboltable: SymbolTable,
|
||||||
private val options: CompilationOptions,
|
private val options: CompilationOptions,
|
||||||
private val errors: IErrorReporter) {
|
private val errors: IErrorReporter) {
|
||||||
|
|
||||||
@ -35,28 +36,59 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
if(options.zeropage== ZeropageType.DONTUSE)
|
if(options.zeropage== ZeropageType.DONTUSE)
|
||||||
return
|
return
|
||||||
|
|
||||||
val allVariables = (
|
val allVariablesOld = (
|
||||||
vars.blockVars.asSequence().flatMap { it.value } +
|
vars.blockVars.asSequence().flatMap { it.value } +
|
||||||
vars.subroutineVars.asSequence().flatMap { it.value }
|
vars.subroutineVars.asSequence().flatMap { it.value }
|
||||||
).toList()
|
).toList()
|
||||||
|
|
||||||
val numberOfAllocatableVariables = allVariables.size
|
val allVariables = collectAllVariables(symboltable)
|
||||||
val varsRequiringZp = allVariables.filter { it.zp == ZeropageWish.REQUIRE_ZEROPAGE }
|
require(allVariables.size == allVariablesOld.size)
|
||||||
val varsPreferringZp = allVariables.filter { it.zp == ZeropageWish.PREFER_ZEROPAGE }
|
require(allVariables.map{it.scopedName}.toSet()==allVariablesOld.map{it.scopedname}.toSet())
|
||||||
val varsDontCare = allVariables.filter { it.zp == ZeropageWish.DONTCARE }
|
|
||||||
val numberOfExplicitNonZpVariables = allVariables.count { it.zp == ZeropageWish.NOT_IN_ZEROPAGE }
|
val numberOfAllocatableVariables = allVariablesOld.size
|
||||||
|
val varsRequiringZp = allVariablesOld.filter { it.zp == ZeropageWish.REQUIRE_ZEROPAGE }
|
||||||
|
val varsPreferringZp = allVariablesOld.filter { it.zp == ZeropageWish.PREFER_ZEROPAGE }
|
||||||
|
val varsDontCare = allVariablesOld.filter { it.zp == ZeropageWish.DONTCARE }
|
||||||
|
val numberOfExplicitNonZpVariables = allVariablesOld.count { it.zp == ZeropageWish.NOT_IN_ZEROPAGE }
|
||||||
require(varsDontCare.size + varsRequiringZp.size + varsPreferringZp.size + numberOfExplicitNonZpVariables == numberOfAllocatableVariables)
|
require(varsDontCare.size + varsRequiringZp.size + varsPreferringZp.size + numberOfExplicitNonZpVariables == numberOfAllocatableVariables)
|
||||||
|
|
||||||
|
val numberOfAllocatableVariables2 = allVariables.size
|
||||||
|
val varsRequiringZp2 = allVariables.filter { it.zpw == ZeropageWish.REQUIRE_ZEROPAGE }
|
||||||
|
val varsPreferringZp2 = allVariables.filter { it.zpw == ZeropageWish.PREFER_ZEROPAGE }
|
||||||
|
val varsDontCare2 = allVariables.filter { it.zpw == ZeropageWish.DONTCARE }
|
||||||
|
val numberOfExplicitNonZpVariables2 = allVariables.count { it.zpw == ZeropageWish.NOT_IN_ZEROPAGE }
|
||||||
|
require(varsDontCare2.size + varsRequiringZp2.size + varsPreferringZp2.size + numberOfExplicitNonZpVariables2 == numberOfAllocatableVariables2)
|
||||||
|
require(varsDontCare2.size==varsDontCare.size)
|
||||||
|
require(varsRequiringZp2.size==varsRequiringZp.size)
|
||||||
|
require(varsPreferringZp2.size==varsPreferringZp.size)
|
||||||
|
require(numberOfExplicitNonZpVariables2==numberOfExplicitNonZpVariables)
|
||||||
|
require(numberOfAllocatableVariables2==numberOfAllocatableVariables)
|
||||||
|
|
||||||
|
val oldvarsByName = varsDontCare.associateBy { it.scopedname }
|
||||||
|
val newvarsByName = varsDontCare2.associateBy { it.scopedName }
|
||||||
|
require(oldvarsByName.keys==newvarsByName.keys)
|
||||||
|
oldvarsByName.forEach { (name, oldvar) ->
|
||||||
|
val newvar = newvarsByName.getValue(name)
|
||||||
|
require(oldvar.scopedname==newvar.scopedName)
|
||||||
|
require(oldvar.type==newvar.dt)
|
||||||
|
require(oldvar.zp==newvar.zpw)
|
||||||
|
require(oldvar.initialValue==newvar.initialvalue)
|
||||||
|
require(oldvar.arraysize==newvar.arraysize)
|
||||||
|
require(oldvar.position==newvar.position)
|
||||||
|
require(numArrayElements(oldvar) == numArrayElements(newvar))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var numVariablesAllocatedInZP = 0
|
var numVariablesAllocatedInZP = 0
|
||||||
var numberOfNonIntegerVariables = 0
|
var numberOfNonIntegerVariables = 0
|
||||||
|
|
||||||
varsRequiringZp.forEach { variable ->
|
varsRequiringZp2.forEach { variable ->
|
||||||
val numElements = numArrayElements(variable)
|
val numElements = numArrayElements(variable)
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedname,
|
variable.scopedName,
|
||||||
variable.type,
|
variable.dt,
|
||||||
numElements,
|
numElements,
|
||||||
variable.initialValue,
|
variable.initialvalue,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -71,13 +103,13 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
varsPreferringZp.forEach { variable ->
|
varsPreferringZp2.forEach { variable ->
|
||||||
val numElements = numArrayElements(variable)
|
val numElements = numArrayElements(variable)
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedname,
|
variable.scopedName,
|
||||||
variable.type,
|
variable.dt,
|
||||||
numElements,
|
numElements,
|
||||||
variable.initialValue,
|
variable.initialvalue,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -88,17 +120,17 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
// try to allocate any other interger variables into the zeropage until it is full.
|
// try to allocate any other interger variables into the zeropage until it is full.
|
||||||
// TODO some form of intelligent priorization? most often used variables first? loopcounter vars first? ...?
|
// TODO some form of intelligent priorization? most often used variables first? loopcounter vars first? ...?
|
||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
for (variable in varsDontCare) {
|
for (variable in varsDontCare2.sortedWith(compareBy({it.scopedName.size}, {it.name}))) {
|
||||||
if(variable.type in IntegerDatatypes) {
|
if(variable.dt in IntegerDatatypes) {
|
||||||
if(zeropage.free.isEmpty()) {
|
if(zeropage.free.isEmpty()) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
val numElements = numArrayElements(variable)
|
val numElements = numArrayElements(variable)
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedname,
|
variable.scopedName,
|
||||||
variable.type,
|
variable.dt,
|
||||||
numElements,
|
numElements,
|
||||||
variable.initialValue,
|
variable.initialvalue,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -115,6 +147,20 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
println(" zeropage free space: ${zeropage.free.size} bytes")
|
println(" zeropage free space: ${zeropage.free.size} bytes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun collectAllVariables(st: SymbolTable): Collection<StStaticVariable> {
|
||||||
|
val vars = mutableListOf<StStaticVariable>()
|
||||||
|
fun collect(node: StNode) {
|
||||||
|
for(child in node.children) {
|
||||||
|
if(child.value.type==StNodeType.STATICVAR)
|
||||||
|
vars.add(child.value as StStaticVariable)
|
||||||
|
else
|
||||||
|
collect(child.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collect(st)
|
||||||
|
return vars
|
||||||
|
}
|
||||||
|
|
||||||
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
|
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
|
||||||
|
|
||||||
private fun numArrayElements(variable: IVariablesAndConsts.StaticVariable) =
|
private fun numArrayElements(variable: IVariablesAndConsts.StaticVariable) =
|
||||||
@ -124,6 +170,13 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun numArrayElements(variable: StStaticVariable) =
|
||||||
|
when(variable.dt) {
|
||||||
|
DataType.STR -> (variable.initialvalue as StringLiteral).value.length
|
||||||
|
in ArrayDatatypes -> variable.arraysize!!
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
||||||
var extra = subroutineExtras[sub]
|
var extra = subroutineExtras[sub]
|
||||||
return if(extra==null) {
|
return if(extra==null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user