mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 01:49:22 +00:00
more tests and some cleanups/fixes
This commit is contained in:
parent
759babb4c1
commit
8f5d42dbc2
@ -55,19 +55,17 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||
}
|
||||
}
|
||||
|
||||
infix fun isSameAs(target: PtAssignTarget): Boolean {
|
||||
return when {
|
||||
target.memory != null && this is PtMemoryByte-> {
|
||||
target.memory!!.address isSameAs this.address
|
||||
}
|
||||
target.identifier != null && this is PtIdentifier -> {
|
||||
this.name == target.identifier!!.name
|
||||
}
|
||||
target.array != null && this is PtArrayIndexer -> {
|
||||
this.variable.name == target.array!!.variable.name && this.index isSameAs target.array!!.index && this.splitWords==target.array!!.splitWords
|
||||
}
|
||||
else -> false
|
||||
infix fun isSameAs(target: PtAssignTarget): Boolean = when {
|
||||
target.memory != null && this is PtMemoryByte -> {
|
||||
target.memory!!.address isSameAs this.address
|
||||
}
|
||||
target.identifier != null && this is PtIdentifier -> {
|
||||
this.name == target.identifier!!.name
|
||||
}
|
||||
target.array != null && this is PtArrayIndexer -> {
|
||||
this.variable.name == target.array!!.variable.name && this.index isSameAs target.array!!.index && this.splitWords==target.array!!.splitWords
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun asConstInteger(): Int? = (this as? PtNumber)?.number?.toInt() ?: (this as? PtBool)?.asInt()
|
||||
|
@ -149,7 +149,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
else {
|
||||
// normal array to array copy, various element types
|
||||
val eltsize = asmgen.options.compTarget.memorySize(source.type.sub!!) // TODO test this!
|
||||
val eltsize = asmgen.options.compTarget.memorySize(source.type.sub!!)
|
||||
val numBytes = numElements * eltsize
|
||||
asmgen.out("""
|
||||
lda #<${sourceAsm}
|
||||
|
@ -604,19 +604,20 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
|
||||
private fun uninitializedVariable2asm(variable: StStaticVariable) {
|
||||
val dt = variable.dt
|
||||
when {
|
||||
variable.dt.isBool || variable.dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ?")
|
||||
variable.dt.isSignedByte -> asmgen.out("${variable.name}\t.char ?")
|
||||
variable.dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ?")
|
||||
variable.dt.isSignedWord -> asmgen.out("${variable.name}\t.sint ?")
|
||||
variable.dt.isFloat -> asmgen.out("${variable.name}\t.fill ${compTarget.machine.FLOAT_MEM_SIZE}")
|
||||
variable.dt.isSplitWordArray -> {
|
||||
val numbytesPerHalf = compTarget.memorySize(variable.dt, variable.length!!) / 2
|
||||
dt.isBool || dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ?")
|
||||
dt.isSignedByte -> asmgen.out("${variable.name}\t.char ?")
|
||||
dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ?")
|
||||
dt.isSignedWord -> asmgen.out("${variable.name}\t.sint ?")
|
||||
dt.isFloat -> asmgen.out("${variable.name}\t.fill ${compTarget.machine.FLOAT_MEM_SIZE}")
|
||||
dt.isSplitWordArray -> {
|
||||
val numbytesPerHalf = compTarget.memorySize(dt, variable.length!!) / 2
|
||||
asmgen.out("${variable.name}_lsb\t.fill $numbytesPerHalf")
|
||||
asmgen.out("${variable.name}_msb\t.fill $numbytesPerHalf")
|
||||
}
|
||||
variable.dt.isArray -> {
|
||||
val numbytes = compTarget.memorySize(variable.dt, variable.length!!)
|
||||
dt.isArray -> {
|
||||
val numbytes = compTarget.memorySize(dt, variable.length!!)
|
||||
asmgen.out("${variable.name}\t.fill $numbytes")
|
||||
}
|
||||
else -> {
|
||||
@ -634,12 +635,13 @@ internal class ProgramAndVarsGen(
|
||||
variable.onetimeInitializationNumericValue!!.toInt()
|
||||
} else 0
|
||||
|
||||
val dt=variable.dt
|
||||
when {
|
||||
variable.dt.isBool || variable.dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
|
||||
variable.dt.isSignedByte -> asmgen.out("${variable.name}\t.char $initialValue")
|
||||
variable.dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
|
||||
variable.dt.isSignedWord -> asmgen.out("${variable.name}\t.sint $initialValue")
|
||||
variable.dt.isFloat -> {
|
||||
dt.isBool || dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
|
||||
dt.isSignedByte -> asmgen.out("${variable.name}\t.char $initialValue")
|
||||
dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
|
||||
dt.isSignedWord -> asmgen.out("${variable.name}\t.sint $initialValue")
|
||||
dt.isFloat -> {
|
||||
if(initialValue==0) {
|
||||
asmgen.out("${variable.name}\t.byte 0,0,0,0,0 ; float")
|
||||
} else {
|
||||
@ -647,10 +649,10 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("${variable.name}\t.byte $floatFill ; float $initialValue")
|
||||
}
|
||||
}
|
||||
variable.dt.isString -> {
|
||||
dt.isString -> {
|
||||
throw AssemblyError("all string vars should have been interned into prog")
|
||||
}
|
||||
variable.dt.isArray -> arrayVariable2asm(variable.name, variable.dt, variable.onetimeInitializationArrayValue, variable.length)
|
||||
dt.isArray -> arrayVariable2asm(variable.name, dt, variable.onetimeInitializationArrayValue, variable.length)
|
||||
else -> {
|
||||
throw AssemblyError("weird dt")
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
else {
|
||||
// normal array to array copy (various element types)
|
||||
val eltsize = codeGen.options.compTarget.memorySize(source.type.sub!!) // TODO test this!
|
||||
val eltsize = codeGen.options.compTarget.memorySize(source.type.sub!!)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=fromReg, labelSymbol = source.name)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=toReg, labelSymbol = target.name)
|
||||
@ -583,8 +583,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
if(arr!=null && index!=null) {
|
||||
if(arr.splitWords) TODO("IR rol/ror on split words array")
|
||||
val variable = arr.variable.name
|
||||
val itemsize = codeGen.program.memsizer.memorySize(arr.type.sub!!) // TODO test this!
|
||||
addInstr(result, IRInstruction(opcodeMemAndReg.first, vmDt, labelSymbol = variable, symbolOffset = index*itemsize), null)
|
||||
val offset = codeGen.program.memsizer.memorySize(arr.type, index)
|
||||
addInstr(result, IRInstruction(opcodeMemAndReg.first, vmDt, labelSymbol = variable, symbolOffset = offset), null)
|
||||
return ExpressionCodeResult(result, vmDt, -1, -1)
|
||||
}
|
||||
|
||||
@ -669,7 +669,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
else {
|
||||
val eltSize = codeGen.program.memsizer.memorySize(target.type.sub!!) // TODO test this!
|
||||
val eltSize = codeGen.program.memsizer.memorySize(target.type, null)
|
||||
val constIndex = target.index.asConstInteger()
|
||||
if(isConstZeroValue) {
|
||||
if(constIndex!=null) {
|
||||
|
@ -317,18 +317,19 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, tr.resultReg, tr.resultFpReg)
|
||||
var actualResultReg2 = -1
|
||||
var actualResultFpReg2 = -1
|
||||
val valueDt = cast.value.type
|
||||
when(cast.type.dt) {
|
||||
BaseDataType.BOOL -> {
|
||||
when {
|
||||
cast.value.type.isByte -> {
|
||||
valueDt.isByte -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.SNZ, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg), null)
|
||||
}
|
||||
cast.value.type.isWord -> {
|
||||
valueDt.isWord -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.SNZ, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg), null)
|
||||
}
|
||||
cast.value.type.isFloat -> {
|
||||
valueDt.isFloat -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SGN, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg)
|
||||
@ -339,7 +340,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
BaseDataType.UBYTE -> {
|
||||
when(cast.value.type.dt) {
|
||||
when(valueDt.dt) {
|
||||
BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||
actualResultReg2 = tr.resultReg // just keep the LSB as it is
|
||||
}
|
||||
@ -351,7 +352,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
BaseDataType.BYTE -> {
|
||||
when(cast.value.type.dt) {
|
||||
when(valueDt.dt) {
|
||||
BaseDataType.BOOL, BaseDataType.UBYTE, BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||
actualResultReg2 = tr.resultReg // just keep the LSB as it is
|
||||
}
|
||||
@ -363,7 +364,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
BaseDataType.UWORD -> {
|
||||
when(cast.value.type.dt) {
|
||||
when(valueDt.dt) {
|
||||
BaseDataType.BYTE -> {
|
||||
// byte -> uword: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
@ -385,7 +386,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
BaseDataType.WORD -> {
|
||||
when(cast.value.type.dt) {
|
||||
when(valueDt.dt) {
|
||||
BaseDataType.BYTE -> {
|
||||
// byte -> word: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
@ -408,7 +409,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultFpReg2 = codeGen.registers.nextFreeFloat()
|
||||
when(cast.value.type.dt) {
|
||||
when(valueDt.dt) {
|
||||
BaseDataType.BOOL, BaseDataType.UBYTE -> {
|
||||
addInstr(result, IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=tr.resultReg, fpReg1 = actualResultFpReg2), null)
|
||||
}
|
||||
|
@ -400,8 +400,9 @@ internal class ConstantIdentifierReplacer(
|
||||
|
||||
// convert the initializer range expression from a range or int, to an actual array.
|
||||
// this is to allow initialization of arrays with a single value like ubyte[10] array = 42
|
||||
val dt = decl.datatype
|
||||
when {
|
||||
decl.datatype.isUnsignedByteArray || decl.datatype.isSignedByteArray || decl.datatype.isUnsignedWordArray || decl.datatype.isSignedWordArray -> {
|
||||
dt.isUnsignedByteArray || dt.isSignedByteArray || dt.isUnsignedWordArray || dt.isSignedWordArray -> {
|
||||
val rangeExpr = decl.value as? RangeExpression
|
||||
if(rangeExpr!=null) {
|
||||
val constRange = rangeExpr.toConstantIntegerRange()
|
||||
@ -417,12 +418,12 @@ internal class ConstantIdentifierReplacer(
|
||||
if(constRange!=null) {
|
||||
val rangeType = rangeExpr.inferType(program).getOr(DataType.forDt(BaseDataType.UBYTE))
|
||||
return if(rangeType.isByte) {
|
||||
ArrayLiteral(InferredTypes.InferredType.known(decl.datatype),
|
||||
ArrayLiteral(InferredTypes.InferredType.known(dt),
|
||||
constRange.map { NumericLiteral(rangeType.dt, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
||||
position = decl.value!!.position)
|
||||
} else {
|
||||
require(rangeType.sub!=null)
|
||||
ArrayLiteral(InferredTypes.InferredType.known(decl.datatype),
|
||||
ArrayLiteral(InferredTypes.InferredType.known(dt),
|
||||
constRange.map { NumericLiteral(rangeType.sub!!.dt, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
||||
position = decl.value!!.position)
|
||||
}
|
||||
@ -436,30 +437,30 @@ internal class ConstantIdentifierReplacer(
|
||||
// arraysize initializer is empty or a single int, and we know the size; create the arraysize.
|
||||
val fillvalue = numericLv.number.toInt()
|
||||
when {
|
||||
decl.datatype.isUnsignedByteArray -> {
|
||||
dt.isUnsignedByteArray -> {
|
||||
if(fillvalue !in 0..255)
|
||||
errors.err("ubyte value overflow", numericLv.position)
|
||||
}
|
||||
decl.datatype.isSignedByteArray -> {
|
||||
dt.isSignedByteArray -> {
|
||||
if(fillvalue !in -128..127)
|
||||
errors.err("byte value overflow", numericLv.position)
|
||||
}
|
||||
decl.datatype.isUnsignedWordArray -> {
|
||||
dt.isUnsignedWordArray -> {
|
||||
if(fillvalue !in 0..65535)
|
||||
errors.err("uword value overflow", numericLv.position)
|
||||
}
|
||||
decl.datatype.isSignedWordArray -> {
|
||||
dt.isSignedWordArray -> {
|
||||
if(fillvalue !in -32768..32767)
|
||||
errors.err("word value overflow", numericLv.position)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
// create the array itself, filled with the fillvalue.
|
||||
val array = Array(size) {fillvalue}.map { NumericLiteral(decl.datatype.elementType().dt, it.toDouble(), numericLv.position) }.toTypedArray<Expression>()
|
||||
return ArrayLiteral(InferredTypes.InferredType.known(decl.datatype), array, position = numericLv.position)
|
||||
val array = Array(size) {fillvalue}.map { NumericLiteral(dt.elementType().dt, it.toDouble(), numericLv.position) }.toTypedArray<Expression>()
|
||||
return ArrayLiteral(InferredTypes.InferredType.known(dt), array, position = numericLv.position)
|
||||
}
|
||||
}
|
||||
decl.datatype.isFloatArray -> {
|
||||
dt.isFloatArray -> {
|
||||
val rangeExpr = decl.value as? RangeExpression
|
||||
if(rangeExpr!=null) {
|
||||
// convert the initializer range expression to an actual array of floats
|
||||
@ -487,7 +488,7 @@ internal class ConstantIdentifierReplacer(
|
||||
}
|
||||
}
|
||||
}
|
||||
decl.datatype.isBoolArray -> {
|
||||
dt.isBoolArray -> {
|
||||
val size = decl.arraysize?.constIndex() ?: return null
|
||||
val numericLv = decl.value as? NumericLiteral
|
||||
if(numericLv!=null) {
|
||||
|
@ -742,17 +742,18 @@ internal class AstChecker(private val program: Program,
|
||||
val arraysize = decl.arraysize
|
||||
if(arraysize!=null) {
|
||||
val arraySize = arraysize.constIndex() ?: 1
|
||||
val dt = decl.datatype
|
||||
when {
|
||||
decl.datatype.isString || decl.datatype.isByteArray || decl.datatype.isBoolArray ->
|
||||
dt.isString || dt.isByteArray || dt.isBoolArray ->
|
||||
if(arraySize > 256)
|
||||
err("byte array length must be 1-256")
|
||||
decl.datatype.isSplitWordArray ->
|
||||
dt.isSplitWordArray ->
|
||||
if(arraySize > 256)
|
||||
err("split word array length must be 1-256")
|
||||
decl.datatype.isWordArray ->
|
||||
dt.isWordArray ->
|
||||
if(arraySize > 128)
|
||||
err("word array length must be 1-128")
|
||||
decl.datatype.isFloatArray ->
|
||||
dt.isFloatArray ->
|
||||
if(arraySize > 51)
|
||||
err("float array length must be 1-51")
|
||||
else -> {}
|
||||
|
@ -137,16 +137,16 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
if(isMultiComparisonRecurse(leftBinExpr1)) {
|
||||
val elementType = needle.inferType(program).getOrElse { throw FatalAstException("invalid needle dt") }
|
||||
require(elementType.isNumericOrBool)
|
||||
if(values.size==2 || values.size==3 && elementType in IntegerDatatypes) {
|
||||
if(values.size==2 || values.size==3 && elementType.isInteger) {
|
||||
val numbers = values.map{it.number}.toSet()
|
||||
if(numbers == setOf(0.0, 1.0)) {
|
||||
// we can replace x==0 or x==1 with x<2
|
||||
val compare = BinaryExpression(needle, "<", NumericLiteral(elementType, 2.0, expr.position), expr.position)
|
||||
val compare = BinaryExpression(needle, "<", NumericLiteral(elementType.dt, 2.0, expr.position), expr.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, compare, parent))
|
||||
}
|
||||
if(numbers == setOf(0.0, 1.0, 2.0)) {
|
||||
// we can replace x==0 or x==1 or x==2 with x<3
|
||||
val compare = BinaryExpression(needle, "<", NumericLiteral(elementType, 3.0, expr.position), expr.position)
|
||||
val compare = BinaryExpression(needle, "<", NumericLiteral(elementType.dt, 3.0, expr.position), expr.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, compare, parent))
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import io.kotest.matchers.types.instanceOf
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.code.ast.PtArray
|
||||
import prog8.code.ast.PtVariable
|
||||
import prog8.code.core.BaseDataType
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Position
|
||||
@ -692,5 +694,36 @@ main {
|
||||
DataType.arrayFor(BaseDataType.UWORD, true).isArray shouldBe true
|
||||
DataType.arrayFor(BaseDataType.UWORD, true).isSplitWordArray shouldBe true
|
||||
}
|
||||
|
||||
test("array of strings becomes array of uword pointers") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
str variable = "name1"
|
||||
str[2] @shared names = [ variable, "name2" ]
|
||||
}
|
||||
}"""
|
||||
|
||||
val result = compileText(C64Target(), false, src, writeAssembly = true)
|
||||
result shouldNotBe null
|
||||
|
||||
val st1 = result!!.compilerAst.entrypoint.statements
|
||||
st1.size shouldBe 3
|
||||
st1[0] shouldBe instanceOf<VarDecl>()
|
||||
st1[1] shouldBe instanceOf<VarDecl>()
|
||||
(st1[0] as VarDecl).name shouldBe "variable"
|
||||
(st1[1] as VarDecl).name shouldBe "names"
|
||||
val array1 = (st1[1] as VarDecl).value as ArrayLiteral
|
||||
array1.type.isArray shouldBe true
|
||||
array1.type.getOrUndef() shouldBe DataType.arrayFor(BaseDataType.UWORD, false)
|
||||
|
||||
val ast2 = result.codegenAst!!
|
||||
val st2 = ast2.entrypoint()!!.children
|
||||
st2.size shouldBe 3
|
||||
(st2[0] as PtVariable).name shouldBe "p8v_variable"
|
||||
(st2[1] as PtVariable).name shouldBe "p8v_names"
|
||||
val array2 = (st2[1] as PtVariable).value as PtArray
|
||||
array2.type shouldBe DataType.arrayFor(BaseDataType.UWORD, false)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,15 +1,27 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
add array of strings test that it becomes an array of uword pointers
|
||||
replace some when { xxx.isWord... } with (when xxx.dt) { UWORD -> ...} again
|
||||
Main branch: IR funcRolRor: add this: if(arr.splitWords) TODO("rol/ror on split words array")
|
||||
Main branch: possible optimization for: if x < 2/ x<1 -> if x==0 or x==1 likewise for > 253/ >254
|
||||
Main branch: fix IR/VM problem with containment check:
|
||||
main {
|
||||
sub start() {
|
||||
ubyte @shared x
|
||||
|
||||
Extra CHECKS/Unit tests:
|
||||
codegens: check array copy (elt size)
|
||||
check: try to replace a multi-comparison expression (if x==1 | x==2 | x==3 ... ) by a simple containment check.
|
||||
IR: check for loop over split word array
|
||||
IR: check rol ror in array (elt size)
|
||||
IR: check set lsb/msb in array (elt size)
|
||||
x=3
|
||||
if x==1 or x==2 or x==3 or x==4
|
||||
txt.print("yep1\n")
|
||||
|
||||
x = 9
|
||||
if x==1 or x==2 or x==3 or x==4
|
||||
txt.print("yep2-shouldn't-see-this\n") ; TODO fix this in IR/VM
|
||||
|
||||
if x in 1 to 4
|
||||
txt.print("yep3-shouldn't-see-this\n")
|
||||
if x in 4 to 10
|
||||
txt.print("yep4\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Improve register load order in subroutine call args assignments:
|
||||
|
@ -4,16 +4,26 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
str name1 = "name1"
|
||||
str name2 = "name2"
|
||||
uword[] @split names = [name1, name2, "name3"]
|
||||
txt.print(names[2])
|
||||
uword[2] array = [$1111,$eeee]
|
||||
uword[2] @split sarray = [$1111,$eeee]
|
||||
|
||||
;uword[] @split names2 = [name1, name2, "name3"]
|
||||
;uword[] addresses = [0,0,0]
|
||||
;names = [1111,2222,3333]
|
||||
;addresses = names
|
||||
;names = addresses
|
||||
;names2 = names
|
||||
txt.print_uwhex(array[1], true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(sarray[1], true)
|
||||
txt.nl()
|
||||
|
||||
setmsb(array[1], $55)
|
||||
setmsb(sarray[1], $55)
|
||||
txt.print_uwhex(array[1], true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(sarray[1], true)
|
||||
txt.nl()
|
||||
|
||||
setlsb(array[1], $44)
|
||||
setlsb(sarray[1], $44)
|
||||
txt.print_uwhex(array[1], true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(sarray[1], true)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
@ -249,22 +249,23 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb=$lsbValue zp=${variable.zpwish}\n")
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_msb=$msbValue zp=${variable.zpwish}\n")
|
||||
} else {
|
||||
val dt = variable.dt
|
||||
val value: String = when {
|
||||
variable.dt.isBool -> variable.onetimeInitializationNumericValue?.toInt()?.toString() ?: ""
|
||||
variable.dt.isFloat -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
||||
variable.dt.isNumeric -> variable.onetimeInitializationNumericValue?.toInt()?.toHex() ?: ""
|
||||
variable.dt.isString -> {
|
||||
dt.isBool -> variable.onetimeInitializationNumericValue?.toInt()?.toString() ?: ""
|
||||
dt.isFloat -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
||||
dt.isNumeric -> variable.onetimeInitializationNumericValue?.toInt()?.toHex() ?: ""
|
||||
dt.isString -> {
|
||||
val encoded = irProgram.encoding.encodeString(variable.onetimeInitializationStringValue!!.first, variable.onetimeInitializationStringValue.second) + listOf(0u)
|
||||
encoded.joinToString(",") { it.toInt().toString() }
|
||||
}
|
||||
variable.dt.isFloatArray -> {
|
||||
dt.isFloatArray -> {
|
||||
if(variable.onetimeInitializationArrayValue!=null) {
|
||||
variable.onetimeInitializationArrayValue.joinToString(",") { it.number!!.toString() }
|
||||
} else {
|
||||
"" // array will be zero'd out at program start
|
||||
}
|
||||
}
|
||||
variable.dt.isArray -> {
|
||||
dt.isArray -> {
|
||||
if(variable.onetimeInitializationArrayValue!==null) {
|
||||
variable.onetimeInitializationArrayValue.joinToString(",") {
|
||||
if(it.number!=null)
|
||||
|
@ -199,23 +199,24 @@ class VmProgramLoader {
|
||||
// zero out uninitialized ('bss') variables.
|
||||
if(variable.uninitialized) {
|
||||
if(variable.dt.isArray) {
|
||||
val dt = variable.dt
|
||||
repeat(variable.length!!) {
|
||||
when {
|
||||
variable.dt.isString || variable.dt.isBoolArray || variable.dt.isByteArray -> {
|
||||
dt.isString || dt.isBoolArray || dt.isByteArray -> {
|
||||
memory.setUB(addr, 0u)
|
||||
addr++
|
||||
}
|
||||
variable.dt.isSplitWordArray -> {
|
||||
dt.isSplitWordArray -> {
|
||||
// lo bytes come after the hi bytes
|
||||
memory.setUB(addr, 0u)
|
||||
memory.setUB(addr+variable.length!!, 0u)
|
||||
addr++
|
||||
}
|
||||
variable.dt.isWordArray -> {
|
||||
dt.isWordArray -> {
|
||||
memory.setUW(addr, 0u)
|
||||
addr += 2
|
||||
}
|
||||
variable.dt.isFloatArray -> {
|
||||
dt.isFloatArray -> {
|
||||
memory.setFloat(addr, 0.0)
|
||||
addr += program.options.compTarget.machine.FLOAT_MEM_SIZE
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user