mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
report free/occupied Zeropage space at end of compilation
This commit is contained in:
parent
f7e74b3088
commit
c13b7fd883
@ -39,6 +39,7 @@ internal class ProgramAndVarsGen(
|
||||
require(allInitializers.all { it.origin==AssignmentOrigin.VARINIT }) {"all block-level assignments must be a variable initializer"}
|
||||
|
||||
allocator.allocateZeropageVariables()
|
||||
|
||||
header()
|
||||
val allBlocks = program.allBlocks
|
||||
if(allBlocks.first().name != "main")
|
||||
@ -63,7 +64,8 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("; generated by $ourName on ${LocalDateTime.now().withNano(0)}")
|
||||
asmgen.out("; assembler syntax is for the 64tasm cross-assembler")
|
||||
asmgen.out("; output options: output=${options.output} launcher=${options.launcher} zp=${options.zeropage}")
|
||||
asmgen.out("\n.cpu '$cpu'\n.enc 'none'\n")
|
||||
asmgen.out("")
|
||||
asmgen.out(".cpu '$cpu'\n.enc 'none'\n")
|
||||
|
||||
program.actualLoadAddress = program.definedLoadAddress
|
||||
if (program.actualLoadAddress == 0u) // fix load address
|
||||
@ -153,7 +155,8 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
|
||||
private fun block2asm(block: Block) {
|
||||
asmgen.out("\n\n; ---- block: '${block.name}' ----")
|
||||
asmgen.out("")
|
||||
asmgen.out("; ---- block: '${block.name}' ----")
|
||||
if(block.address!=null)
|
||||
asmgen.out("* = ${block.address!!.toHex()}")
|
||||
else {
|
||||
@ -172,7 +175,8 @@ internal class ProgramAndVarsGen(
|
||||
asmsubs2asm(block.statements)
|
||||
nonZpVariables2asm(block)
|
||||
|
||||
asmgen.out("\n; subroutines in this block")
|
||||
asmgen.out("")
|
||||
asmgen.out("; subroutines in this block")
|
||||
|
||||
// First translate regular statements, and then put the subroutines at the end.
|
||||
// (regular statements = everything except the initialization assignments;
|
||||
@ -365,7 +369,8 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
|
||||
private fun nonZpVariables2asm(variables: List<IVariablesAndConsts.StaticVariable>) {
|
||||
asmgen.out("\n; non-zeropage variables")
|
||||
asmgen.out("")
|
||||
asmgen.out("; non-zeropage variables")
|
||||
val (stringvars, othervars) = variables.partition { it.type==DataType.STR }
|
||||
stringvars.forEach {
|
||||
val stringvalue = it.initialValue as StringLiteralValue
|
||||
|
@ -1,9 +1,8 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import com.github.michaelbull.result.onFailure
|
||||
import prog8.ast.base.ArrayDatatypes
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.IntegerDatatypes
|
||||
import com.github.michaelbull.result.fold
|
||||
import com.github.michaelbull.result.onSuccess
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.expressions.StringLiteralValue
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.ast.statements.ZeropageWish
|
||||
@ -41,20 +40,52 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
vars.subroutineVars.asSequence().flatMap { it.value }
|
||||
).toList()
|
||||
|
||||
val numberOfAllocatableVariables = allVariables.size
|
||||
val totalAllocatedMemorySize = allVariables.sumOf { memsize(it) }
|
||||
|
||||
val varsRequiringZp = allVariables.filter { it.zp == ZeropageWish.REQUIRE_ZEROPAGE }
|
||||
val varsPreferringZp = allVariables.filter { it.zp == ZeropageWish.PREFER_ZEROPAGE }
|
||||
val varsDontCare = allVariables.filter { it.zp == ZeropageWish.DONTCARE }
|
||||
val numberOfExplicitNonZpVariables = allVariables.count { it.zp == ZeropageWish.NOT_IN_ZEROPAGE }
|
||||
require(varsDontCare.size + varsRequiringZp.size + varsPreferringZp.size + numberOfExplicitNonZpVariables == numberOfAllocatableVariables)
|
||||
|
||||
var numVariablesAllocatedInZP: Int = 0
|
||||
var numberOfNonIntegerVariables: Int = 0
|
||||
|
||||
varsRequiringZp.forEach { variable ->
|
||||
val numElements = numArrayElements(variable)
|
||||
val result = zeropage.allocate(variable.scopedname, variable.type, variable.scope, numElements, variable.initialValue, variable.position, errors)
|
||||
result.onFailure { errors.err(it.message!!, variable.position) }
|
||||
val result = zeropage.allocate(
|
||||
variable.scopedname,
|
||||
variable.type,
|
||||
variable.scope,
|
||||
numElements,
|
||||
variable.initialValue,
|
||||
variable.position,
|
||||
errors
|
||||
)
|
||||
result.fold(
|
||||
success = {
|
||||
numVariablesAllocatedInZP++
|
||||
},
|
||||
failure = {
|
||||
errors.err(it.message!!, variable.position)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if(errors.noErrors()) {
|
||||
varsPreferringZp.forEach { variable ->
|
||||
val numElements = numArrayElements(variable)
|
||||
zeropage.allocate(variable.scopedname, variable.type, variable.scope, numElements, variable.initialValue, variable.position, errors)
|
||||
val result = zeropage.allocate(
|
||||
variable.scopedname,
|
||||
variable.type,
|
||||
variable.scope,
|
||||
numElements,
|
||||
variable.initialValue,
|
||||
variable.position,
|
||||
errors
|
||||
)
|
||||
result.onSuccess { numVariablesAllocatedInZP++ }
|
||||
// no need to check for allocation error, if there is one, just allocate in normal system ram.
|
||||
}
|
||||
|
||||
@ -63,14 +94,40 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
if(errors.noErrors()) {
|
||||
for (variable in varsDontCare) {
|
||||
if(variable.type in IntegerDatatypes) {
|
||||
val numElements = numArrayElements(variable)
|
||||
zeropage.allocate(variable.scopedname, variable.type, variable.scope, numElements, variable.initialValue, variable.position, errors)
|
||||
if(zeropage.free.isEmpty())
|
||||
if(zeropage.free.isEmpty()) {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
val numElements = numArrayElements(variable)
|
||||
val result = zeropage.allocate(
|
||||
variable.scopedname,
|
||||
variable.type,
|
||||
variable.scope,
|
||||
numElements,
|
||||
variable.initialValue,
|
||||
variable.position,
|
||||
errors
|
||||
)
|
||||
result.onSuccess { numVariablesAllocatedInZP++ }
|
||||
}
|
||||
} else
|
||||
numberOfNonIntegerVariables++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println(" number of allocated vars: $numberOfAllocatableVariables total size: $totalAllocatedMemorySize")
|
||||
println(" put into zeropage: $numVariablesAllocatedInZP, non-zp allocatable: ${numberOfNonIntegerVariables+numberOfExplicitNonZpVariables}")
|
||||
println(" zeropage free space: ${zeropage.free.size} bytes")
|
||||
}
|
||||
|
||||
private fun memsize(variable: IVariablesAndConsts.StaticVariable): Int {
|
||||
return when(variable.type) {
|
||||
in NumericDatatypes ->
|
||||
options.compTarget.memorySize(variable.type)
|
||||
in ArrayDatatypes -> variable.arraysize!! * options.compTarget.memorySize(ArrayToElementTypes.getValue(variable.type))
|
||||
DataType.STR -> (variable.initialValue as StringLiteralValue).value.length + 1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.variables
|
||||
|
@ -112,31 +112,31 @@ fun compileProgram(args: CompilerArguments): CompilationResult {
|
||||
println("\nTotal compilation+assemble time: ${round(seconds*100.0)/100.0} sec.")
|
||||
return CompilationResult(true, program, programName, compTarget, importedFiles)
|
||||
} catch (px: ParseError) {
|
||||
System.err.print("\u001b[91m") // bright red
|
||||
System.err.print("\n\u001b[91m") // bright red
|
||||
System.err.println("${px.position.toClickableStr()} parse error: ${px.message}".trim())
|
||||
System.err.print("\u001b[0m") // reset
|
||||
} catch (ac: AbortCompilation) {
|
||||
if(!ac.message.isNullOrEmpty()) {
|
||||
System.err.print("\u001b[91m") // bright red
|
||||
System.err.print("\n\u001b[91m") // bright red
|
||||
System.err.println(ac.message)
|
||||
System.err.print("\u001b[0m") // reset
|
||||
}
|
||||
} catch (nsf: NoSuchFileException) {
|
||||
System.err.print("\u001b[91m") // bright red
|
||||
System.err.print("\n\u001b[91m") // bright red
|
||||
System.err.println("File not found: ${nsf.message}")
|
||||
System.err.print("\u001b[0m") // reset
|
||||
} catch (ax: AstException) {
|
||||
System.err.print("\u001b[91m") // bright red
|
||||
System.err.print("\n\u001b[91m") // bright red
|
||||
System.err.println(ax.toString())
|
||||
System.err.print("\u001b[0m") // reset
|
||||
} catch (x: Exception) {
|
||||
print("\u001b[91m") // bright red
|
||||
print("\n\u001b[91m") // bright red
|
||||
println("\n* internal error *")
|
||||
print("\u001b[0m") // reset
|
||||
System.out.flush()
|
||||
throw x
|
||||
} catch (x: NotImplementedError) {
|
||||
print("\u001b[91m") // bright red
|
||||
print("\n\u001b[91m") // bright red
|
||||
println("\n* internal error: missing feature/code *")
|
||||
print("\u001b[0m") // reset
|
||||
System.out.flush()
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- make it so that subroutine parameters as variables can again be allocated in ZP, if there's still space
|
||||
...
|
||||
|
||||
|
||||
Need help with
|
||||
|
@ -1,63 +1,12 @@
|
||||
%import floats
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
ubyte @zp mainglobal1=10
|
||||
float @shared fl1 = floats.TWOPI
|
||||
|
||||
uword @shared m1 = memory("ee", 200, 0)
|
||||
|
||||
uword [2] nullwords
|
||||
ubyte [2] nullbytes
|
||||
uword [2] valuewords = [1111,22222]
|
||||
ubyte [2] valuebytes = [111,222]
|
||||
str name = "irmen"
|
||||
|
||||
uword [2] @requirezp zpnullwords
|
||||
ubyte [2] @requirezp zpnullbytes
|
||||
uword [2] @requirezp zpvaluewords = [11111,22222]
|
||||
ubyte [2] @requirezp zpvaluebytes = [111,222]
|
||||
str @requirezp zpname = "irmenzp"
|
||||
|
||||
sub start() {
|
||||
prog8_lib.P8ZP_SCRATCH_B1 = 1
|
||||
prog8_lib.P8ZP_SCRATCH_W1 = 1111
|
||||
str alsoname = "also name"
|
||||
|
||||
txt.print(alsoname)
|
||||
txt.print(zpname)
|
||||
txt.print("internedstring")
|
||||
txt.spc()
|
||||
txt.print_uwhex(&prog8_lib.P8ZP_SCRATCH_B1, true)
|
||||
txt.spc()
|
||||
txt.print_uwhex(&prog8_lib.P8ZP_SCRATCH_W1, true)
|
||||
txt.spc()
|
||||
txt.print_uwhex(&prog8_lib.P8ZP_SCRATCH_W2, true)
|
||||
txt.nl()
|
||||
|
||||
txt.print_uw(nullwords[1])
|
||||
txt.nl()
|
||||
txt.print_ub(nullbytes[1])
|
||||
txt.nl()
|
||||
txt.print_uw(valuewords[1])
|
||||
txt.nl()
|
||||
txt.print_ub(valuebytes[1])
|
||||
txt.nl()
|
||||
txt.print(name)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
txt.print_uw(zpnullwords[1])
|
||||
txt.nl()
|
||||
txt.print_ub(zpnullbytes[1])
|
||||
txt.nl()
|
||||
txt.print_uw(zpvaluewords[1])
|
||||
txt.nl()
|
||||
txt.print_ub(zpvaluebytes[1])
|
||||
txt.nl()
|
||||
txt.print(zpname)
|
||||
txt.nl()
|
||||
cx16.r0=0
|
||||
void routine22(1,2,3,4,5)
|
||||
}
|
||||
|
||||
sub routine22(ubyte aa1, ubyte aa2, ubyte aa3, ubyte aa4, ubyte aa5) -> ubyte {
|
||||
return aa1+aa2+aa3+aa4+aa5
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user