mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 04:29:36 +00:00
slight tweaks to zp and allocator
This commit is contained in:
parent
c8cd6e9460
commit
2725c4ad4d
@ -297,10 +297,9 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
}
|
||||
|
||||
val zp = zeropage
|
||||
// string and array variables in zeropage that have initializer value, should be initialized
|
||||
val stringVarsWithInitInZp = zp.variables.filter { it.value.dt==DataType.STR && it.value.initialStringValue!=null }
|
||||
val arrayVarsWithInitInZp = zp.variables.filter { it.value.dt in ArrayDatatypes && it.value.initialArrayValue!=null }
|
||||
val stringVarsWithInitInZp = allocator.zeropageVars.filter { it.value.dt==DataType.STR && it.value.initialStringValue!=null }
|
||||
val arrayVarsWithInitInZp = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes && it.value.initialArrayValue!=null }
|
||||
if(stringVarsWithInitInZp.isNotEmpty() || arrayVarsWithInitInZp.isNotEmpty()) {
|
||||
asmgen.out("; zp str and array initializations")
|
||||
stringVarsWithInitInZp.forEach {
|
||||
@ -352,7 +351,7 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
|
||||
private fun zeropagevars2asm(scope: INameScope) {
|
||||
val zpVariables = zeropage.variables.filter { it.value.originalScope==scope }
|
||||
val zpVariables = allocator.zeropageVars.filter { it.value.originalScope==scope }
|
||||
for ((scopedName, zpvar) in zpVariables) {
|
||||
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
|
||||
|
@ -8,10 +8,7 @@ import prog8.ast.base.IntegerDatatypes
|
||||
import prog8.ast.expressions.StringLiteral
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.ast.statements.ZeropageWish
|
||||
import prog8.compilerinterface.CompilationOptions
|
||||
import prog8.compilerinterface.IErrorReporter
|
||||
import prog8.compilerinterface.IVariablesAndConsts
|
||||
import prog8.compilerinterface.ZeropageType
|
||||
import prog8.compilerinterface.*
|
||||
|
||||
|
||||
internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
@ -23,6 +20,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>()
|
||||
internal val memorySlabs: Map<String, Pair<UInt, UInt>> = memorySlabsInternal
|
||||
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
|
||||
internal val zeropageVars: Map<List<String>, Zeropage.ZpAllocation> = zeropage.allocatedVariables
|
||||
|
||||
internal fun getMemorySlab(name: String) = memorySlabsInternal[name]
|
||||
internal fun allocateMemorySlab(name: String, size: UInt, align: UInt) {
|
||||
@ -120,7 +118,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
println(" zeropage free space: ${zeropage.free.size} bytes")
|
||||
}
|
||||
|
||||
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.variables
|
||||
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
|
||||
|
||||
private fun numArrayElements(variable: IVariablesAndConsts.StaticVariable) =
|
||||
when(variable.type) {
|
||||
@ -129,7 +127,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
||||
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
||||
var extra = subroutineExtras[sub]
|
||||
return if(extra==null) {
|
||||
extra = SubroutineExtraAsmInfo()
|
||||
@ -140,7 +138,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||
extra
|
||||
}
|
||||
|
||||
fun getFloatAsmConst(number: Double): String {
|
||||
internal fun getFloatAsmConst(number: Double): String {
|
||||
val asmName = globalFloatConsts[number]
|
||||
if(asmName!=null)
|
||||
return asmName
|
||||
|
@ -264,12 +264,12 @@ class TestCx16Zeropage: FunSpec({
|
||||
|
||||
test("preallocated zp vars") {
|
||||
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target))
|
||||
zp1.variables[listOf("test")] shouldBe null
|
||||
zp1.variables[listOf("cx16", "r0")] shouldNotBe null
|
||||
zp1.variables[listOf("cx16", "r15")] shouldNotBe null
|
||||
zp1.variables[listOf("cx16", "r0L")] shouldNotBe null
|
||||
zp1.variables[listOf("cx16", "r15L")] shouldNotBe null
|
||||
zp1.variables[listOf("cx16", "r0sH")] shouldNotBe null
|
||||
zp1.variables[listOf("cx16", "r15sH")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("test")] shouldBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r0")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r15")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r0L")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r15L")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r0sH")] shouldNotBe null
|
||||
zp1.allocatedVariables[listOf("cx16", "r15sH")] shouldNotBe null
|
||||
}
|
||||
})
|
||||
|
@ -29,9 +29,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
||||
|
||||
// the variables allocated into Zeropage.
|
||||
// name (scoped) ==> pair of address to (Datatype + bytesize)
|
||||
protected val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()
|
||||
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
|
||||
val variables: Map<List<String>, ZpAllocation> = allocatedVariables
|
||||
val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()
|
||||
|
||||
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
|
||||
|
||||
@ -61,7 +59,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
||||
position: Position?,
|
||||
errors: IErrorReporter): Result<Pair<UInt, Int>, ZeropageAllocationError> {
|
||||
|
||||
require(name.isEmpty() || !allocations.values.any { it.first==name } ) {"name can't be allocated twice"}
|
||||
require(name.isEmpty() || name !in allocatedVariables) {"name can't be allocated twice"}
|
||||
|
||||
if(options.zeropage== ZeropageType.DONTUSE)
|
||||
return Err(ZeropageAllocationError("zero page usage has been disabled"))
|
||||
@ -114,7 +112,6 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
||||
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>, initValue: Expression?, originalScope: INameScope): UInt {
|
||||
require(size>=0)
|
||||
free.removeAll(address until address+size.toUInt())
|
||||
allocations[address] = name to datatype
|
||||
if(name.isNotEmpty()) {
|
||||
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
|
||||
|
@ -27,6 +27,7 @@ Compiler:
|
||||
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
|
||||
- unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement classes, may require moving Expression/Statement into interfaces instead of abstract base classes
|
||||
- for the pipe operator: recognise a placeholder (``?`` or ``%`` or ``_``) in a non-unary function call to allow non-unary functions in the chain; ``4 |> mkword(?, $44) |> print_uw``
|
||||
OR: change pipe syntax and require function call, but always have implicit first argument added.
|
||||
- for the pipe operator: make it 100% syntactic sugar so there's no need for asm codegen like translatePipeExpression
|
||||
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
|
||||
but this requires all identifiers in the inlined expression to be changed to fully scoped names.
|
||||
@ -69,5 +70,6 @@ Optimizations:
|
||||
- translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable
|
||||
- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions
|
||||
- when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop
|
||||
but we have no efficient way right now to see if the body references a variable.
|
||||
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning.
|
||||
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword zzz = memory("sdfasdf", 100, 0)
|
||||
str @shared foobar = "zsdfzsdf"
|
||||
str @shared foobar2 = sc:"zsdfzsdf"
|
||||
ubyte @shared xx
|
||||
|
||||
if xx==1 or xx==2 or xx==3 {
|
||||
xx++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user