mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
introduced type cast "... as ..." instead of builtin functions
This commit is contained in:
parent
445db44c05
commit
5870006b2f
@ -8,12 +8,14 @@
|
||||
|
||||
; @todo unify the type cast functions... "wrd(5)" -> "5 as word"
|
||||
|
||||
; @todo docs: "integer / int will not result in float but is integer floor division." verify this!
|
||||
|
||||
sub toscreenx(float x, float z) -> word {
|
||||
return 42 as word
|
||||
}
|
||||
|
||||
asmsub blerp(ubyte x @ A, uword ding @ XY) -> clobbers() -> () {
|
||||
word qq = X as word
|
||||
word qq = A as word
|
||||
}
|
||||
|
||||
sub start() {
|
||||
|
@ -39,7 +39,7 @@ private fun compileMain(args: Array<String>) {
|
||||
else if(!arg.startsWith("--"))
|
||||
moduleFile = arg
|
||||
}
|
||||
if(moduleFile.isNullOrBlank())
|
||||
if(moduleFile.isBlank())
|
||||
usage()
|
||||
|
||||
val filepath = Paths.get(moduleFile).normalize()
|
||||
|
@ -995,7 +995,6 @@ class TypecastExpression(var expression: IExpression, var type: DataType, overri
|
||||
|
||||
companion object {
|
||||
fun typecast(cv: LiteralValue, type: DataType): LiteralValue? {
|
||||
println("CONSTVALUE $cv -> $type")
|
||||
return when (cv.type) {
|
||||
DataType.UBYTE -> {
|
||||
when (type) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package prog8.ast
|
||||
|
||||
import com.sun.org.apache.xpath.internal.operations.Bool
|
||||
import prog8.compiler.CompilationOptions
|
||||
import prog8.compiler.HeapValues
|
||||
import prog8.compiler.target.c64.FLOAT_MAX_NEGATIVE
|
||||
|
@ -580,8 +580,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun convertType(givenDt: DataType, targetDt: DataType) {
|
||||
// only WIDENS a type, never NARROWS
|
||||
// TODO replace by type cast "... as type" ?
|
||||
// only WIDENS a type, never NARROWS. To avoid loss of precision.
|
||||
if(givenDt==targetDt)
|
||||
return
|
||||
if(givenDt !in NumericDatatypes)
|
||||
@ -590,23 +589,25 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
throw CompilerException("converting $givenDt to non-numeric $targetDt")
|
||||
when(givenDt) {
|
||||
DataType.UBYTE -> when(targetDt) {
|
||||
DataType.UWORD, DataType.WORD -> prog.instr(Opcode.UB2UWORD)
|
||||
DataType.FLOAT -> prog.instr(Opcode.UB2FLOAT)
|
||||
DataType.UWORD -> prog.instr(Opcode.CAST_UB_TO_UW)
|
||||
DataType.WORD -> prog.instr(Opcode.CAST_UB_TO_W)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_UB_TO_F)
|
||||
else -> {}
|
||||
}
|
||||
DataType.BYTE -> when(targetDt) {
|
||||
DataType.UWORD, DataType.WORD -> prog.instr(Opcode.B2WORD)
|
||||
DataType.FLOAT -> prog.instr(Opcode.B2FLOAT)
|
||||
DataType.UWORD -> prog.instr(Opcode.CAST_B_TO_UW)
|
||||
DataType.WORD -> prog.instr(Opcode.CAST_B_TO_W)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_B_TO_F)
|
||||
else -> {}
|
||||
}
|
||||
DataType.UWORD -> when(targetDt) {
|
||||
DataType.UBYTE, DataType.BYTE -> throw CompilerException("narrowing type")
|
||||
DataType.FLOAT -> prog.instr(Opcode.UW2FLOAT)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_UW_TO_F)
|
||||
else -> {}
|
||||
}
|
||||
DataType.WORD -> when(targetDt) {
|
||||
DataType.UBYTE, DataType.BYTE -> throw CompilerException("narrowing type")
|
||||
DataType.FLOAT -> prog.instr(Opcode.W2FLOAT)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_W_TO_F)
|
||||
else -> {}
|
||||
}
|
||||
DataType.FLOAT -> if(targetDt in IntegerDatatypes) throw CompilerException("narrowing type")
|
||||
@ -724,22 +725,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
else -> throw CompilerException("wrong datatype for $funcname()")
|
||||
}
|
||||
}
|
||||
"flt" -> {
|
||||
// 1 argument, type determines the exact opcode to use
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.UB2FLOAT)
|
||||
DataType.BYTE -> prog.instr(Opcode.B2FLOAT)
|
||||
DataType.UWORD -> prog.instr(Opcode.UW2FLOAT)
|
||||
DataType.WORD -> prog.instr(Opcode.W2FLOAT)
|
||||
DataType.FLOAT -> prog.instr(Opcode.NOP)
|
||||
else -> throw CompilerException("wrong datatype for flt()")
|
||||
}
|
||||
}
|
||||
"msb" -> prog.instr(Opcode.MSB)
|
||||
"lsb" -> prog.instr(Opcode.LSB)
|
||||
"b2ub" -> prog.instr(Opcode.B2UB)
|
||||
"ub2b" -> prog.instr(Opcode.UB2B)
|
||||
"lsb" -> TODO("lsb -> uw2ub or w2ub?")
|
||||
"lsl" -> {
|
||||
val arg = args.single()
|
||||
val dt = arg.resultingDatatype(namespace, heap)
|
||||
@ -1269,15 +1256,15 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.WORD -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.UB2UWORD)
|
||||
DataType.BYTE -> prog.instr(Opcode.B2WORD)
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_W)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_W)
|
||||
else -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
}
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.UB2UWORD)
|
||||
DataType.BYTE -> prog.instr(Opcode.B2WORD)
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_UW)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_UW)
|
||||
DataType.STR, DataType.STR_S -> pushStringAddress(stmt.value, true)
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.ARRAY_W, DataType.ARRAY_UW, DataType.ARRAY_F -> {
|
||||
if (stmt.value is IdentifierReference) {
|
||||
@ -1293,10 +1280,10 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.UB2FLOAT)
|
||||
DataType.BYTE -> prog.instr(Opcode.B2FLOAT)
|
||||
DataType.UWORD -> prog.instr(Opcode.UW2FLOAT)
|
||||
DataType.WORD -> prog.instr(Opcode.W2FLOAT)
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_F)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_F)
|
||||
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_F)
|
||||
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_F)
|
||||
else -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
}
|
||||
}
|
||||
@ -1979,7 +1966,52 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun translate(expr: TypecastExpression) {
|
||||
TODO("translate typecast $expr") //To change body of created functions use File | Settings | File Templates.
|
||||
translate(expr.expression)
|
||||
val sourceDt = expr.expression.resultingDatatype(namespace, heap) ?: throw CompilerException("don't know what type to cast")
|
||||
if(sourceDt==expr.type)
|
||||
return
|
||||
|
||||
when(expr.type) {
|
||||
DataType.UBYTE -> when(sourceDt) {
|
||||
DataType.UBYTE -> {}
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_UB)
|
||||
DataType.UWORD, DataType.WORD -> prog.instr(Opcode.CAST_WRD_TO_UB)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UB)
|
||||
else -> throw CompilerException("invalid cast type $sourceDt")
|
||||
}
|
||||
DataType.BYTE -> when(sourceDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_B)
|
||||
DataType.BYTE -> {}
|
||||
DataType.UWORD, DataType.WORD -> prog.instr(Opcode.CAST_WRD_TO_B)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_B)
|
||||
else -> throw CompilerException("invalid cast type $sourceDt")
|
||||
}
|
||||
DataType.UWORD -> when(sourceDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_UW)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_UW)
|
||||
DataType.UWORD -> {}
|
||||
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_UW)
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UW)
|
||||
else -> throw CompilerException("invalid cast type $sourceDt")
|
||||
}
|
||||
DataType.WORD -> when(sourceDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_W)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_W)
|
||||
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_W)
|
||||
DataType.WORD -> {}
|
||||
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_W)
|
||||
else -> throw CompilerException("invalid cast type $sourceDt")
|
||||
}
|
||||
DataType.FLOAT -> when(sourceDt) {
|
||||
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_F)
|
||||
DataType.BYTE -> prog.instr(Opcode.CAST_B_TO_F)
|
||||
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_F)
|
||||
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_F)
|
||||
DataType.FLOAT -> {}
|
||||
else -> throw CompilerException("invalid cast type $sourceDt")
|
||||
}
|
||||
else -> throw CompilerException("can't typecast to ${expr.type}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -179,26 +179,21 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
|
||||
fun optimizeFloatConversion(index0: Int, index1: Int, ins1: Instruction) {
|
||||
when (ins1.opcode) {
|
||||
Opcode.LSB,
|
||||
Opcode.MSB,
|
||||
Opcode.B2WORD,
|
||||
Opcode.UB2UWORD,
|
||||
Opcode.B2FLOAT,
|
||||
Opcode.UB2FLOAT,
|
||||
Opcode.UW2FLOAT,
|
||||
Opcode.W2FLOAT -> throw CompilerException("invalid conversion following a float")
|
||||
Opcode.DISCARD_FLOAT -> {
|
||||
instructionsToReplace[index0] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD_BYTE, Opcode.DISCARD_WORD -> throw CompilerException("invalid discard type following a float")
|
||||
else -> throw CompilerException("invalid conversion opcode ${ins1.opcode}")
|
||||
else -> throw CompilerException("invalid conversion opcode ${ins1.opcode} following a float")
|
||||
}
|
||||
}
|
||||
|
||||
fun optimizeWordConversion(index0: Int, ins0: Instruction, index1: Int, ins1: Instruction) {
|
||||
when (ins1.opcode) {
|
||||
Opcode.LSB -> {
|
||||
Opcode.CAST_B_TO_W, Opcode.CAST_B_TO_UW -> TODO("cast byte to (u)word")
|
||||
Opcode.CAST_UB_TO_W, Opcode.CAST_UB_TO_UW -> TODO("cast ubyte to (u)word")
|
||||
Opcode.CAST_WRD_TO_B -> TODO("cast (u)word to byte")
|
||||
Opcode.CAST_WRD_TO_UB -> {
|
||||
val ins = Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, ins0.arg!!.integerValue() and 255))
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
@ -208,11 +203,7 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.B2WORD,
|
||||
Opcode.UB2UWORD,
|
||||
Opcode.B2FLOAT,
|
||||
Opcode.UB2FLOAT -> throw CompilerException("invalid conversion following a word")
|
||||
Opcode.W2FLOAT, Opcode.UW2FLOAT -> {
|
||||
Opcode.CAST_W_TO_F, Opcode.CAST_UW_TO_F -> {
|
||||
val ins = Instruction(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, ins0.arg!!.integerValue().toDouble()))
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
@ -222,30 +213,32 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD_BYTE, Opcode.DISCARD_FLOAT -> throw CompilerException("invalid discard type following a byte")
|
||||
else -> throw CompilerException("invalid conversion opcode ${ins1.opcode}")
|
||||
else -> throw CompilerException("invalid conversion opcode ${ins1.opcode} following a word")
|
||||
}
|
||||
}
|
||||
|
||||
fun optimizeByteConversion(index0: Int, ins0: Instruction, index1: Int, ins1: Instruction) {
|
||||
when (ins1.opcode) {
|
||||
Opcode.LSB -> instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
Opcode.CAST_B_TO_UB, Opcode.CAST_UB_TO_B,
|
||||
Opcode.CAST_WRD_TO_B, Opcode.CAST_WRD_TO_UB -> instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
Opcode.MSB -> throw CompilerException("msb of a byte")
|
||||
Opcode.UB2UWORD -> {
|
||||
Opcode.CAST_UB_TO_UW -> {
|
||||
val ins = Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, ins0.arg!!.integerValue()))
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.B2WORD -> {
|
||||
Opcode.CAST_B_TO_W -> {
|
||||
val ins = Instruction(Opcode.PUSH_WORD, Value(DataType.WORD, ins0.arg!!.integerValue()))
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.B2FLOAT, Opcode.UB2FLOAT -> {
|
||||
Opcode.CAST_B_TO_UW, Opcode.CAST_UB_TO_W -> TODO("cast byte to (u)word")
|
||||
Opcode.CAST_B_TO_F, Opcode.CAST_UB_TO_F-> {
|
||||
val ins = Instruction(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, ins0.arg!!.integerValue().toDouble()))
|
||||
instructionsToReplace[index0] = ins
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.W2FLOAT, Opcode.UW2FLOAT -> throw CompilerException("invalid conversion following a byte")
|
||||
Opcode.CAST_W_TO_F, Opcode.CAST_UW_TO_F-> throw CompilerException("invalid conversion following a byte")
|
||||
Opcode.DISCARD_BYTE -> {
|
||||
instructionsToReplace[index0] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[index1] = Instruction(Opcode.NOP)
|
||||
@ -259,14 +252,25 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
instructionsToReplace.clear()
|
||||
|
||||
val typeConversionOpcodes = setOf(
|
||||
Opcode.LSB,
|
||||
Opcode.MSB,
|
||||
Opcode.B2WORD,
|
||||
Opcode.UB2UWORD,
|
||||
Opcode.B2FLOAT,
|
||||
Opcode.UB2FLOAT,
|
||||
Opcode.W2FLOAT,
|
||||
Opcode.UW2FLOAT,
|
||||
Opcode.CAST_UB_TO_B,
|
||||
Opcode.CAST_UB_TO_UW,
|
||||
Opcode.CAST_UB_TO_W,
|
||||
Opcode.CAST_UB_TO_F,
|
||||
Opcode.CAST_B_TO_UB,
|
||||
Opcode.CAST_B_TO_UW,
|
||||
Opcode.CAST_B_TO_W,
|
||||
Opcode.CAST_B_TO_F,
|
||||
Opcode.CAST_UW_TO_W,
|
||||
Opcode.CAST_UW_TO_F,
|
||||
Opcode.CAST_WRD_TO_UB,
|
||||
Opcode.CAST_WRD_TO_B,
|
||||
Opcode.CAST_W_TO_UW,
|
||||
Opcode.CAST_W_TO_F,
|
||||
Opcode.CAST_F_TO_UB,
|
||||
Opcode.CAST_F_TO_B,
|
||||
Opcode.CAST_F_TO_UW,
|
||||
Opcode.CAST_F_TO_W,
|
||||
Opcode.DISCARD_BYTE,
|
||||
Opcode.DISCARD_WORD,
|
||||
Opcode.DISCARD_FLOAT
|
||||
|
@ -119,16 +119,25 @@ enum class Opcode {
|
||||
INV_WORD,
|
||||
|
||||
// numeric type conversions
|
||||
LSB,
|
||||
MSB,
|
||||
B2UB,
|
||||
UB2B,
|
||||
B2WORD, // convert a byte into a word where it is the lower eight bits $ssxx with sign extension
|
||||
UB2UWORD, // convert a byte into a word where it is the lower eight bits $00xx
|
||||
B2FLOAT, // convert byte into floating point
|
||||
UB2FLOAT, // convert unsigned byte into floating point
|
||||
W2FLOAT, // convert word into floating point
|
||||
UW2FLOAT, // convert unsigned word into floating point
|
||||
MSB, // note: lsb is equivalent to CAST_UW_TO_UB or CAST_WRD_TO_UB
|
||||
CAST_UB_TO_B,
|
||||
CAST_UB_TO_UW,
|
||||
CAST_UB_TO_W,
|
||||
CAST_UB_TO_F,
|
||||
CAST_B_TO_UB,
|
||||
CAST_B_TO_UW,
|
||||
CAST_B_TO_W,
|
||||
CAST_B_TO_F,
|
||||
CAST_WRD_TO_UB, // word and uword: just take the LSB
|
||||
CAST_WRD_TO_B, // word and uword: just take the LSB
|
||||
CAST_W_TO_UW,
|
||||
CAST_W_TO_F,
|
||||
CAST_UW_TO_W,
|
||||
CAST_UW_TO_F,
|
||||
CAST_F_TO_UB,
|
||||
CAST_F_TO_B,
|
||||
CAST_F_TO_UW,
|
||||
CAST_F_TO_W,
|
||||
|
||||
// logical operations
|
||||
AND_BYTE,
|
||||
|
@ -386,15 +386,6 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
}
|
||||
}
|
||||
|
||||
fun lsb(): Value {
|
||||
return when(type) {
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, byteval!!)
|
||||
DataType.BYTE -> Value(DataType.UBYTE, byteval!!.toInt() and 255)
|
||||
DataType.UWORD, DataType.WORD -> Value(DataType.UBYTE, wordval!! and 255)
|
||||
else -> throw VmExecutionException("lsb can only work on (u)byte/(u)word")
|
||||
}
|
||||
}
|
||||
|
||||
fun msb(): Value {
|
||||
return when(type) {
|
||||
DataType.UBYTE, DataType.BYTE -> Value(DataType.UBYTE, 0)
|
||||
|
@ -426,7 +426,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}")
|
||||
val call = Syscall.values().find { it.callNr==ins.arg.numericValue() }
|
||||
when(call) {
|
||||
Syscall.FUNC_WRD, Syscall.FUNC_UWRD -> ""
|
||||
Syscall.FUNC_STR2UBYTE, Syscall.FUNC_STR2UWORD -> " jsr prog8_lib.func_str2uword"
|
||||
else -> " jsr prog8_lib.${call.toString().toLowerCase()}"
|
||||
}
|
||||
@ -671,14 +670,25 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
bne ${ins.callLabel}
|
||||
"""
|
||||
}
|
||||
Opcode.UB2FLOAT -> " jsr prog8_lib.stack_ub2float"
|
||||
Opcode.B2FLOAT -> " jsr prog8_lib.stack_b2float"
|
||||
Opcode.UW2FLOAT -> " jsr prog8_lib.stack_uw2float"
|
||||
Opcode.W2FLOAT -> " jsr prog8_lib.stack_w2float"
|
||||
Opcode.B2UB -> "" // is a no-op, just carry on with the byte as-is
|
||||
Opcode.UB2B -> "" // is a no-op, just carry on with the byte as-is
|
||||
Opcode.UB2UWORD -> " lda #0 | sta ${ESTACK_HI+1},x"
|
||||
Opcode.B2WORD -> " ${signExtendA("${ESTACK_HI+1},x")}"
|
||||
Opcode.CAST_B_TO_UB -> "" // is a no-op, just carry on with the byte as-is
|
||||
Opcode.CAST_UB_TO_B -> "" // is a no-op, just carry on with the byte as-is
|
||||
Opcode.CAST_W_TO_UW -> "" // is a no-op, just carry on with the word as-is
|
||||
Opcode.CAST_UW_TO_W -> "" // is a no-op, just carry on with the word as-is
|
||||
Opcode.CAST_WRD_TO_UB -> "" // is a no-op, just carry on with the lsb of the (u)word as-is
|
||||
Opcode.CAST_WRD_TO_B -> "" // is a no-op, just carry on with the lsb of the (u)word as-is
|
||||
Opcode.CAST_UB_TO_F -> " jsr prog8_lib.stack_ub2float"
|
||||
Opcode.CAST_B_TO_F -> " jsr prog8_lib.stack_b2float"
|
||||
Opcode.CAST_UW_TO_F -> " jsr prog8_lib.stack_uw2float"
|
||||
Opcode.CAST_W_TO_F -> " jsr prog8_lib.stack_w2float"
|
||||
Opcode.CAST_UB_TO_UW -> " lda #0 | sta ${ESTACK_HI+1},x" // clear the msb
|
||||
Opcode.CAST_UB_TO_W -> TODO("ub2w")
|
||||
Opcode.CAST_B_TO_UW -> TODO("b2uw")
|
||||
Opcode.CAST_B_TO_W -> " ${signExtendA("${ESTACK_HI+1},x")}" // sign extend the lsb @todo missing an lda???
|
||||
Opcode.CAST_F_TO_UB -> TODO("f2ub")
|
||||
Opcode.CAST_F_TO_B -> TODO("f2b")
|
||||
Opcode.CAST_F_TO_UW -> TODO("f2uw")
|
||||
Opcode.CAST_F_TO_W -> TODO("f2w")
|
||||
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
|
||||
|
||||
Opcode.DIV_UB -> " jsr prog8_lib.div_ub"
|
||||
Opcode.DIV_B -> " jsr prog8_lib.div_b"
|
||||
@ -765,9 +775,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.LESSEQ_W -> " jsr prog8_lib.lesseq_w"
|
||||
Opcode.LESSEQ_F -> " jsr prog8_lib.lesseq_f"
|
||||
|
||||
Opcode.LSB -> ""
|
||||
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@ -1358,7 +1365,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = ubytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment ->
|
||||
when(segment[0].callLabel) {
|
||||
"A" -> " sta ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1"
|
||||
"X" -> " stx ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1"
|
||||
@ -1385,7 +1392,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment ->
|
||||
" lda ${hexVal(segment[0])} | sta ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1"
|
||||
},
|
||||
// var = mem (u)word
|
||||
@ -1400,19 +1407,19 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = ubytearray[index_byte]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment ->
|
||||
val index = hexVal(segment[0])
|
||||
" lda ${segment[1].callLabel}+$index | sta ${segment[3].callLabel} | lda #0 | sta ${segment[3].callLabel}+1"
|
||||
},
|
||||
// var = ubytearray[index var]
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment ->
|
||||
val loadA = loadAFromIndexedByVar(segment[0], segment[1])
|
||||
" $loadA | sta ${segment[3].callLabel} | lda #0 | sta ${segment[3].callLabel}+1"
|
||||
},
|
||||
// var = ubytearray[index mem]
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${segment[3].callLabel}
|
||||
@ -1458,7 +1465,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem uword = ubyte var
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment ->
|
||||
when(segment[0].callLabel) {
|
||||
"A" -> " sta ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}"
|
||||
"X" -> " stx ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}"
|
||||
@ -1467,7 +1474,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
},
|
||||
// mem uword = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${hexVal(segment[2])}
|
||||
@ -1495,7 +1502,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem uword = ubytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment ->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -1505,7 +1512,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem uword = bytearray[index] (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment ->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -1514,7 +1521,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem uword = bytearray[index var] (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment ->
|
||||
val loadA = loadAFromIndexedByVar(segment[0], segment[1])
|
||||
"""
|
||||
$loadA
|
||||
@ -1524,8 +1531,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// mem uword = bytearray[mem (u)byte] (sign extended)
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_MEM_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${hexVal(segment[3])}
|
||||
@ -1533,14 +1540,14 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem uword = ubytearray[index var]
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment ->
|
||||
val loadA = loadAFromIndexedByVar(segment[0], segment[1])
|
||||
" $loadA | sta ${hexVal(segment[3])} | lda #0 | sta ${hexValPlusOne(segment[3])}"
|
||||
},
|
||||
// mem uword = ubytearray[mem (u)bute]
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_MEM_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${hexVal(segment[3])}
|
||||
@ -1582,7 +1589,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// word var = bytevar (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${segment[2].callLabel}
|
||||
@ -1590,7 +1597,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem word = bytevar (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment ->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${hexVal(segment[2])}
|
||||
@ -1598,7 +1605,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// mem word = mem byte (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.POP_MEM_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${hexVal(segment[2])}
|
||||
@ -1606,7 +1613,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = membyte (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${segment[2].callLabel}
|
||||
@ -1614,7 +1621,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = bytearray[index_byte] (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment ->
|
||||
val index = hexVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -1623,7 +1630,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// var = bytearray[index var] (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment ->
|
||||
val loadByteA = loadAFromIndexedByVar(segment[0], segment[1])
|
||||
"""
|
||||
$loadByteA
|
||||
@ -1633,8 +1640,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// var = bytearray[mem (u)byte] (sign extended)
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${segment[3].callLabel}
|
||||
@ -1712,7 +1719,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// uwordarray[index] = ubytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val index = intVal(segment[2])*2
|
||||
when(segment[0].callLabel) {
|
||||
"A" -> " sta ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index+1}"
|
||||
@ -1722,7 +1729,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
},
|
||||
// wordarray[index] = bytevar (extend sign)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val index = intVal(segment[2])*2
|
||||
when(segment[0].callLabel) {
|
||||
"A" ->
|
||||
@ -1752,8 +1759,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// wordarray[index mem] = bytevar (extend sign)
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
when(segment[0].callLabel) {
|
||||
"A" ->
|
||||
"""
|
||||
@ -1799,8 +1806,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// wordarray[memory (u)byte] = ubyte mem
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[2])}
|
||||
asl a
|
||||
@ -1811,7 +1818,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// wordarray[index] = mem byte (extend sign)
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val index = intVal(segment[2])*2
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
@ -1820,7 +1827,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// wordarray2[index2] = bytearray1[index1] (extend sign)
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index1 = intVal(segment[0])
|
||||
val index2 = segment[3].arg!!.integerValue()*2
|
||||
"""
|
||||
@ -1831,8 +1838,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// wordarray2[mem (u)byte] = bytearray1[index1] (extend sign)
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index1 = intVal(segment[0])
|
||||
"""
|
||||
lda ${hexVal(segment[3])}
|
||||
@ -1845,7 +1852,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
|
||||
// wordarray[indexvar] = byte var (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val loadValueOnStack = when(segment[0].callLabel) {
|
||||
"A" -> " pha"
|
||||
"X" -> " txa | pha"
|
||||
@ -1867,7 +1874,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// wordarray[indexvar] = byte mem (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val loadIndexY = when(segment[2].callLabel) {
|
||||
"A" -> " asl a | tay"
|
||||
"X" -> " txa | asl a | tay"
|
||||
@ -1892,7 +1899,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// wordarray2[indexvar] = bytearay[index] (sign extended)
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
val loadIndex2Y = when(segment[3].callLabel) {
|
||||
"A" -> " asl a | tay"
|
||||
@ -1925,8 +1932,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
|
||||
// uwordarray[index mem] = ubytevar
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
when(segment[0].callLabel) {
|
||||
"A" ->
|
||||
"""
|
||||
@ -1975,8 +1982,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// uwordarray[index mem] = ubyte mem
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[2])}
|
||||
asl a
|
||||
@ -1988,7 +1995,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// uwordarray[index] = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val index = intVal(segment[2])*2
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
@ -2018,7 +2025,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// uwordarray2[index2] = ubytearray1[index1]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index1 = intVal(segment[0])
|
||||
val index2 = segment[3].arg!!.integerValue()*2
|
||||
"""
|
||||
@ -2051,7 +2058,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
" $loadIndexY | lda #<$value | sta ${segment[2].callLabel},y | lda #>$value | sta ${segment[2].callLabel}+1,y"
|
||||
},
|
||||
// uwordarray[indexvar] = ubyte var
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val loadValueOnStack = when(segment[0].callLabel) {
|
||||
"A" -> " pha"
|
||||
"X" -> " txa | pha"
|
||||
@ -2087,7 +2094,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
" $loadIndexY | lda #<${segment[0].callLabel} | sta ${segment[2].callLabel},y | lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}+1,y"
|
||||
},
|
||||
// uwordarray[indexvar] = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2UWORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
|
||||
val loadIndexY = when(segment[2].callLabel) {
|
||||
"A" -> " asl a | tay"
|
||||
"X" -> " txa | asl a | tay"
|
||||
@ -2109,7 +2116,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
" $loadIndexY | lda ${hexVal(segment[0])} | sta ${segment[2].callLabel},y | lda ${hexValPlusOne(segment[0])} | sta ${segment[2].callLabel}+1,y"
|
||||
},
|
||||
// uwordarray2[indexvar] = ubytearay[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
val loadIndex2Y = when(segment[3].callLabel) {
|
||||
"A" -> " asl a | tay"
|
||||
@ -2132,8 +2139,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
// uwordarray2[index mem] = ubytearray1[index1]
|
||||
AsmPattern(
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD),
|
||||
listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment->
|
||||
val index1 = intVal(segment[0])
|
||||
"""
|
||||
lda ${hexVal(segment[3])}
|
||||
@ -2164,7 +2171,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
|
||||
// ----------- assignment to FLOAT VARIABLE ----------------
|
||||
// floatvar = ubytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val loadByteA = when(segment[0].callLabel) {
|
||||
"A" -> ""
|
||||
"X" -> "txa"
|
||||
@ -2180,7 +2187,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = uwordvar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2192,7 +2199,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = bytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val loadByteA = when(segment[0].callLabel) {
|
||||
"A" -> ""
|
||||
"X" -> "txa"
|
||||
@ -2208,7 +2215,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = wordvar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2257,7 +2264,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = mem byte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_B1}
|
||||
@ -2267,7 +2274,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_B1}
|
||||
@ -2277,7 +2284,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = mem word
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.W2FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2289,7 +2296,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = mem uword
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.UW2FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2302,7 +2309,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
|
||||
// floatvar = bytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2313,7 +2320,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = ubytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2324,7 +2331,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = wordarray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])*2
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2337,7 +2344,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// floatvar = uwordarray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])*2
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2389,7 +2396,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = ubytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.UB2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val loadByteA = when(segment[0].callLabel) {
|
||||
"A" -> ""
|
||||
"X" -> "txa"
|
||||
@ -2405,7 +2412,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = uwordvar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2417,7 +2424,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = bytevar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.B2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val loadByteA = when(segment[0].callLabel) {
|
||||
"A" -> ""
|
||||
"X" -> "txa"
|
||||
@ -2433,7 +2440,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = wordvar
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${segment[0].callLabel}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2445,7 +2452,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = mem byte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.B2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_B1}
|
||||
@ -2455,7 +2462,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = mem ubyte
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.UB2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_B1}
|
||||
@ -2465,7 +2472,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = mem word
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.W2FLOAT, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2477,7 +2484,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = mem uword
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.UW2FLOAT, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment ->
|
||||
"""
|
||||
lda ${hexVal(segment[0])}
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
@ -2501,7 +2508,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = bytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2512,7 +2519,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = ubytearray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2523,7 +2530,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = wordarray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.W2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])*2
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2536,7 +2543,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
},
|
||||
// memfloat = uwordarray[index]
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.UW2FLOAT, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment->
|
||||
val index = intVal(segment[0])*2
|
||||
"""
|
||||
lda ${segment[1].callLabel}+$index
|
||||
@ -2707,8 +2714,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
},
|
||||
|
||||
|
||||
// byte var = lsb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB, Opcode.POP_VAR_BYTE)) { segment ->
|
||||
// byte var = wordvar as (u)byte
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_WRD_TO_UB, Opcode.POP_VAR_BYTE),
|
||||
listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_WRD_TO_B, Opcode.POP_VAR_BYTE)) { segment ->
|
||||
when(segment[2].callLabel) {
|
||||
"A" -> " lda ${segment[0].callLabel}"
|
||||
"X" -> " ldx ${segment[0].callLabel}"
|
||||
@ -2725,8 +2733,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
else -> " lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}"
|
||||
}
|
||||
},
|
||||
// push lsb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.LSB)) { segment ->
|
||||
// push word var as (u)byte
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_WRD_TO_UB),
|
||||
listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_WRD_TO_B)) { segment ->
|
||||
" lda ${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
// push msb(word var)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package prog8.functions
|
||||
|
||||
import prog8.ast.*
|
||||
import prog8.compiler.CompilerException
|
||||
import prog8.compiler.HeapValues
|
||||
import kotlin.math.log2
|
||||
|
||||
@ -46,13 +45,6 @@ val BuiltinFunctions = mapOf(
|
||||
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
||||
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
|
||||
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
|
||||
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), DataType.FLOAT, ::builtinFlt),
|
||||
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.WORD))), DataType.UWORD, ::builtinUwrd),
|
||||
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD))), DataType.WORD, ::builtinWrd),
|
||||
"fintb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.BYTE, ::builtinFintb),
|
||||
"fintw" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD, ::builtinFintw),
|
||||
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
|
||||
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinUb2b),
|
||||
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
|
||||
"rndw" to FunctionSignature(true, emptyList(), DataType.UWORD),
|
||||
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
|
||||
@ -62,6 +54,7 @@ val BuiltinFunctions = mapOf(
|
||||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
// @todo change the string conversion functions into "string as byte" type casts?
|
||||
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.BYTE),
|
||||
"str2ubyte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UBYTE),
|
||||
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.WORD),
|
||||
@ -237,96 +230,6 @@ private fun collectionArgOutputBoolean(args: List<IExpression>, position: Positi
|
||||
return LiteralValue.fromBoolean(result, position)
|
||||
}
|
||||
|
||||
private fun builtinFlt(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 numeric arg, convert to float
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("flt requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val number = constval.asNumericValue ?: throw SyntaxError("flt requires one numeric argument", position)
|
||||
return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinFintb(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 float arg, convert to byte
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("fintb requires one floating point argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.FLOAT)
|
||||
throw SyntaxError("fintb requires one floating point argument", position)
|
||||
val integer: Short
|
||||
val flt = constval.floatvalue!!
|
||||
integer = when {
|
||||
flt <= -128 -> -128
|
||||
flt >= 127 -> 127
|
||||
else -> flt.toShort()
|
||||
}
|
||||
return LiteralValue(DataType.BYTE, bytevalue = integer, position = position)
|
||||
}
|
||||
|
||||
private fun builtinFintw(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 float arg, convert to word
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("fintw requires one floating point argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.FLOAT)
|
||||
throw SyntaxError("fintw requires one floating point argument", position)
|
||||
val integer: Int
|
||||
val flt = constval.floatvalue!!
|
||||
integer = when {
|
||||
flt <= -32768 -> -32768
|
||||
flt >= 32767 -> 32767
|
||||
else -> flt.toInt()
|
||||
}
|
||||
return LiteralValue(DataType.WORD, wordvalue = integer, position = position)
|
||||
}
|
||||
|
||||
private fun builtinWrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to word
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("wrd requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.UBYTE && constval.type!=DataType.BYTE && constval.type!=DataType.UWORD)
|
||||
throw SyntaxError("wrd requires one argument of type ubyte, byte or uword", position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = constval.asIntegerValue, position = position)
|
||||
}
|
||||
|
||||
private fun builtinUwrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 arg, convert to uword
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("uwrd requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE && constval.type!=DataType.WORD && constval.type!=DataType.UWORD)
|
||||
throw SyntaxError("uwrd requires one argument of type byte, word or uword", position)
|
||||
return LiteralValue(DataType.UWORD, wordvalue = constval.asIntegerValue!! and 65535, position = position)
|
||||
}
|
||||
|
||||
private fun builtinB2ub(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to ubyte
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("b2ub requires one byte argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE && constval.type!=DataType.UBYTE)
|
||||
throw SyntaxError("b2ub requires one argument of type byte or ubyte", position)
|
||||
return LiteralValue(DataType.UBYTE, bytevalue=(constval.bytevalue!!.toInt() and 255).toShort(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinUb2b(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 ubyte arg, convert to byte
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("ub2b requires one ubyte argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.UBYTE)
|
||||
throw SyntaxError("ub2b requires one argument of type ubyte", position)
|
||||
return LiteralValue(DataType.BYTE, bytevalue=(constval.bytevalue!!.toInt() and 255).toShort(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 arg, type = float or int, result type= same as argument type
|
||||
if(args.size!=1)
|
||||
|
@ -1,8 +1,6 @@
|
||||
package prog8.stackvm
|
||||
|
||||
import prog8.ast.DataType
|
||||
import prog8.ast.IterableDatatypes
|
||||
import prog8.ast.NumericDatatypes
|
||||
import prog8.ast.*
|
||||
import prog8.compiler.HeapValues
|
||||
import prog8.compiler.intermediate.Instruction
|
||||
import prog8.compiler.intermediate.Opcode
|
||||
@ -39,13 +37,9 @@ enum class Syscall(val callNr: Short) {
|
||||
FUNC_ROUND(79),
|
||||
FUNC_FLOOR(80),
|
||||
FUNC_CEIL(81),
|
||||
FUNC_FINTB(82),
|
||||
FUNC_FINTW(83),
|
||||
FUNC_RND(89), // push a random byte on the stack
|
||||
FUNC_RNDW(90), // push a random word on the stack
|
||||
FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
|
||||
FUNC_WRD(92),
|
||||
FUNC_UWRD(93),
|
||||
FUNC_STR2BYTE(100),
|
||||
FUNC_STR2UBYTE(101),
|
||||
FUNC_STR2WORD(102),
|
||||
@ -955,11 +949,6 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(variable, DataType.FLOAT)
|
||||
variables[ins.callLabel] =variable.dec()
|
||||
}
|
||||
Opcode.LSB -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||
evalstack.push(v.lsb())
|
||||
}
|
||||
Opcode.MSB -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||
@ -1167,49 +1156,6 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(second, DataType.FLOAT)
|
||||
evalstack.push(Value(DataType.UBYTE, if (second != top) 1 else 0))
|
||||
}
|
||||
Opcode.B2UB -> {
|
||||
val byte = evalstack.pop()
|
||||
checkDt(byte, DataType.BYTE)
|
||||
evalstack.push(Value(DataType.UBYTE, byte.integerValue() and 255))
|
||||
}
|
||||
Opcode.UB2B -> {
|
||||
val byte = evalstack.pop()
|
||||
checkDt(byte, DataType.UBYTE)
|
||||
if(byte.integerValue() > 127) {
|
||||
evalstack.push(Value(DataType.BYTE, -((byte.integerValue() xor 255) + 1)))
|
||||
} else
|
||||
evalstack.push(Value(DataType.BYTE, byte.integerValue()))
|
||||
}
|
||||
Opcode.B2WORD -> {
|
||||
val byte = evalstack.pop()
|
||||
checkDt(byte, DataType.BYTE)
|
||||
evalstack.push(Value(DataType.WORD, byte.integerValue()))
|
||||
}
|
||||
Opcode.UB2UWORD -> {
|
||||
val ubyte = evalstack.pop()
|
||||
checkDt(ubyte, DataType.UBYTE)
|
||||
evalstack.push(Value(DataType.UWORD, ubyte.integerValue()))
|
||||
}
|
||||
Opcode.B2FLOAT -> {
|
||||
val byte = evalstack.pop()
|
||||
checkDt(byte, DataType.BYTE)
|
||||
evalstack.push(Value(DataType.FLOAT, byte.integerValue()))
|
||||
}
|
||||
Opcode.UB2FLOAT -> {
|
||||
val byte = evalstack.pop()
|
||||
checkDt(byte, DataType.UBYTE)
|
||||
evalstack.push(Value(DataType.FLOAT, byte.integerValue()))
|
||||
}
|
||||
Opcode.W2FLOAT -> {
|
||||
val wrd = evalstack.pop()
|
||||
checkDt(wrd, DataType.UWORD)
|
||||
evalstack.push(Value(DataType.FLOAT, wrd.integerValue()))
|
||||
}
|
||||
Opcode.UW2FLOAT -> {
|
||||
val uwrd = evalstack.pop()
|
||||
checkDt(uwrd, DataType.UWORD)
|
||||
evalstack.push(Value(DataType.FLOAT, uwrd.integerValue()))
|
||||
}
|
||||
Opcode.READ_INDEXED_VAR_BYTE -> {
|
||||
// put the byte value of variable[index] onto the stack
|
||||
val index = evalstack.pop().integerValue()
|
||||
@ -1399,6 +1345,11 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
throw VmExecutionException("expected string to be on heap")
|
||||
evalstack.push(Value(DataType.UWORD, heapId)) // push the "address" of the string
|
||||
}
|
||||
Opcode.CAST_UB_TO_B, Opcode.CAST_WRD_TO_B, Opcode.CAST_F_TO_B -> typecast(DataType.BYTE)
|
||||
Opcode.CAST_B_TO_UB, Opcode.CAST_WRD_TO_UB, Opcode.CAST_F_TO_UB -> typecast(DataType.UBYTE)
|
||||
Opcode.CAST_UB_TO_UW, Opcode.CAST_B_TO_UW, Opcode.CAST_W_TO_UW, Opcode.CAST_F_TO_UW -> typecast(DataType.UWORD)
|
||||
Opcode.CAST_UB_TO_W, Opcode.CAST_B_TO_W, Opcode.CAST_UW_TO_W, Opcode.CAST_F_TO_W -> typecast(DataType.WORD)
|
||||
Opcode.CAST_UB_TO_F, Opcode.CAST_B_TO_F, Opcode.CAST_UW_TO_F, Opcode.CAST_W_TO_F -> typecast(DataType.FLOAT)
|
||||
|
||||
//else -> throw VmExecutionException("unimplemented opcode: ${ins.opcode}")
|
||||
}
|
||||
@ -1411,6 +1362,13 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
return ins.next
|
||||
}
|
||||
|
||||
private fun typecast(type: DataType) {
|
||||
val value = evalstack.pop()
|
||||
val lv = LiteralValue.optimalNumeric(value.numericValue(), Position("?", 0, 0, 0))
|
||||
val lv2 = TypecastExpression.typecast(lv, type) ?: throw VmExecutionException("type cast error")
|
||||
evalstack.push(Value(lv2.type, lv2.asNumericValue!!))
|
||||
}
|
||||
|
||||
private fun dispatchSyscall(ins: Instruction) {
|
||||
val callId = ins.arg!!.integerValue().toShort()
|
||||
val syscall = Syscall.values().first { it.callNr == callId }
|
||||
@ -1627,69 +1585,7 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
val y = str.str!!.trim().trimEnd('\u0000')
|
||||
evalstack.push(Value(DataType.FLOAT, y.toDouble()))
|
||||
}
|
||||
Syscall.FUNC_FINTB -> {
|
||||
val value = evalstack.pop()
|
||||
if(value.type in NumericDatatypes) {
|
||||
val integer: Short
|
||||
val flt = value.numericValue().toDouble()
|
||||
integer = when {
|
||||
flt <= -128 -> -128
|
||||
flt >= 127 -> 127
|
||||
else -> flt.toShort()
|
||||
}
|
||||
evalstack.push(Value(DataType.BYTE, integer))
|
||||
}
|
||||
else throw VmExecutionException("cannot fintb $value")
|
||||
}
|
||||
Syscall.FUNC_FINTW -> {
|
||||
val value = evalstack.pop()
|
||||
if(value.type in NumericDatatypes) {
|
||||
val integer: Int
|
||||
val flt = value.numericValue().toDouble()
|
||||
integer = when {
|
||||
flt <= -32768 -> -32768
|
||||
flt >= 32767 -> 32767
|
||||
else -> flt.toInt()
|
||||
}
|
||||
evalstack.push(Value(DataType.WORD, integer))
|
||||
}
|
||||
else throw VmExecutionException("cannot fintw $value")
|
||||
}
|
||||
Syscall.FUNC_WRD -> {
|
||||
val value = evalstack.pop()
|
||||
checkDt(value, DataType.UBYTE, DataType.BYTE, DataType.UWORD)
|
||||
when(value.type) {
|
||||
DataType.UBYTE, DataType.BYTE -> evalstack.push(Value(DataType.WORD, value.integerValue()))
|
||||
DataType.UWORD -> {
|
||||
val v2=
|
||||
if(value.integerValue() <= 32767)
|
||||
Value(DataType.WORD, value.integerValue())
|
||||
else
|
||||
Value(DataType.WORD, -((value.integerValue() xor 65535) + 1))
|
||||
evalstack.push(v2)
|
||||
}
|
||||
DataType.WORD -> evalstack.push(value)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
Syscall.FUNC_UWRD -> {
|
||||
val value = evalstack.pop()
|
||||
checkDt(value, DataType.UBYTE, DataType.BYTE, DataType.WORD)
|
||||
when(value.type) {
|
||||
DataType.UBYTE -> evalstack.push(Value(DataType.UWORD, value.integerValue()))
|
||||
DataType.UWORD -> evalstack.push(value)
|
||||
DataType.BYTE, DataType.WORD -> {
|
||||
val v2 =
|
||||
if(value.integerValue()>=0)
|
||||
Value(DataType.UWORD, value.integerValue())
|
||||
else
|
||||
Value(DataType.UWORD, (abs(value.integerValue()) xor 65535) + 1)
|
||||
evalstack.push(v2)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun irq(timestamp: Long) {
|
||||
|
@ -421,22 +421,6 @@ class TestStackVmOpcodes {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLsb() {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 0x45)),
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 0xea31)),
|
||||
Instruction(Opcode.LSB),
|
||||
Instruction(Opcode.LSB)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
assertEquals(Value(DataType.UBYTE, 0x31), vm.evalstack.pop())
|
||||
assertFailsWith<VmExecutionException> {
|
||||
vm.step(1)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMsb() {
|
||||
val ins = mutableListOf(
|
||||
@ -453,13 +437,15 @@ class TestStackVmOpcodes {
|
||||
}
|
||||
}
|
||||
|
||||
// @todo more conversion tests.
|
||||
|
||||
@Test
|
||||
fun testB2Ub() {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.BYTE, -88)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.BYTE, 127)),
|
||||
Instruction(Opcode.B2UB),
|
||||
Instruction(Opcode.B2UB)
|
||||
Instruction(Opcode.CAST_B_TO_UB),
|
||||
Instruction(Opcode.CAST_B_TO_UB)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -473,8 +459,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 168)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 127)),
|
||||
Instruction(Opcode.UB2B),
|
||||
Instruction(Opcode.UB2B)
|
||||
Instruction(Opcode.CAST_UB_TO_B),
|
||||
Instruction(Opcode.CAST_UB_TO_B)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -488,8 +474,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.WORD, 0x7a31)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.BYTE, 127)),
|
||||
Instruction(Opcode.B2WORD),
|
||||
Instruction(Opcode.B2WORD)
|
||||
Instruction(Opcode.CAST_B_TO_W),
|
||||
Instruction(Opcode.CAST_B_TO_W)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -504,8 +490,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 0xea31)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 0x45)),
|
||||
Instruction(Opcode.UB2UWORD),
|
||||
Instruction(Opcode.UB2UWORD)
|
||||
Instruction(Opcode.CAST_UB_TO_UW),
|
||||
Instruction(Opcode.CAST_UB_TO_UW)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -520,8 +506,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.WORD, 0x7a31)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.BYTE, 127)),
|
||||
Instruction(Opcode.B2FLOAT),
|
||||
Instruction(Opcode.B2FLOAT)
|
||||
Instruction(Opcode.CAST_B_TO_F),
|
||||
Instruction(Opcode.CAST_B_TO_F)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -536,8 +522,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 0xea31)),
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 177)),
|
||||
Instruction(Opcode.UB2FLOAT),
|
||||
Instruction(Opcode.UB2FLOAT)
|
||||
Instruction(Opcode.CAST_UB_TO_F),
|
||||
Instruction(Opcode.CAST_UB_TO_F)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -552,8 +538,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 177)),
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 52345)),
|
||||
Instruction(Opcode.W2FLOAT),
|
||||
Instruction(Opcode.W2FLOAT)
|
||||
Instruction(Opcode.CAST_W_TO_F),
|
||||
Instruction(Opcode.CAST_W_TO_F)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
@ -568,8 +554,8 @@ class TestStackVmOpcodes {
|
||||
val ins = mutableListOf(
|
||||
Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, 177)),
|
||||
Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 52345)),
|
||||
Instruction(Opcode.UW2FLOAT),
|
||||
Instruction(Opcode.UW2FLOAT)
|
||||
Instruction(Opcode.CAST_UW_TO_F),
|
||||
Instruction(Opcode.CAST_UW_TO_F)
|
||||
)
|
||||
vm.load(makeProg(ins), null)
|
||||
vm.step(3)
|
||||
|
@ -435,8 +435,9 @@ You can also reference idendifiers defined elsewhere in your code.
|
||||
Calculations with integers will not result in floating point values;
|
||||
if you divide two integer values (say: ``32500 / 99``) the result will be the integer floor
|
||||
division (328) rather than the floating point result (328.2828282828283). If you need the full precision,
|
||||
you'll have to write ``flt(32500) / 99`` (or if they're constants, simply ``32500.0 / 99``), to make sure the
|
||||
first operand is a floating point value.
|
||||
you'll have to make sure at least the first operand is a floating point. So write ``32500.0 / 99.0``,
|
||||
or use the type cast ``value as float``.
|
||||
|
||||
|
||||
|
||||
Arithmetic and Logical expressions
|
||||
@ -542,35 +543,11 @@ len(x)
|
||||
Note: this can be different from the number of *bytes* in memory if the datatype isn't a byte.
|
||||
|
||||
lsb(x)
|
||||
Get the least significant byte of the word x.
|
||||
Get the least significant byte of the word x. Equivalent to the cast "x as ubyte".
|
||||
|
||||
msb(x)
|
||||
Get the most significant byte of the word x.
|
||||
|
||||
flt(x)
|
||||
Explicitly convert the number x to a floating point number.
|
||||
This is required if you want calculations to have floating point precision when the values aren't float already.
|
||||
|
||||
fintb(x)
|
||||
Take floor of the floating point into a byte value. (no overflow check). Use together with b2ub() to convert into a unsigned byte instead.
|
||||
|
||||
fintw(x)
|
||||
Take floor of the floating point into a word value. (no overflow check).
|
||||
|
||||
wrd(x)
|
||||
Explicitly convert the value x to a signed word (sign extended).
|
||||
This is required if you want calculations to have word precision when the values are different types.
|
||||
|
||||
uwrd(x)
|
||||
Explicitly convert the byte x to an unsigned word.
|
||||
This is required if you want calculations to have unsigned word precision when the values are different types.
|
||||
|
||||
b2ub(x)
|
||||
Convert signed byte to unsinged byte. Uses 2's complement if dealing with a negative number.
|
||||
|
||||
ub2b(x)
|
||||
Convert an unsigned byte to a signed byte. Uses 2's complement to deal with negative numbers.
|
||||
|
||||
any(x)
|
||||
1 ('true') if any of the values in the array value x is 'true' (not zero), else 0 ('false')
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user