mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
remove explicit 'bss' from St var, changed to 'uninitialized'
This commit is contained in:
parent
9ca6860ffa
commit
dddf9a9396
@ -147,7 +147,6 @@ open class StNode(val name: String,
|
||||
|
||||
class StStaticVariable(name: String,
|
||||
val dt: DataType,
|
||||
val bss: Boolean,
|
||||
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
|
||||
val onetimeInitializationStringValue: StString?,
|
||||
val onetimeInitializationArrayValue: StArray?,
|
||||
@ -155,25 +154,22 @@ class StStaticVariable(name: String,
|
||||
val zpwish: ZeropageWish, // used in the variable allocator
|
||||
astNode: PtNode) : StNode(name, StNodeType.STATICVAR, astNode) {
|
||||
|
||||
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
|
||||
|
||||
init {
|
||||
if(bss) {
|
||||
require(onetimeInitializationNumericValue==null)
|
||||
require(onetimeInitializationStringValue==null)
|
||||
require(onetimeInitializationArrayValue.isNullOrEmpty())
|
||||
} else {
|
||||
require(onetimeInitializationNumericValue!=null ||
|
||||
onetimeInitializationStringValue!=null ||
|
||||
onetimeInitializationArrayValue!=null)
|
||||
}
|
||||
if(length!=null) {
|
||||
require(onetimeInitializationNumericValue == null)
|
||||
if(onetimeInitializationArrayValue!=null)
|
||||
require(onetimeInitializationArrayValue.isEmpty() ||onetimeInitializationArrayValue.size==length)
|
||||
}
|
||||
if(onetimeInitializationNumericValue!=null)
|
||||
if(onetimeInitializationNumericValue!=null) {
|
||||
require(dt in NumericDatatypes)
|
||||
if(onetimeInitializationArrayValue!=null)
|
||||
require(onetimeInitializationNumericValue!=0.0) { "zero as init value should just remain uninitialized"}
|
||||
}
|
||||
if(onetimeInitializationArrayValue!=null) {
|
||||
require(dt in ArrayDatatypes)
|
||||
require(onetimeInitializationArrayValue.any { it.number!=0.0} ) { "array of all zerors as init value should just remain uninitialized"}
|
||||
}
|
||||
if(onetimeInitializationStringValue!=null) {
|
||||
require(dt == DataType.STR)
|
||||
require(length == onetimeInitializationStringValue.first.length+1)
|
||||
|
@ -72,7 +72,8 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
val numElements: Int?
|
||||
val value = node.value
|
||||
if(value!=null) {
|
||||
initialNumeric = (value as? PtNumber)?.number
|
||||
val number = (value as? PtNumber)?.number
|
||||
initialNumeric = if(number==0.0) null else number // 0 as init value -> just uninitialized
|
||||
when (value) {
|
||||
is PtString -> {
|
||||
initialString = StString(value.value, value.encoding)
|
||||
@ -80,9 +81,10 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
numElements = value.value.length + 1 // include the terminating 0-byte
|
||||
}
|
||||
is PtArray -> {
|
||||
initialArray = makeInitialArray(value)
|
||||
val array = makeInitialArray(value)
|
||||
initialArray = if(array.all { it.number==0.0 }) null else array // all 0 as init value -> just uninitialized
|
||||
initialString = null
|
||||
numElements = initialArray.size
|
||||
numElements = array.size
|
||||
require(node.arraySize?.toInt()==numElements)
|
||||
}
|
||||
else -> {
|
||||
@ -97,7 +99,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
initialString = null
|
||||
numElements = node.arraySize?.toInt()
|
||||
}
|
||||
StStaticVariable(node.name, node.type, node.bss, initialNumeric, initialString, initialArray, numElements, node.zeropage, node)
|
||||
StStaticVariable(node.name, node.type, initialNumeric, initialString, initialArray, numElements, node.zeropage, node)
|
||||
}
|
||||
is PtBuiltinFunctionCall -> {
|
||||
if(node.name=="memory") {
|
||||
|
@ -155,13 +155,6 @@ class PtVariable(name: String, override val type: DataType, val zeropage: Zeropa
|
||||
init {
|
||||
value?.let {it.parent=this}
|
||||
}
|
||||
|
||||
val bss: Boolean =
|
||||
when (type) {
|
||||
DataType.STR -> false
|
||||
in ArrayDatatypes -> value==null || arraySize==0u
|
||||
else -> value==null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
|
||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
||||
val dontReinitGlobals by cli.option(ArgType.Boolean, fullName = "noreinit", description = "don't create code to reinitialize globals on multiple runs of the program (experimental)")
|
||||
val dontReinitGlobals by cli.option(ArgType.Boolean, fullName = "noreinit", description = "don't create code to reinitialize globals on multiple runs of the program")
|
||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
|
||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||
|
@ -124,10 +124,10 @@ private fun makeSt(): SymbolTable {
|
||||
block1.add(sub12)
|
||||
block1.add(StConstant("c1", DataType.UWORD, 12345.0, astConstant1))
|
||||
block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2))
|
||||
sub11.add(StStaticVariable("v1", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub1v1))
|
||||
sub11.add(StStaticVariable("v2", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2))
|
||||
sub12.add(StStaticVariable("v1", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1))
|
||||
sub12.add(StStaticVariable("v2", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2))
|
||||
sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v1))
|
||||
sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2))
|
||||
sub12.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1))
|
||||
sub12.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2))
|
||||
|
||||
val block2 = StNode("block2", StNodeType.BLOCK, astBlock2)
|
||||
val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21)
|
||||
|
@ -3,15 +3,14 @@ TODO
|
||||
|
||||
For next minor release
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
- fix hasInitValue() and isBssVar()
|
||||
- BSS.
|
||||
64tass can put variables into a section with .section BSS <variable> .send BSS
|
||||
and then putting .dsection BSS where it should output the BSS
|
||||
Define vars in BSS with .fill rather than .byte otherwise they STILL take up space!
|
||||
|
||||
- BSS in 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with bss=true.
|
||||
- BSS in 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with uninitialized=true.
|
||||
Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible.
|
||||
Note that 'bss' can still be true for variables that were moved into zeropage, so have to check that!
|
||||
Note that 'uninitialized' can still be true for variables that were moved into zeropage, so have to check that!
|
||||
- BSS subroutine parameters don't have to be set to 0.
|
||||
- when putting BSS in specific memory block ($a000-$bfff, $c000-$cfff) add a .cerror check for overflow!
|
||||
|
||||
|
@ -172,7 +172,7 @@ class IRFileReader {
|
||||
val dt: DataType = parseDatatype(type, arraysize!=null)
|
||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
|
||||
val newVar = StStaticVariable(name, dt, true, null, null, null, arraysize, zp, dummyNode)
|
||||
val newVar = StStaticVariable(name, dt, null, null, null, arraysize, zp, dummyNode)
|
||||
variables.add(newVar)
|
||||
}
|
||||
return variables
|
||||
@ -202,40 +202,23 @@ class IRFileReader {
|
||||
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
|
||||
val dt: DataType = parseDatatype(type, arraysize!=null)
|
||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||
val bss: Boolean
|
||||
var initNumeric: Double? = null
|
||||
var initArray: StArray? = null
|
||||
when(dt) {
|
||||
in NumericDatatypes -> {
|
||||
if(value.isBlank()) {
|
||||
require(!dontReinitGlobals)
|
||||
bss = true
|
||||
} else {
|
||||
require(dontReinitGlobals)
|
||||
bss = false
|
||||
initNumeric = parseIRValue(value).toDouble()
|
||||
}
|
||||
}
|
||||
in NumericDatatypes -> initNumeric = parseIRValue(value).toDouble()
|
||||
in ArrayDatatypes -> {
|
||||
if(value.isBlank()) {
|
||||
bss = true
|
||||
initArray = emptyList()
|
||||
} else {
|
||||
bss = false
|
||||
initArray = value.split(',').map {
|
||||
if (it.startsWith('@'))
|
||||
StArrayElement(null, it.drop(1))
|
||||
else
|
||||
StArrayElement(parseIRValue(it).toDouble(), null)
|
||||
}
|
||||
initArray = value.split(',').map {
|
||||
if (it.startsWith('@'))
|
||||
StArrayElement(null, it.drop(1))
|
||||
else
|
||||
StArrayElement(parseIRValue(it).toDouble(), null)
|
||||
}
|
||||
}
|
||||
DataType.STR -> throw IRParseException("STR should have been converted to byte array")
|
||||
else -> throw IRParseException("weird dt")
|
||||
}
|
||||
require(!bss) { "bss var should be in BSS section" }
|
||||
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
|
||||
variables.add(StStaticVariable(name, dt, bss, initNumeric, null, initArray, arraysize, zp, dummyNode))
|
||||
variables.add(StStaticVariable(name, dt, initNumeric, null, initArray, arraysize, zp, dummyNode))
|
||||
}
|
||||
return variables
|
||||
}
|
||||
|
@ -139,14 +139,16 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
|
||||
private fun writeVariables() {
|
||||
|
||||
val (variablesNoInit, variablesWithInit) = irProgram.st.allVariables().partition { it.uninitialized }
|
||||
|
||||
out.write("\n<VARIABLESNOINIT>\n")
|
||||
for (variable in irProgram.st.allVariables().filter { it.bss }) {
|
||||
for (variable in variablesNoInit) {
|
||||
val typeStr = getTypeString(variable)
|
||||
out.write("$typeStr ${variable.name} zp=${variable.zpwish}\n")
|
||||
}
|
||||
|
||||
out.write("</VARIABLESNOINIT>\n<VARIABLESWITHINIT>\n")
|
||||
for (variable in irProgram.st.allVariables().filter { !it.bss }) {
|
||||
for (variable in variablesWithInit) {
|
||||
val typeStr = getTypeString(variable)
|
||||
val value: String = when(variable.dt) {
|
||||
DataType.FLOAT -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
||||
|
@ -75,7 +75,7 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
||||
}
|
||||
scopedName = variable.scopedName
|
||||
val dummyNode = PtVariable(scopedName, variable.dt, variable.zpwish, null, null, variable.astNode.position)
|
||||
varToadd = StStaticVariable(scopedName, variable.dt, variable.bss,
|
||||
varToadd = StStaticVariable(scopedName, variable.dt,
|
||||
variable.onetimeInitializationNumericValue,
|
||||
variable.onetimeInitializationStringValue,
|
||||
fixupAddressOfInArray(variable.onetimeInitializationArrayValue),
|
||||
|
@ -110,7 +110,7 @@ return
|
||||
program.st.allVariables().count() shouldBe 2
|
||||
val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable
|
||||
val var2 = program.st.lookup("sys.bssvar") as StStaticVariable
|
||||
var1.bss shouldBe false
|
||||
var2.bss shouldBe true
|
||||
var1.uninitialized shouldBe false
|
||||
var2.uninitialized shouldBe true
|
||||
}
|
||||
})
|
@ -177,7 +177,7 @@ class VmProgramLoader {
|
||||
var addr = allocations.allocations.getValue(variable.name)
|
||||
|
||||
// zero out uninitialized variables.
|
||||
if(variable.bss) {
|
||||
if(variable.uninitialized) {
|
||||
if(variable.dt in ArrayDatatypes) {
|
||||
repeat(variable.length!!) {
|
||||
when(variable.dt) {
|
||||
@ -222,10 +222,10 @@ class VmProgramLoader {
|
||||
require(variable.length==it.size || it.size==1 || it.size==0)
|
||||
if(it.isEmpty() || it.size==1) {
|
||||
val value = if(it.isEmpty()) {
|
||||
require(variable.bss)
|
||||
require(variable.uninitialized)
|
||||
0.0
|
||||
} else {
|
||||
require(!variable.bss)
|
||||
require(!variable.uninitialized)
|
||||
it[0].number!!
|
||||
}
|
||||
when(variable.dt) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user