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,
|
class StStaticVariable(name: String,
|
||||||
val dt: DataType,
|
val dt: DataType,
|
||||||
val bss: Boolean,
|
|
||||||
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
|
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
|
||||||
val onetimeInitializationStringValue: StString?,
|
val onetimeInitializationStringValue: StString?,
|
||||||
val onetimeInitializationArrayValue: StArray?,
|
val onetimeInitializationArrayValue: StArray?,
|
||||||
@ -155,25 +154,22 @@ class StStaticVariable(name: String,
|
|||||||
val zpwish: ZeropageWish, // used in the variable allocator
|
val zpwish: ZeropageWish, // used in the variable allocator
|
||||||
astNode: PtNode) : StNode(name, StNodeType.STATICVAR, astNode) {
|
astNode: PtNode) : StNode(name, StNodeType.STATICVAR, astNode) {
|
||||||
|
|
||||||
|
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if(bss) {
|
|
||||||
require(onetimeInitializationNumericValue==null)
|
|
||||||
require(onetimeInitializationStringValue==null)
|
|
||||||
require(onetimeInitializationArrayValue.isNullOrEmpty())
|
|
||||||
} else {
|
|
||||||
require(onetimeInitializationNumericValue!=null ||
|
|
||||||
onetimeInitializationStringValue!=null ||
|
|
||||||
onetimeInitializationArrayValue!=null)
|
|
||||||
}
|
|
||||||
if(length!=null) {
|
if(length!=null) {
|
||||||
require(onetimeInitializationNumericValue == null)
|
require(onetimeInitializationNumericValue == null)
|
||||||
if(onetimeInitializationArrayValue!=null)
|
if(onetimeInitializationArrayValue!=null)
|
||||||
require(onetimeInitializationArrayValue.isEmpty() ||onetimeInitializationArrayValue.size==length)
|
require(onetimeInitializationArrayValue.isEmpty() ||onetimeInitializationArrayValue.size==length)
|
||||||
}
|
}
|
||||||
if(onetimeInitializationNumericValue!=null)
|
if(onetimeInitializationNumericValue!=null) {
|
||||||
require(dt in NumericDatatypes)
|
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(dt in ArrayDatatypes)
|
||||||
|
require(onetimeInitializationArrayValue.any { it.number!=0.0} ) { "array of all zerors as init value should just remain uninitialized"}
|
||||||
|
}
|
||||||
if(onetimeInitializationStringValue!=null) {
|
if(onetimeInitializationStringValue!=null) {
|
||||||
require(dt == DataType.STR)
|
require(dt == DataType.STR)
|
||||||
require(length == onetimeInitializationStringValue.first.length+1)
|
require(length == onetimeInitializationStringValue.first.length+1)
|
||||||
|
@ -72,7 +72,8 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
|||||||
val numElements: Int?
|
val numElements: Int?
|
||||||
val value = node.value
|
val value = node.value
|
||||||
if(value!=null) {
|
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) {
|
when (value) {
|
||||||
is PtString -> {
|
is PtString -> {
|
||||||
initialString = StString(value.value, value.encoding)
|
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
|
numElements = value.value.length + 1 // include the terminating 0-byte
|
||||||
}
|
}
|
||||||
is PtArray -> {
|
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
|
initialString = null
|
||||||
numElements = initialArray.size
|
numElements = array.size
|
||||||
require(node.arraySize?.toInt()==numElements)
|
require(node.arraySize?.toInt()==numElements)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@ -97,7 +99,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
|||||||
initialString = null
|
initialString = null
|
||||||
numElements = node.arraySize?.toInt()
|
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 -> {
|
is PtBuiltinFunctionCall -> {
|
||||||
if(node.name=="memory") {
|
if(node.name=="memory") {
|
||||||
|
@ -155,13 +155,6 @@ class PtVariable(name: String, override val type: DataType, val zeropage: Zeropa
|
|||||||
init {
|
init {
|
||||||
value?.let {it.parent=this}
|
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 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 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 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 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 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")
|
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(sub12)
|
||||||
block1.add(StConstant("c1", DataType.UWORD, 12345.0, astConstant1))
|
block1.add(StConstant("c1", DataType.UWORD, 12345.0, astConstant1))
|
||||||
block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2))
|
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("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v1))
|
||||||
sub11.add(StStaticVariable("v2", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2))
|
sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2))
|
||||||
sub12.add(StStaticVariable("v1", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1))
|
sub12.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1))
|
||||||
sub12.add(StStaticVariable("v2", DataType.BYTE, true, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2))
|
sub12.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2))
|
||||||
|
|
||||||
val block2 = StNode("block2", StNodeType.BLOCK, astBlock2)
|
val block2 = StNode("block2", StNodeType.BLOCK, astBlock2)
|
||||||
val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21)
|
val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21)
|
||||||
|
@ -3,15 +3,14 @@ TODO
|
|||||||
|
|
||||||
For next minor release
|
For next minor release
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- fix hasInitValue() and isBssVar()
|
|
||||||
- BSS.
|
- BSS.
|
||||||
64tass can put variables into a section with .section BSS <variable> .send 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
|
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!
|
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.
|
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.
|
- 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!
|
- 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 dt: DataType = parseDatatype(type, arraysize!=null)
|
||||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||||
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
|
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)
|
variables.add(newVar)
|
||||||
}
|
}
|
||||||
return variables
|
return variables
|
||||||
@ -202,40 +202,23 @@ class IRFileReader {
|
|||||||
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
|
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
|
||||||
val dt: DataType = parseDatatype(type, arraysize!=null)
|
val dt: DataType = parseDatatype(type, arraysize!=null)
|
||||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||||
val bss: Boolean
|
|
||||||
var initNumeric: Double? = null
|
var initNumeric: Double? = null
|
||||||
var initArray: StArray? = null
|
var initArray: StArray? = null
|
||||||
when(dt) {
|
when(dt) {
|
||||||
in NumericDatatypes -> {
|
in NumericDatatypes -> initNumeric = parseIRValue(value).toDouble()
|
||||||
if(value.isBlank()) {
|
|
||||||
require(!dontReinitGlobals)
|
|
||||||
bss = true
|
|
||||||
} else {
|
|
||||||
require(dontReinitGlobals)
|
|
||||||
bss = false
|
|
||||||
initNumeric = parseIRValue(value).toDouble()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
in ArrayDatatypes -> {
|
in ArrayDatatypes -> {
|
||||||
if(value.isBlank()) {
|
initArray = value.split(',').map {
|
||||||
bss = true
|
if (it.startsWith('@'))
|
||||||
initArray = emptyList()
|
StArrayElement(null, it.drop(1))
|
||||||
} else {
|
else
|
||||||
bss = false
|
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")
|
DataType.STR -> throw IRParseException("STR should have been converted to byte array")
|
||||||
else -> throw IRParseException("weird dt")
|
else -> throw IRParseException("weird dt")
|
||||||
}
|
}
|
||||||
require(!bss) { "bss var should be in BSS section" }
|
|
||||||
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
|
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
|
return variables
|
||||||
}
|
}
|
||||||
|
@ -139,14 +139,16 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
|
|
||||||
private fun writeVariables() {
|
private fun writeVariables() {
|
||||||
|
|
||||||
|
val (variablesNoInit, variablesWithInit) = irProgram.st.allVariables().partition { it.uninitialized }
|
||||||
|
|
||||||
out.write("\n<VARIABLESNOINIT>\n")
|
out.write("\n<VARIABLESNOINIT>\n")
|
||||||
for (variable in irProgram.st.allVariables().filter { it.bss }) {
|
for (variable in variablesNoInit) {
|
||||||
val typeStr = getTypeString(variable)
|
val typeStr = getTypeString(variable)
|
||||||
out.write("$typeStr ${variable.name} zp=${variable.zpwish}\n")
|
out.write("$typeStr ${variable.name} zp=${variable.zpwish}\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
out.write("</VARIABLESNOINIT>\n<VARIABLESWITHINIT>\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 typeStr = getTypeString(variable)
|
||||||
val value: String = when(variable.dt) {
|
val value: String = when(variable.dt) {
|
||||||
DataType.FLOAT -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
DataType.FLOAT -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
||||||
|
@ -75,7 +75,7 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
|||||||
}
|
}
|
||||||
scopedName = variable.scopedName
|
scopedName = variable.scopedName
|
||||||
val dummyNode = PtVariable(scopedName, variable.dt, variable.zpwish, null, null, variable.astNode.position)
|
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.onetimeInitializationNumericValue,
|
||||||
variable.onetimeInitializationStringValue,
|
variable.onetimeInitializationStringValue,
|
||||||
fixupAddressOfInArray(variable.onetimeInitializationArrayValue),
|
fixupAddressOfInArray(variable.onetimeInitializationArrayValue),
|
||||||
|
@ -110,7 +110,7 @@ return
|
|||||||
program.st.allVariables().count() shouldBe 2
|
program.st.allVariables().count() shouldBe 2
|
||||||
val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable
|
val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable
|
||||||
val var2 = program.st.lookup("sys.bssvar") as StStaticVariable
|
val var2 = program.st.lookup("sys.bssvar") as StStaticVariable
|
||||||
var1.bss shouldBe false
|
var1.uninitialized shouldBe false
|
||||||
var2.bss shouldBe true
|
var2.uninitialized shouldBe true
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -177,7 +177,7 @@ class VmProgramLoader {
|
|||||||
var addr = allocations.allocations.getValue(variable.name)
|
var addr = allocations.allocations.getValue(variable.name)
|
||||||
|
|
||||||
// zero out uninitialized variables.
|
// zero out uninitialized variables.
|
||||||
if(variable.bss) {
|
if(variable.uninitialized) {
|
||||||
if(variable.dt in ArrayDatatypes) {
|
if(variable.dt in ArrayDatatypes) {
|
||||||
repeat(variable.length!!) {
|
repeat(variable.length!!) {
|
||||||
when(variable.dt) {
|
when(variable.dt) {
|
||||||
@ -222,10 +222,10 @@ class VmProgramLoader {
|
|||||||
require(variable.length==it.size || it.size==1 || it.size==0)
|
require(variable.length==it.size || it.size==1 || it.size==0)
|
||||||
if(it.isEmpty() || it.size==1) {
|
if(it.isEmpty() || it.size==1) {
|
||||||
val value = if(it.isEmpty()) {
|
val value = if(it.isEmpty()) {
|
||||||
require(variable.bss)
|
require(variable.uninitialized)
|
||||||
0.0
|
0.0
|
||||||
} else {
|
} else {
|
||||||
require(!variable.bss)
|
require(!variable.uninitialized)
|
||||||
it[0].number!!
|
it[0].number!!
|
||||||
}
|
}
|
||||||
when(variable.dt) {
|
when(variable.dt) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user