IR codegen: global vars with numeric initialization value are now also put into the VARIABLESWITHINIT section rather than requiring explicit code instructions to initialize them in INITGLOBALS.

Note that something similar, such as putting those variables inline in the program initialized with their value and all, cannot be done for the 6502 codegen: the program needs a mechanism to reset ALL variables when it runs a second time.
This commit is contained in:
Irmen de Jong
2024-10-16 20:07:48 +02:00
parent abbf7c7cb0
commit 38ef394e15
9 changed files with 103 additions and 42 deletions
+24 -12
View File
@@ -178,31 +178,43 @@ open class StNode(val name: String,
class StStaticVariable(name: String,
val dt: DataType,
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
val onetimeInitializationStringValue: StString?,
val onetimeInitializationArrayValue: StArray?,
val initializationStringValue: StString?,
val initializationArrayValue: StArray?,
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
val zpwish: ZeropageWish, // used in the variable allocator
astNode: PtNode) : StNode(name, StNodeType.STATICVAR, astNode) {
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
var initializationNumericValue: Double? = null
private set
fun setOnetimeInitNumeric(number: Double) {
// In certain cases the init value of an existing var should be updated,
// so we can't ask this as a constructor parameter.
// This has to do with the way Prog8 does the (re)initialization of such variables: via code assignment statements.
// Certain codegens might want to put them back into the variable directly.
// For strings and arrays this doesn't occur - these are always already specced at creation time.
initializationNumericValue = number
}
val uninitialized: Boolean
get() = initializationArrayValue==null && initializationStringValue==null && initializationNumericValue==null
init {
if(length!=null) {
require(onetimeInitializationNumericValue == null)
if(onetimeInitializationArrayValue!=null)
require(onetimeInitializationArrayValue.isEmpty() ||onetimeInitializationArrayValue.size==length)
require(initializationNumericValue == null)
if(initializationArrayValue!=null)
require(initializationArrayValue.isEmpty() ||initializationArrayValue.size==length)
}
if(onetimeInitializationNumericValue!=null) {
if(initializationNumericValue!=null) {
require(dt in NumericDatatypes || dt==DataType.BOOL)
}
if(onetimeInitializationArrayValue!=null) {
if(initializationArrayValue!=null) {
require(dt in ArrayDatatypes)
require(length==onetimeInitializationArrayValue.size)
require(length==initializationArrayValue.size)
}
if(onetimeInitializationStringValue!=null) {
if(initializationStringValue!=null) {
require(dt == DataType.STR)
require(length == onetimeInitializationStringValue.first.length+1)
require(length == initializationStringValue.first.length+1)
}
}
}
+4 -1
View File
@@ -95,7 +95,10 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
// if(node.type in SplitWordArrayTypes) {
// ... split array also add _lsb and _msb to symboltable?
// }
StStaticVariable(node.name, node.type, initialNumeric, initialString, initialArray, numElements, node.zeropage, node)
val stVar = StStaticVariable(node.name, node.type, initialString, initialArray, numElements, node.zeropage, node)
if(initialNumeric!=null)
stVar.setOnetimeInitNumeric(initialNumeric)
stVar
}
is PtBuiltinFunctionCall -> {
if(node.name=="memory") {