mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 04:17:16 +00:00
adding long arrays
This commit is contained in:
@@ -145,7 +145,7 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
|
|||||||
return if(splitwordarray && actualElementDt.isWord)
|
return if(splitwordarray && actualElementDt.isWord)
|
||||||
DataType(BaseDataType.ARRAY_SPLITW, actualElementDt, null)
|
DataType(BaseDataType.ARRAY_SPLITW, actualElementDt, null)
|
||||||
else {
|
else {
|
||||||
if(actualElementDt.isNumericOrBool && actualElementDt != BaseDataType.LONG)
|
if(actualElementDt.isNumericOrBool)
|
||||||
DataType(BaseDataType.ARRAY, actualElementDt, null)
|
DataType(BaseDataType.ARRAY, actualElementDt, null)
|
||||||
else
|
else
|
||||||
throw NoSuchElementException("invalid basic element dt $elementDt")
|
throw NoSuchElementException("invalid basic element dt $elementDt")
|
||||||
@@ -224,6 +224,7 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
|
|||||||
BaseDataType.WORD -> "word[]"
|
BaseDataType.WORD -> "word[]"
|
||||||
BaseDataType.UBYTE -> "ubyte[]"
|
BaseDataType.UBYTE -> "ubyte[]"
|
||||||
BaseDataType.UWORD -> "uword[]"
|
BaseDataType.UWORD -> "uword[]"
|
||||||
|
BaseDataType.LONG -> "long[]"
|
||||||
else -> throw IllegalArgumentException("invalid sub type")
|
else -> throw IllegalArgumentException("invalid sub type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,6 +287,7 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
|
|||||||
BaseDataType.BOOL -> "bool["
|
BaseDataType.BOOL -> "bool["
|
||||||
BaseDataType.BYTE -> "byte["
|
BaseDataType.BYTE -> "byte["
|
||||||
BaseDataType.WORD -> "@nosplit word["
|
BaseDataType.WORD -> "@nosplit word["
|
||||||
|
BaseDataType.LONG -> "long["
|
||||||
BaseDataType.FLOAT -> "float["
|
BaseDataType.FLOAT -> "float["
|
||||||
else -> throw IllegalArgumentException("invalid sub type")
|
else -> throw IllegalArgumentException("invalid sub type")
|
||||||
}
|
}
|
||||||
@@ -365,6 +367,7 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
|
|||||||
val isWordArray = base.isArray && !base.isPointerArray && (sub == BaseDataType.UWORD || sub == BaseDataType.WORD)
|
val isWordArray = base.isArray && !base.isPointerArray && (sub == BaseDataType.UWORD || sub == BaseDataType.WORD)
|
||||||
val isUnsignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.UWORD
|
val isUnsignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.UWORD
|
||||||
val isSignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.WORD
|
val isSignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.WORD
|
||||||
|
val isLongArray = base.isArray && sub == BaseDataType.LONG
|
||||||
val isFloatArray = base.isArray && !base.isPointerArray && sub == BaseDataType.FLOAT
|
val isFloatArray = base.isArray && !base.isPointerArray && sub == BaseDataType.FLOAT
|
||||||
val isString = base == BaseDataType.STR
|
val isString = base == BaseDataType.STR
|
||||||
val isBool = base == BaseDataType.BOOL
|
val isBool = base == BaseDataType.BOOL
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
val sscope = fcall.definingISub()
|
val sscope = fcall.definingISub()
|
||||||
|
|
||||||
when (fcall.name) {
|
when (fcall.name) {
|
||||||
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
|
"msw" -> funcMsw(fcall, resultRegister)
|
||||||
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
|
"lsw" -> funcLsw(fcall, resultRegister)
|
||||||
"msb" -> funcMsb(fcall, resultRegister)
|
"msb" -> funcMsb(fcall, resultRegister)
|
||||||
"lsb" -> funcLsb(fcall, resultRegister)
|
"lsb" -> funcLsb(fcall, resultRegister)
|
||||||
"mkword" -> funcMkword(fcall, resultRegister)
|
"mkword" -> funcMkword(fcall, resultRegister)
|
||||||
@@ -1185,7 +1185,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
private fun funcMsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
private fun funcMsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
val arg = fcall.args.single()
|
val arg = fcall.args.single()
|
||||||
if (!arg.type.isWord)
|
if (!arg.type.isWord)
|
||||||
throw AssemblyError("msb required word argument")
|
throw AssemblyError("msb requires word argument")
|
||||||
if (arg is PtNumber)
|
if (arg is PtNumber)
|
||||||
throw AssemblyError("msb(const) should have been const-folded away")
|
throw AssemblyError("msb(const) should have been const-folded away")
|
||||||
if (arg is PtIdentifier) {
|
if (arg is PtIdentifier) {
|
||||||
@@ -1371,6 +1371,53 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcMsw(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
|
val arg = fcall.args.single()
|
||||||
|
if (!arg.type.isLong)
|
||||||
|
throw AssemblyError("msw requires long argument")
|
||||||
|
if (arg is PtNumber)
|
||||||
|
throw AssemblyError("msw(const) should have been const-folded away")
|
||||||
|
if (arg is PtIdentifier) {
|
||||||
|
val sourceName = asmgen.asmVariableName(arg)
|
||||||
|
when(resultRegister) {
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" lda $sourceName+2 | ldx $sourceName+3")
|
||||||
|
null, RegisterOrPair.AY -> asmgen.out(" lda $sourceName+2 | ldy $sourceName+3")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName+2 | ldy $sourceName+3")
|
||||||
|
in Cx16VirtualRegisters -> {
|
||||||
|
val regname = resultRegister.name.lowercase()
|
||||||
|
asmgen.out(" lda $sourceName+2 | sta cx16.$regname | lda $sourceName+3 | sta cx16.$regname+1")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("invalid reg")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TODO("msw(expression) ${fcall.position} - use a temporary variable for now")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcLsw(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
|
val arg = fcall.args.single()
|
||||||
|
if (!arg.type.isLong)
|
||||||
|
throw AssemblyError("lsw requires long argument")
|
||||||
|
if (arg is PtNumber)
|
||||||
|
throw AssemblyError("lsw(const) should have been const-folded away")
|
||||||
|
if (arg is PtIdentifier) {
|
||||||
|
val sourceName = asmgen.asmVariableName(arg)
|
||||||
|
when(resultRegister) {
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx $sourceName+1")
|
||||||
|
null, RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy $sourceName+1")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy $sourceName+1")
|
||||||
|
in Cx16VirtualRegisters -> {
|
||||||
|
val regname = resultRegister.name.lowercase()
|
||||||
|
asmgen.out(" lda $sourceName | sta cx16.$regname | lda $sourceName+1 | sta cx16.$regname+1")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("invalid reg")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TODO("lsw(expression) ${fcall.position} - use a temporary variable for now")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private fun translateArguments(call: PtBuiltinFunctionCall, scope: IPtSubroutine?) {
|
private fun translateArguments(call: PtBuiltinFunctionCall, scope: IPtSubroutine?) {
|
||||||
val signature = BuiltinFunctions.getValue(call.name)
|
val signature = BuiltinFunctions.getValue(call.name)
|
||||||
val callConv = signature.callConvention(call.args.map {
|
val callConv = signature.callConvention(call.args.map {
|
||||||
|
|||||||
@@ -505,137 +505,158 @@ $endLabel""")
|
|||||||
is StMemVar -> symbol.length!!
|
is StMemVar -> symbol.length!!
|
||||||
else -> 0u
|
else -> 0u
|
||||||
}
|
}
|
||||||
when {
|
|
||||||
iterableDt.isString -> {
|
fun iterateStrings() {
|
||||||
if(asmgen.options.romable) {
|
if(asmgen.options.romable) {
|
||||||
val indexVar = asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
val indexVar = asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
sty $indexVar
|
sty $indexVar
|
||||||
$loopLabel lda $iterableName,y
|
$loopLabel lda $iterableName,y
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
||||||
asmgen.translate(stmt.statements)
|
asmgen.translate(stmt.statements)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inc $indexVar
|
inc $indexVar
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
} else {
|
} else {
|
||||||
val indexVar = asmgen.makeLabel("for_index")
|
val indexVar = asmgen.makeLabel("for_index")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
sty $indexVar
|
sty $indexVar
|
||||||
$loopLabel lda $iterableName,y
|
$loopLabel lda $iterableName,y
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
||||||
asmgen.translate(stmt.statements)
|
asmgen.translate(stmt.statements)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inc $indexVar
|
inc $indexVar
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
$indexVar .byte 0
|
$indexVar .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
iterableDt.isByteArray || iterableDt.isBoolArray -> {
|
}
|
||||||
val indexVar = if(asmgen.options.romable)
|
|
||||||
asmgen.createTempVarReused(iterableDt.elementType().base, false, stmt)
|
fun iterateBytes() {
|
||||||
else
|
val indexVar = if(asmgen.options.romable)
|
||||||
asmgen.makeLabel("for_index")
|
asmgen.createTempVarReused(iterableDt.elementType().base, false, stmt)
|
||||||
asmgen.out("""
|
else
|
||||||
|
asmgen.makeLabel("for_index")
|
||||||
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
$loopLabel sty $indexVar
|
$loopLabel sty $indexVar
|
||||||
lda $iterableName,y
|
lda $iterableName,y
|
||||||
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
||||||
asmgen.translate(stmt.statements)
|
asmgen.translate(stmt.statements)
|
||||||
if(numElements<=255u) {
|
if(numElements<=255u) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
cpy #$numElements
|
cpy #$numElements
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
bne $loopLabel""")
|
bne $loopLabel""")
|
||||||
} else {
|
} else {
|
||||||
// length is 256
|
// length is 256
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
}
|
|
||||||
if(!asmgen.options.romable) {
|
|
||||||
if(numElements>=16u) {
|
|
||||||
// allocate index var on ZP if possible, otherwise inline
|
|
||||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
|
||||||
result.fold(
|
|
||||||
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
|
||||||
failure = { asmgen.out("$indexVar .byte 0") }
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
asmgen.out("$indexVar .byte 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
asmgen.out(endLabel)
|
|
||||||
}
|
}
|
||||||
iterableDt.isSplitWordArray -> {
|
if(!asmgen.options.romable) {
|
||||||
val indexVar = if(asmgen.options.romable)
|
if(numElements>=16u) {
|
||||||
asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
// allocate index var on ZP if possible, otherwise inline
|
||||||
else
|
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
asmgen.makeLabel("for_index")
|
result.fold(
|
||||||
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||||
asmgen.out("""
|
failure = { asmgen.out("$indexVar .byte 0") }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
asmgen.out("$indexVar .byte 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asmgen.out(endLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun iterateSplitWords() {
|
||||||
|
val indexVar = if(asmgen.options.romable)
|
||||||
|
asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
||||||
|
else
|
||||||
|
asmgen.makeLabel("for_index")
|
||||||
|
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
||||||
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
$loopLabel sty $indexVar
|
$loopLabel sty $indexVar
|
||||||
lda ${iterableName}_lsb,y
|
lda ${iterableName}_lsb,y
|
||||||
sta $loopvarName
|
sta $loopvarName
|
||||||
lda ${iterableName}_msb,y
|
lda ${iterableName}_msb,y
|
||||||
sta $loopvarName+1""")
|
sta $loopvarName+1""")
|
||||||
asmgen.translate(stmt.statements)
|
asmgen.translate(stmt.statements)
|
||||||
if(numElements<=255u) {
|
if(numElements<=255u) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
cpy #$numElements
|
cpy #$numElements
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
bne $loopLabel""")
|
bne $loopLabel""")
|
||||||
} else {
|
} else {
|
||||||
// length is 256
|
// length is 256
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
}
|
|
||||||
if(!asmgen.options.romable) {
|
|
||||||
if(numElements>=16u) {
|
|
||||||
// allocate index var on ZP if possible, otherwise inline
|
|
||||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
|
||||||
result.fold(
|
|
||||||
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
|
||||||
failure = { asmgen.out("$indexVar .byte 0") }
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
asmgen.out("$indexVar .byte 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
asmgen.out(endLabel)
|
|
||||||
}
|
}
|
||||||
iterableDt.isWordArray -> {
|
if(!asmgen.options.romable) {
|
||||||
val indexVar = if(asmgen.options.romable)
|
if(numElements>=16u) {
|
||||||
asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
// allocate index var on ZP if possible, otherwise inline
|
||||||
else
|
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
asmgen.makeLabel("for_index")
|
result.fold(
|
||||||
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||||
asmgen.out("""
|
failure = { asmgen.out("$indexVar .byte 0") }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
asmgen.out("$indexVar .byte 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asmgen.out(endLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun iterateWords(actuallyLongs: Boolean = false) {
|
||||||
|
val indexVar = if(asmgen.options.romable)
|
||||||
|
asmgen.createTempVarReused(BaseDataType.UBYTE, false, stmt)
|
||||||
|
else
|
||||||
|
asmgen.makeLabel("for_index")
|
||||||
|
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
||||||
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
$loopLabel sty $indexVar
|
$loopLabel sty $indexVar
|
||||||
lda $iterableName,y
|
lda $iterableName,y
|
||||||
sta $loopvarName
|
sta $loopvarName
|
||||||
lda $iterableName+1,y
|
lda $iterableName+1,y
|
||||||
sta $loopvarName+1""")
|
sta $loopvarName+1""")
|
||||||
asmgen.translate(stmt.statements)
|
if(actuallyLongs) {
|
||||||
if(numElements<=127u) {
|
asmgen.out("""
|
||||||
|
lda $iterableName+2,y
|
||||||
|
sta $loopvarName+2
|
||||||
|
lda $iterableName+3,y
|
||||||
|
sta $loopvarName+3""")
|
||||||
|
}
|
||||||
|
asmgen.translate(stmt.statements)
|
||||||
|
if(numElements<=127u) {
|
||||||
|
if(actuallyLongs) {
|
||||||
|
asmgen.out("""
|
||||||
|
ldy $indexVar
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
cpy #${numElements*4u}
|
||||||
|
beq $endLabel
|
||||||
|
bne $loopLabel""")
|
||||||
|
} else {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
@@ -643,6 +664,19 @@ $loopLabel sty $indexVar
|
|||||||
cpy #${numElements*2u}
|
cpy #${numElements*2u}
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
bne $loopLabel""")
|
bne $loopLabel""")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(actuallyLongs) {
|
||||||
|
// array size is 64 longs, 256 bytes
|
||||||
|
asmgen.out("""
|
||||||
|
ldy $indexVar
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
bne $loopLabel
|
||||||
|
beq $endLabel""")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// array size is 128 words, 256 bytes
|
// array size is 128 words, 256 bytes
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@@ -652,23 +686,29 @@ $loopLabel sty $indexVar
|
|||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
}
|
}
|
||||||
if(!asmgen.options.romable) {
|
}
|
||||||
if(numElements>=16u) {
|
if(!asmgen.options.romable) {
|
||||||
// allocate index var on ZP if possible, otherwise inline
|
if(numElements>=16u) {
|
||||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
// allocate index var on ZP if possible, otherwise inline
|
||||||
result.fold(
|
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
result.fold(
|
||||||
failure = { asmgen.out("$indexVar .byte 0") }
|
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||||
)
|
failure = { asmgen.out("$indexVar .byte 0") }
|
||||||
} else {
|
)
|
||||||
asmgen.out("$indexVar .byte 0")
|
} else {
|
||||||
}
|
asmgen.out("$indexVar .byte 0")
|
||||||
}
|
}
|
||||||
asmgen.out(endLabel)
|
|
||||||
}
|
|
||||||
iterableDt.isFloatArray -> {
|
|
||||||
throw AssemblyError("for loop with floating point variables is not supported")
|
|
||||||
}
|
}
|
||||||
|
asmgen.out(endLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
iterableDt.isString -> iterateStrings()
|
||||||
|
iterableDt.isByteArray || iterableDt.isBoolArray -> iterateBytes()
|
||||||
|
iterableDt.isSplitWordArray -> iterateSplitWords()
|
||||||
|
iterableDt.isWordArray -> iterateWords()
|
||||||
|
iterableDt.isLongArray -> iterateWords(true)
|
||||||
|
iterableDt.isFloatArray -> throw AssemblyError("for loop with floating point variables is not supported")
|
||||||
else -> throw AssemblyError("can't iterate over $iterableDt")
|
else -> throw AssemblyError("can't iterate over $iterableDt")
|
||||||
}
|
}
|
||||||
asmgen.loopEndLabels.removeLast()
|
asmgen.loopEndLabels.removeLast()
|
||||||
|
|||||||
@@ -901,6 +901,16 @@ internal class ProgramAndVarsGen(
|
|||||||
asmgen.out(" .sint " + chunk.joinToString())
|
asmgen.out(" .sint " + chunk.joinToString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dt.isLongArray -> {
|
||||||
|
val data = makeArrayFillDataSigned(dt, value, orNumberOfZeros)
|
||||||
|
if (data.size <= 16)
|
||||||
|
asmgen.out("$varname\t.dint ${data.joinToString()}")
|
||||||
|
else {
|
||||||
|
asmgen.out(varname)
|
||||||
|
for (chunk in data.chunked(16))
|
||||||
|
asmgen.out(" .dint " + chunk.joinToString())
|
||||||
|
}
|
||||||
|
}
|
||||||
dt.isFloatArray -> {
|
dt.isFloatArray -> {
|
||||||
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
||||||
val floatFills = array.map {
|
val floatFills = array.map {
|
||||||
@@ -1023,7 +1033,7 @@ internal class ProgramAndVarsGen(
|
|||||||
val number = it.number!!.toInt()
|
val number = it.number!!.toInt()
|
||||||
"$" + number.toString(16).padStart(4, '0')
|
"$" + number.toString(16).padStart(4, '0')
|
||||||
}
|
}
|
||||||
dt.isArray && dt.elementType().isSignedWord -> array.map {
|
dt.isSignedWordArray -> array.map {
|
||||||
val number = it.number!!.toInt()
|
val number = it.number!!.toInt()
|
||||||
val hexnum = number.absoluteValue.toString(16).padStart(4, '0')
|
val hexnum = number.absoluteValue.toString(16).padStart(4, '0')
|
||||||
if(number>=0)
|
if(number>=0)
|
||||||
@@ -1031,6 +1041,14 @@ internal class ProgramAndVarsGen(
|
|||||||
else
|
else
|
||||||
"-$$hexnum"
|
"-$$hexnum"
|
||||||
}
|
}
|
||||||
|
dt.isLongArray -> array.map {
|
||||||
|
val number = it.number!!.toInt()
|
||||||
|
val hexnum = number.absoluteValue.toString(16).padStart(8, '0')
|
||||||
|
if(number>=0)
|
||||||
|
"$$hexnum"
|
||||||
|
else
|
||||||
|
"-$$hexnum"
|
||||||
|
}
|
||||||
else -> throw AssemblyError("invalid dt")
|
else -> throw AssemblyError("invalid dt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3964,7 +3964,20 @@ $endLabel""")
|
|||||||
stz ${target.asmVarname}+2
|
stz ${target.asmVarname}+2
|
||||||
stz ${target.asmVarname}+3""")
|
stz ${target.asmVarname}+3""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> TODO("assign long zero to array ${target.position}")
|
TargetStorageKind.ARRAY -> {
|
||||||
|
val deref = target.array!!.pointerderef
|
||||||
|
if(deref!=null) {
|
||||||
|
pointergen.assignLong(IndexedPtrTarget(target), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||||
|
asmgen.out("""
|
||||||
|
lda #0
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
sta ${target.asmVarname}+1,y
|
||||||
|
sta ${target.asmVarname}+2,y
|
||||||
|
sta ${target.asmVarname}+3,y""")
|
||||||
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
|
TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
|
||||||
TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
|
TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
|
||||||
TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
|
TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
|
||||||
@@ -3988,7 +4001,24 @@ $endLabel""")
|
|||||||
store(hex.substring(2,4), 2)
|
store(hex.substring(2,4), 2)
|
||||||
store(hex.substring(0,2), 3)
|
store(hex.substring(0,2), 3)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> TODO("assign long $long to array ${target.position}")
|
TargetStorageKind.ARRAY -> {
|
||||||
|
val deref = target.array!!.pointerderef
|
||||||
|
if(deref!=null) {
|
||||||
|
pointergen.assignWord(IndexedPtrTarget(target), long)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||||
|
val hex = long.toUInt().toString(16).padStart(8, '0')
|
||||||
|
asmgen.out("""
|
||||||
|
lda #$${hex.substring(6,8)}
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
lda #$${hex.substring(4, 6)}
|
||||||
|
sta ${target.asmVarname}+1,y
|
||||||
|
lda #$${hex.substring(2, 4)}
|
||||||
|
sta ${target.asmVarname}+2,y
|
||||||
|
lda #$${hex.take(2)}
|
||||||
|
sta ${target.asmVarname}+3,y""")
|
||||||
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
|
TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
|
||||||
TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
|
TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
|
||||||
TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
|
TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
|
||||||
@@ -4009,7 +4039,7 @@ $endLabel""")
|
|||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
val deref = target.array!!.pointerderef
|
val deref = target.array!!.pointerderef
|
||||||
if(deref!=null) {
|
if(deref!=null) {
|
||||||
pointergen.assignWord(IndexedPtrTarget(target), word)
|
pointergen.assignWord(IndexedPtrTarget(target), 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||||
|
|||||||
@@ -302,6 +302,25 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target.datatype.isLong -> {
|
||||||
|
when(value.kind) {
|
||||||
|
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationLongWithLiteralval(targetVarName, operator, value.boolean!!.asInt())
|
||||||
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationLongWithLiteralval(targetVarName, operator, value.number!!.number.toInt())
|
||||||
|
SourceStorageKind.VARIABLE -> inplacemodificationLongWithVariable(targetVarName, operator, value.asmVarname)
|
||||||
|
SourceStorageKind.REGISTER -> inplacemodificationLongWithVariable(targetVarName, operator, regName(value))
|
||||||
|
SourceStorageKind.MEMORY -> TODO("inplace long modifiication ${target.position}")
|
||||||
|
SourceStorageKind.ARRAY -> TODO("inplace long modifiication ${target.position}")
|
||||||
|
SourceStorageKind.EXPRESSION -> {
|
||||||
|
if(value.expression is PtTypeCast) {
|
||||||
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
|
TODO("inplace long modifiication ${target.position}")
|
||||||
|
} else {
|
||||||
|
TODO("inplace long modifiication ${target.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
target.datatype.isFloat -> {
|
target.datatype.isFloat -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(targetVarName, operator, value.boolean!!.asInt().toDouble())
|
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(targetVarName, operator, value.boolean!!.asInt().toDouble())
|
||||||
|
|||||||
@@ -406,6 +406,10 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
|||||||
TODO("array ptr assign const word ${target.position}")
|
TODO("array ptr assign const word ${target.position}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun assignLong(target: IndexedPtrTarget, long: Int) {
|
||||||
|
TODO("array ptr assign const long ${target.position}")
|
||||||
|
}
|
||||||
|
|
||||||
internal fun assignFloat(target: IndexedPtrTarget, float: Double) {
|
internal fun assignFloat(target: IndexedPtrTarget, float: Double) {
|
||||||
TODO("array ptr assign const float ${target.position}")
|
TODO("array ptr assign const float ${target.position}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
"callfar" -> funcCallfar(call)
|
"callfar" -> funcCallfar(call)
|
||||||
"callfar2" -> funcCallfar2(call)
|
"callfar2" -> funcCallfar2(call)
|
||||||
"call" -> funcCall(call)
|
"call" -> funcCall(call)
|
||||||
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
|
"msw" -> funcMsw(call)
|
||||||
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
|
"lsw" -> funcLsw(call)
|
||||||
"msb" -> funcMsb(call)
|
"msb" -> funcMsb(call)
|
||||||
"lsb" -> funcLsb(call)
|
"lsb" -> funcLsb(call)
|
||||||
"memory" -> funcMemory(call)
|
"memory" -> funcMemory(call)
|
||||||
@@ -525,6 +525,15 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcLsw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
||||||
|
}
|
||||||
|
|
||||||
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val tr = exprGen.translateExpression(call.args.single())
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
@@ -535,6 +544,15 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcMsw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
|
addInstr(result, IRInstruction(Opcode.MSIG, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
||||||
|
}
|
||||||
|
|
||||||
private fun funcRolRor(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcRolRor(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val arg = call.args[0]
|
val arg = call.args[0]
|
||||||
|
|||||||
@@ -240,6 +240,11 @@ internal class AstChecker(private val program: Program,
|
|||||||
errors.err("word loop variable can only loop over bytes or words", forLoop.position)
|
errors.err("word loop variable can only loop over bytes or words", forLoop.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseDataType.LONG -> {
|
||||||
|
if(!iterableDt.elementType().isInteger)
|
||||||
|
errors.err("long loop variable can only loop over integers", forLoop.position)
|
||||||
|
}
|
||||||
|
|
||||||
BaseDataType.FLOAT -> {
|
BaseDataType.FLOAT -> {
|
||||||
// Looping over float variables is very inefficient because the loopvar is going to
|
// Looping over float variables is very inefficient because the loopvar is going to
|
||||||
// get copied over with new values all the time. We don't support this for now.
|
// get copied over with new values all the time. We don't support this for now.
|
||||||
@@ -941,6 +946,9 @@ internal class AstChecker(private val program: Program,
|
|||||||
dt.isWordArray ->
|
dt.isWordArray ->
|
||||||
if(arraySize > 128)
|
if(arraySize > 128)
|
||||||
err("regular word array length must be 1-128, use split array to get to 256")
|
err("regular word array length must be 1-128, use split array to get to 256")
|
||||||
|
dt.isLongArray ->
|
||||||
|
if(arraySize > 64)
|
||||||
|
err("long array length must be 1-64")
|
||||||
dt.isFloatArray ->
|
dt.isFloatArray ->
|
||||||
if(arraySize > 51)
|
if(arraySize > 51)
|
||||||
err("float array length must be 1-51")
|
err("float array length must be 1-51")
|
||||||
@@ -1044,6 +1052,10 @@ internal class AstChecker(private val program: Program,
|
|||||||
if (length == 0 || length > 128)
|
if (length == 0 || length > 128)
|
||||||
err("regular word array length must be 1-128, use split array to get to 256")
|
err("regular word array length must be 1-128, use split array to get to 256")
|
||||||
}
|
}
|
||||||
|
decl.datatype.isLongArray -> {
|
||||||
|
if (length == 0 || length > 64)
|
||||||
|
err("long array length must be 1-64")
|
||||||
|
}
|
||||||
decl.datatype.isFloatArray -> {
|
decl.datatype.isFloatArray -> {
|
||||||
if (length == 0 || length > 51)
|
if (length == 0 || length > 51)
|
||||||
err("float array length must be 1-51")
|
err("float array length must be 1-51")
|
||||||
@@ -2478,7 +2490,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(onGoto: OnGoto) {
|
override fun visit(onGoto: OnGoto) {
|
||||||
val t = onGoto.index.inferType(program)
|
|
||||||
if(!onGoto.index.inferType(program).getOrUndef().isUnsignedByte) {
|
if(!onGoto.index.inferType(program).getOrUndef().isUnsignedByte) {
|
||||||
errors.err("on..goto index must be an unsigned byte", onGoto.index.position)
|
errors.err("on..goto index must be an unsigned byte", onGoto.index.position)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,9 +386,6 @@ class TestMemory: FunSpec({
|
|||||||
shouldThrow<IllegalArgumentException> {
|
shouldThrow<IllegalArgumentException> {
|
||||||
target.memorySize(BaseDataType.UNDEFINED)
|
target.memorySize(BaseDataType.UNDEFINED)
|
||||||
}
|
}
|
||||||
shouldThrow<NoSuchElementException> {
|
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.LONG), 10)
|
|
||||||
}
|
|
||||||
target.memorySize(BaseDataType.BOOL) shouldBe 1
|
target.memorySize(BaseDataType.BOOL) shouldBe 1
|
||||||
target.memorySize(BaseDataType.BYTE) shouldBe 1
|
target.memorySize(BaseDataType.BYTE) shouldBe 1
|
||||||
target.memorySize(BaseDataType.WORD) shouldBe 2
|
target.memorySize(BaseDataType.WORD) shouldBe 2
|
||||||
@@ -397,6 +394,7 @@ class TestMemory: FunSpec({
|
|||||||
|
|
||||||
target.memorySize(DataType.BOOL, null) shouldBe 1
|
target.memorySize(DataType.BOOL, null) shouldBe 1
|
||||||
target.memorySize(DataType.WORD, null) shouldBe 2
|
target.memorySize(DataType.WORD, null) shouldBe 2
|
||||||
|
target.memorySize(DataType.LONG, null) shouldBe 4
|
||||||
target.memorySize(DataType.FLOAT, null) shouldBe target.FLOAT_MEM_SIZE
|
target.memorySize(DataType.FLOAT, null) shouldBe target.FLOAT_MEM_SIZE
|
||||||
|
|
||||||
target.memorySize(DataType.STR, null) shouldBe 2
|
target.memorySize(DataType.STR, null) shouldBe 2
|
||||||
@@ -409,6 +407,7 @@ class TestMemory: FunSpec({
|
|||||||
target.memorySize(DataType.arrayFor(BaseDataType.BYTE), 10) shouldBe 10
|
target.memorySize(DataType.arrayFor(BaseDataType.BYTE), 10) shouldBe 10
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.WORD), 10) shouldBe 20
|
target.memorySize(DataType.arrayFor(BaseDataType.WORD), 10) shouldBe 20
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.UWORD), 10) shouldBe 20
|
target.memorySize(DataType.arrayFor(BaseDataType.UWORD), 10) shouldBe 20
|
||||||
|
target.memorySize(DataType.arrayFor(BaseDataType.LONG), 10) shouldBe 40
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.FLOAT), 10) shouldBe 10*target.FLOAT_MEM_SIZE
|
target.memorySize(DataType.arrayFor(BaseDataType.FLOAT), 10) shouldBe 10*target.FLOAT_MEM_SIZE
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.WORD, true), 10) shouldBe 20
|
target.memorySize(DataType.arrayFor(BaseDataType.WORD, true), 10) shouldBe 20
|
||||||
target.memorySize(DataType.arrayFor(BaseDataType.UWORD, true), 10) shouldBe 20
|
target.memorySize(DataType.arrayFor(BaseDataType.UWORD, true), 10) shouldBe 20
|
||||||
|
|||||||
@@ -871,6 +871,7 @@ main {
|
|||||||
DataType.forDt(BaseDataType.FLOAT).isFloat shouldBe true
|
DataType.forDt(BaseDataType.FLOAT).isFloat shouldBe true
|
||||||
|
|
||||||
DataType.arrayFor(BaseDataType.UBYTE, true).isUnsignedByteArray shouldBe true
|
DataType.arrayFor(BaseDataType.UBYTE, true).isUnsignedByteArray shouldBe true
|
||||||
|
DataType.arrayFor(BaseDataType.LONG).isLongArray shouldBe true
|
||||||
DataType.arrayFor(BaseDataType.FLOAT).isFloatArray shouldBe true
|
DataType.arrayFor(BaseDataType.FLOAT).isFloatArray shouldBe true
|
||||||
DataType.arrayFor(BaseDataType.UWORD).isUnsignedWordArray shouldBe true
|
DataType.arrayFor(BaseDataType.UWORD).isUnsignedWordArray shouldBe true
|
||||||
DataType.arrayFor(BaseDataType.UWORD).isArray shouldBe true
|
DataType.arrayFor(BaseDataType.UWORD).isArray shouldBe true
|
||||||
@@ -886,9 +887,6 @@ main {
|
|||||||
shouldThrow<NoSuchElementException> {
|
shouldThrow<NoSuchElementException> {
|
||||||
DataType.arrayFor(BaseDataType.ARRAY)
|
DataType.arrayFor(BaseDataType.ARRAY)
|
||||||
}
|
}
|
||||||
shouldThrow<NoSuchElementException> {
|
|
||||||
DataType.arrayFor(BaseDataType.LONG)
|
|
||||||
}
|
|
||||||
shouldThrow<NoSuchElementException> {
|
shouldThrow<NoSuchElementException> {
|
||||||
DataType.arrayFor(BaseDataType.UNDEFINED)
|
DataType.arrayFor(BaseDataType.UNDEFINED)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,21 @@ main {
|
|||||||
; }
|
; }
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
long[] array = [-1999888777, -999, 42, 0, 77, 123456, 999999999]
|
||||||
|
long xx
|
||||||
|
for xx in array {
|
||||||
|
txt.print_uw(msw(xx))
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uw(lsw(xx))
|
||||||
|
txt.nl()
|
||||||
|
}
|
||||||
|
txt.nl()
|
||||||
|
array[2] = 0
|
||||||
|
array[3] = 222222222
|
||||||
|
array[4] = bignum
|
||||||
|
array[5]++
|
||||||
|
array[6]--
|
||||||
|
|
||||||
txt.print_l(-1999888777)
|
txt.print_l(-1999888777)
|
||||||
txt.spc()
|
txt.spc()
|
||||||
txt.print_l(-999)
|
txt.print_l(-999)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ fun DataType.irTypeString(length: UInt?): String {
|
|||||||
BaseDataType.UWORD -> "uword[$lengthStr]"
|
BaseDataType.UWORD -> "uword[$lengthStr]"
|
||||||
BaseDataType.BYTE -> "byte[$lengthStr]"
|
BaseDataType.BYTE -> "byte[$lengthStr]"
|
||||||
BaseDataType.WORD -> "word[$lengthStr]"
|
BaseDataType.WORD -> "word[$lengthStr]"
|
||||||
|
BaseDataType.LONG -> "long[$lengthStr]"
|
||||||
BaseDataType.BOOL -> "bool[$lengthStr]"
|
BaseDataType.BOOL -> "bool[$lengthStr]"
|
||||||
BaseDataType.FLOAT -> "float[$lengthStr]"
|
BaseDataType.FLOAT -> "float[$lengthStr]"
|
||||||
else -> throw IllegalArgumentException("invalid sub type")
|
else -> throw IllegalArgumentException("invalid sub type")
|
||||||
|
|||||||
@@ -386,6 +386,17 @@ class VmProgramLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable.dt.isLongArray -> {
|
||||||
|
for (elt in iElts) {
|
||||||
|
val value = getInitializerValue(variable.dt, elt, symbolAddresses)
|
||||||
|
value.fold(
|
||||||
|
{ memory.setSL(address, it.toInt()) },
|
||||||
|
{ throw IRParseException("didn't expect bool") }
|
||||||
|
)
|
||||||
|
address += 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
variable.dt.isFloatArray -> {
|
variable.dt.isFloatArray -> {
|
||||||
for (elt in iElts) {
|
for (elt in iElts) {
|
||||||
val value = getInitializerValue(variable.dt, elt, symbolAddresses)
|
val value = getInitializerValue(variable.dt, elt, symbolAddresses)
|
||||||
|
|||||||
Reference in New Issue
Block a user