mirror of
https://github.com/irmen/prog8.git
synced 2024-09-29 08:57:51 +00:00
fix datatype conversion issues
This commit is contained in:
parent
cc54e3ec99
commit
7aec14524e
@ -37,7 +37,7 @@
|
|||||||
_vm_gfx_text(8, 6, 1, "Spin")
|
_vm_gfx_text(8, 6, 1, "Spin")
|
||||||
_vm_gfx_text(29, 11, 1, "to Win !")
|
_vm_gfx_text(29, 11, 1, "to Win !")
|
||||||
|
|
||||||
for ubyte i in 0 to width//10 {
|
for uword i in 0 to width//10 {
|
||||||
_vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
|
_vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
if attempts_left>1 _vm_write_str("es")
|
if attempts_left>1 _vm_write_str("es")
|
||||||
_vm_write_str(" left. What is your next guess? ")
|
_vm_write_str(" left. What is your next guess? ")
|
||||||
_vm_input_str(guess)
|
_vm_input_str(guess)
|
||||||
ubyte guessednumber = str2byte(guess)
|
ubyte guessednumber = str2ubyte(guess)
|
||||||
if guessednumber==secretnumber {
|
if guessednumber==secretnumber {
|
||||||
_vm_write_str("\nYou guessed it, impressive!\n")
|
_vm_write_str("\nYou guessed it, impressive!\n")
|
||||||
_vm_write_str("Thanks for playing.\n")
|
_vm_write_str("Thanks for playing.\n")
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub screenx(x: float) -> uword {
|
sub screenx(x: float) -> word {
|
||||||
return floor(x * flt(width)/4.1) + width // 2
|
return floor(x * flt(width)/4.1) + width // 2
|
||||||
}
|
}
|
||||||
sub screeny(y: float) -> uword {
|
sub screeny(y: float) -> word {
|
||||||
return floor(y * flt(height)/4.1) + height // 2
|
return floor(y * flt(height)/4.1) + height // 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,37 +3,31 @@
|
|||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
const uword width=320
|
|
||||||
const uword height=200
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
byte[4] barr1 = -2
|
byte bvar = -88
|
||||||
byte[4] barr2 = 33
|
ubyte ubvar = 222
|
||||||
ubyte[4] barr4 = 2
|
word wvar = -12345
|
||||||
ubyte[4] barr5 = 44
|
uword uwvar = 55555
|
||||||
word[4] warr1 = 4444
|
|
||||||
word[4] warr2 = -5555
|
|
||||||
word[4] warr2b = -5522
|
|
||||||
float[4] farr1
|
|
||||||
float[4] farr2 = 23
|
|
||||||
float[4] farr3 = 55.636346
|
|
||||||
|
|
||||||
; byte b1 = 50 * 2
|
|
||||||
; byte b2 = -50 * 2
|
byte bv2
|
||||||
; ubyte ub1 = 50 * 2
|
ubyte ubv2
|
||||||
; word w1 = 999 * 2
|
word wv2
|
||||||
; word w2 = -999 * 2
|
uword uwv2
|
||||||
; uword uw1 = 999 * 2
|
|
||||||
; float f1 = 999*2
|
|
||||||
; float f2 = -999*2
|
bv2 = ub2b(ubvar)
|
||||||
|
ubv2 = b2ub(bvar)
|
||||||
|
wv2 = wrd(uwvar)
|
||||||
|
uwv2 = uwrd(wvar)
|
||||||
|
wv2 = wrd(ubvar)
|
||||||
|
wv2 = wrd(bvar)
|
||||||
|
uwv2 = uwrd(ubvar)
|
||||||
|
uwv2 = uwrd(bvar)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; sub toscreenx(x: float, z: float) -> word {
|
|
||||||
; return floor(x/(4.2+z) * flt(height)) + width // 2
|
|
||||||
; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import prog8.parser.ParsingFailedError
|
|||||||
import prog8.parser.importModule
|
import prog8.parser.importModule
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
@ -983,6 +983,7 @@ class LiteralValue(val type: DataType,
|
|||||||
if(strvalue==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId")
|
if(strvalue==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId")
|
||||||
in ArrayDatatypes ->
|
in ArrayDatatypes ->
|
||||||
if(arrayvalue==null && heapId==null) throw FatalAstException("literal value missing arrayvalue/heapId")
|
if(arrayvalue==null && heapId==null) throw FatalAstException("literal value missing arrayvalue/heapId")
|
||||||
|
else -> throw FatalAstException("invalid type $type")
|
||||||
}
|
}
|
||||||
if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null && heapId==null)
|
if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null && heapId==null)
|
||||||
throw FatalAstException("literal value without actual value")
|
throw FatalAstException("literal value without actual value")
|
||||||
|
@ -93,8 +93,9 @@ class AstChecker(private val namespace: INameScope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (rv in expectedReturnValues.withIndex().zip(returnStmt.values)) {
|
for (rv in expectedReturnValues.withIndex().zip(returnStmt.values)) {
|
||||||
if(rv.first.value!=rv.second.resultingDatatype(namespace, heap))
|
val valueDt=rv.second.resultingDatatype(namespace, heap)
|
||||||
checkResult.add(ExpressionError("type of return value #${rv.first.index+1} doesn't match subroutine return type ${rv.first.value}", rv.second.position))
|
if(rv.first.value!=valueDt)
|
||||||
|
checkResult.add(ExpressionError("type $valueDt of return value #${rv.first.index+1} doesn't match subroutine return type ${rv.first.value}", rv.second.position))
|
||||||
}
|
}
|
||||||
return super.process(returnStmt)
|
return super.process(returnStmt)
|
||||||
}
|
}
|
||||||
|
@ -950,6 +950,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
|||||||
|
|
||||||
private fun translateFunctionCall(funcname: String, args: List<IExpression>) {
|
private fun translateFunctionCall(funcname: String, args: List<IExpression>) {
|
||||||
// some functions are implemented as vm opcodes
|
// some functions are implemented as vm opcodes
|
||||||
|
// note: the arguments of the call have already been translated and put on the eval stack!
|
||||||
when (funcname) {
|
when (funcname) {
|
||||||
"flt" -> {
|
"flt" -> {
|
||||||
// 1 argument, type determines the exact opcode to use
|
// 1 argument, type determines the exact opcode to use
|
||||||
@ -965,8 +966,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
|||||||
}
|
}
|
||||||
"msb" -> stackvmProg.instr(Opcode.MSB)
|
"msb" -> stackvmProg.instr(Opcode.MSB)
|
||||||
"lsb" -> stackvmProg.instr(Opcode.LSB)
|
"lsb" -> stackvmProg.instr(Opcode.LSB)
|
||||||
"wrd" -> stackvmProg.instr(Opcode.B2WORD)
|
"b2ub" -> stackvmProg.instr(Opcode.B2UB)
|
||||||
"wrdhi" -> stackvmProg.instr(Opcode.MSB2WORD)
|
"ub2b" -> stackvmProg.instr(Opcode.UB2B)
|
||||||
"lsl" -> {
|
"lsl" -> {
|
||||||
val arg = args.single()
|
val arg = args.single()
|
||||||
when (arg.resultingDatatype(namespace, heap)) {
|
when (arg.resultingDatatype(namespace, heap)) {
|
||||||
|
@ -6,7 +6,7 @@ import kotlin.math.log2
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BuiltinFunctionParam(val name: String, val possibleDatatypes: List<DataType>)
|
class BuiltinFunctionParam(val name: String, val possibleDatatypes: Set<DataType>)
|
||||||
|
|
||||||
class FunctionSignature(val pure: Boolean, // does it have side effects?
|
class FunctionSignature(val pure: Boolean, // does it have side effects?
|
||||||
val parameters: List<BuiltinFunctionParam>,
|
val parameters: List<BuiltinFunctionParam>,
|
||||||
@ -15,43 +15,42 @@ class FunctionSignature(val pure: Boolean, // does it have side effects?
|
|||||||
|
|
||||||
|
|
||||||
val BuiltinFunctions = mapOf(
|
val BuiltinFunctions = mapOf(
|
||||||
"rol" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"rol" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
"sin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
|
"sin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
|
||||||
"cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
|
"cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
|
||||||
"acos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
|
"acos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
|
||||||
"asin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
|
"asin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
|
||||||
"tan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
|
"tan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
|
||||||
"atan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
|
"atan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
|
||||||
"ln" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
|
"ln" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
|
||||||
"log2" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
|
"log2" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
|
||||||
"log10" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
|
"log10" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
|
||||||
"sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
|
"sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
|
||||||
"rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
|
"rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
|
||||||
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
||||||
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), DataType.FLOAT, ::builtinAvg),
|
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.FLOAT, ::builtinAvg),
|
||||||
"abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT, ::builtinAbs),
|
"abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT, ::builtinAbs),
|
||||||
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
|
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) },
|
||||||
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
|
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) },
|
||||||
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
|
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) },
|
||||||
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
||||||
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
||||||
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
|
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
|
||||||
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes.toList())), DataType.UWORD, ::builtinLen),
|
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes)), DataType.UWORD, ::builtinLen),
|
||||||
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
||||||
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), DataType.UBYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
"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", listOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
|
"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", listOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 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.toList())), DataType.FLOAT, ::builtinFlt),
|
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), DataType.FLOAT, ::builtinFlt),
|
||||||
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.UBYTE, DataType.BYTE, DataType.WORD))), DataType.UWORD, ::builtinUwrd),
|
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.WORD))), DataType.UWORD, ::builtinUwrd),
|
||||||
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD))), DataType.WORD, ::builtinWrd),
|
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD))), DataType.WORD, ::builtinWrd),
|
||||||
"uwrdhi" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.UBYTE, DataType.BYTE))), DataType.UWORD, ::builtinWrdHi),
|
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
|
||||||
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
|
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UBYTE))), DataType.BYTE, ::builtinUb2b),
|
||||||
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.UBYTE))), DataType.BYTE, ::builtinUb2b),
|
|
||||||
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
|
"rnd" to FunctionSignature(true, emptyList(), DataType.UBYTE),
|
||||||
"rndw" to FunctionSignature(true, emptyList(), DataType.UWORD),
|
"rndw" to FunctionSignature(true, emptyList(), DataType.UWORD),
|
||||||
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
|
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
|
||||||
@ -59,33 +58,33 @@ val BuiltinFunctions = mapOf(
|
|||||||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||||
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.BYTE),
|
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.BYTE),
|
||||||
"str2ubyte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.UBYTE),
|
"str2ubyte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UBYTE),
|
||||||
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.WORD),
|
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.WORD),
|
||||||
"str2uword" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.UWORD),
|
"str2uword" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UWORD),
|
||||||
"str2float" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.FLOAT),
|
"str2float" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.FLOAT),
|
||||||
"_vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.UWORD))), null),
|
"_vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
|
||||||
"_vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.UWORD))), null),
|
"_vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
|
||||||
"_vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes.toList())), null),
|
"_vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes)), null),
|
||||||
"_vm_write_char" to FunctionSignature(false, listOf(BuiltinFunctionParam("char", listOf(DataType.UBYTE))), null),
|
"_vm_write_char" to FunctionSignature(false, listOf(BuiltinFunctionParam("char", setOf(DataType.UBYTE))), null),
|
||||||
"_vm_write_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), null),
|
"_vm_write_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("string", StringDatatypes)), null),
|
||||||
"_vm_input_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("intovar", StringDatatypes.toList())), null),
|
"_vm_input_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("intovar", StringDatatypes)), null),
|
||||||
"_vm_gfx_clearscr" to FunctionSignature(false, listOf(BuiltinFunctionParam("color", listOf(DataType.UBYTE))), null),
|
"_vm_gfx_clearscr" to FunctionSignature(false, listOf(BuiltinFunctionParam("color", setOf(DataType.UBYTE))), null),
|
||||||
"_vm_gfx_pixel" to FunctionSignature(false, listOf(
|
"_vm_gfx_pixel" to FunctionSignature(false, listOf(
|
||||||
BuiltinFunctionParam("x", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("x", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("y", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("y", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("color", IntegerDatatypes.toList())), null),
|
BuiltinFunctionParam("color", IntegerDatatypes)), null),
|
||||||
"_vm_gfx_line" to FunctionSignature(false, listOf(
|
"_vm_gfx_line" to FunctionSignature(false, listOf(
|
||||||
BuiltinFunctionParam("x1", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("x1", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("y1", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("y1", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("x2", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("x2", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("y2", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("y2", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("color", IntegerDatatypes.toList())), null),
|
BuiltinFunctionParam("color", IntegerDatatypes)), null),
|
||||||
"_vm_gfx_text" to FunctionSignature(false, listOf(
|
"_vm_gfx_text" to FunctionSignature(false, listOf(
|
||||||
BuiltinFunctionParam("x", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("x", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("y", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("y", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("color", IntegerDatatypes.toList()),
|
BuiltinFunctionParam("color", IntegerDatatypes),
|
||||||
BuiltinFunctionParam("text", StringDatatypes.toList())),
|
BuiltinFunctionParam("text", StringDatatypes)),
|
||||||
null)
|
null)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -272,17 +271,6 @@ private fun builtinUwrd(args: List<IExpression>, position: Position, namespace:I
|
|||||||
return LiteralValue(DataType.UWORD, wordvalue = constval.bytevalue!!.toInt(), position = position)
|
return LiteralValue(DataType.UWORD, wordvalue = constval.bytevalue!!.toInt(), position = position)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun builtinWrdHi(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
|
||||||
// 1 arg, convert to word (in hi byte)
|
|
||||||
if(args.size!=1)
|
|
||||||
throw SyntaxError("wrdhi requires one numeric argument", position)
|
|
||||||
|
|
||||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
|
||||||
if(constval.type!=DataType.UBYTE)
|
|
||||||
throw SyntaxError("wrdhi requires one byte argument", position)
|
|
||||||
return LiteralValue(DataType.UWORD, wordvalue = constval.bytevalue!!.toInt() shl 8, position = position)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun builtinB2ub(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
private fun builtinB2ub(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||||
// 1 byte arg, convert to ubyte
|
// 1 byte arg, convert to ubyte
|
||||||
if(args.size!=1)
|
if(args.size!=1)
|
||||||
@ -291,7 +279,7 @@ private fun builtinB2ub(args: List<IExpression>, position: Position, namespace:I
|
|||||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||||
if(constval.type!=DataType.BYTE)
|
if(constval.type!=DataType.BYTE)
|
||||||
throw SyntaxError("b2ub requires one argument of type byte", position)
|
throw SyntaxError("b2ub requires one argument of type byte", position)
|
||||||
return LiteralValue(DataType.UBYTE, bytevalue=constval.bytevalue!!, position = 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 {
|
private fun builtinUb2b(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||||
@ -302,7 +290,7 @@ private fun builtinUb2b(args: List<IExpression>, position: Position, namespace:I
|
|||||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||||
if(constval.type!=DataType.UBYTE)
|
if(constval.type!=DataType.UBYTE)
|
||||||
throw SyntaxError("ub2b requires one argument of type ubyte", position)
|
throw SyntaxError("ub2b requires one argument of type ubyte", position)
|
||||||
return LiteralValue(DataType.BYTE, bytevalue=constval.bytevalue!!, position = 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 {
|
private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||||
|
@ -35,6 +35,16 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
|||||||
val constTrue = LiteralValue.fromBoolean(true, expr.position)
|
val constTrue = LiteralValue.fromBoolean(true, expr.position)
|
||||||
val constFalse = LiteralValue.fromBoolean(false, expr.position)
|
val constFalse = LiteralValue.fromBoolean(false, expr.position)
|
||||||
|
|
||||||
|
val leftDt = expr.left.resultingDatatype(namespace, heap)
|
||||||
|
val rightDt = expr.right.resultingDatatype(namespace, heap)
|
||||||
|
if(leftDt!=null && rightDt!=null && leftDt!=rightDt) {
|
||||||
|
// try to convert a datatype into the other
|
||||||
|
if(adjustDatatypes(expr, leftVal, leftDt, rightVal, rightDt)) {
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// simplify logical expressions when a term is constant and determines the outcome
|
// simplify logical expressions when a term is constant and determines the outcome
|
||||||
when(expr.operator) {
|
when(expr.operator) {
|
||||||
"or" -> {
|
"or" -> {
|
||||||
@ -112,6 +122,87 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
|||||||
return expr
|
return expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun adjustDatatypes(expr: BinaryExpression,
|
||||||
|
leftConstVal: LiteralValue?, leftDt: DataType,
|
||||||
|
rightConstVal: LiteralValue?, rightDt: DataType): Boolean {
|
||||||
|
|
||||||
|
fun adjust(value: LiteralValue, targetDt: DataType): Pair<Boolean, LiteralValue>{
|
||||||
|
if(value.type==targetDt)
|
||||||
|
return Pair(false, value)
|
||||||
|
when(value.type) {
|
||||||
|
DataType.UBYTE -> {
|
||||||
|
if (targetDt == DataType.BYTE) {
|
||||||
|
if(value.bytevalue!! < 127)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.bytevalue, position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.UWORD || targetDt == DataType.WORD)
|
||||||
|
return Pair(true, LiteralValue(targetDt, wordvalue = value.bytevalue!!.toInt(), position=value.position))
|
||||||
|
}
|
||||||
|
DataType.BYTE -> {
|
||||||
|
if (targetDt == DataType.UBYTE) {
|
||||||
|
if(value.bytevalue!! >= 0)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.bytevalue, position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.UWORD) {
|
||||||
|
if(value.bytevalue!! >= 0)
|
||||||
|
return Pair(true, LiteralValue(targetDt, wordvalue=value.bytevalue.toInt(), position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.WORD) return Pair(true, LiteralValue(targetDt, wordvalue=value.bytevalue!!.toInt(), position=value.position))
|
||||||
|
}
|
||||||
|
DataType.UWORD -> {
|
||||||
|
if (targetDt == DataType.UBYTE) {
|
||||||
|
if(value.wordvalue!! <= 255)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.wordvalue.toShort(), position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.BYTE) {
|
||||||
|
if(value.wordvalue!! <= 127)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.wordvalue.toShort(), position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.WORD) {
|
||||||
|
if(value.wordvalue!! <= 32767)
|
||||||
|
return Pair(true, LiteralValue(targetDt, wordvalue=value.wordvalue, position=value.position))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.WORD -> {
|
||||||
|
if (targetDt == DataType.UBYTE) {
|
||||||
|
if(value.wordvalue!! in 0..255)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.wordvalue.toShort(), position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.BYTE) {
|
||||||
|
if(value.wordvalue!! in -128..127)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.wordvalue.toShort(), position=value.position))
|
||||||
|
}
|
||||||
|
else if (targetDt == DataType.UWORD) {
|
||||||
|
if(value.wordvalue!! >= 0)
|
||||||
|
return Pair(true, LiteralValue(targetDt, value.wordvalue.toShort(), position=value.position))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
return Pair(false, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(leftConstVal==null && rightConstVal!=null) {
|
||||||
|
val (adjusted, newValue) = adjust(rightConstVal, leftDt)
|
||||||
|
if(adjusted) {
|
||||||
|
expr.right = newValue
|
||||||
|
optimizationsDone++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} else if(leftConstVal!=null && rightConstVal==null) {
|
||||||
|
val (adjusted, newValue) = adjust(leftConstVal, rightDt)
|
||||||
|
if(adjusted) {
|
||||||
|
expr.left = newValue
|
||||||
|
optimizationsDone++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
throw AstException("binary expression with 2 const values should have been evaluated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private data class ReorderedAssociativeBinaryExpr(val expr: BinaryExpression, val leftVal: LiteralValue?, val rightVal: LiteralValue?)
|
private data class ReorderedAssociativeBinaryExpr(val expr: BinaryExpression, val leftVal: LiteralValue?, val rightVal: LiteralValue?)
|
||||||
|
|
||||||
private fun reorderAssociative(expr: BinaryExpression, leftVal: LiteralValue?): ReorderedAssociativeBinaryExpr {
|
private fun reorderAssociative(expr: BinaryExpression, leftVal: LiteralValue?): ReorderedAssociativeBinaryExpr {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
||||||
package prog8.parser;
|
package prog8.parser;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
|
||||||
import org.antlr.v4.runtime.CharStream;
|
|
||||||
import org.antlr.v4.runtime.Token;
|
|
||||||
import org.antlr.v4.runtime.TokenStream;
|
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.runtime.atn.*;
|
import org.antlr.v4.runtime.atn.ATN;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||||
|
import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
||||||
|
import org.antlr.v4.runtime.atn.PredictionContextCache;
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.misc.*;
|
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||||
public class prog8Lexer extends Lexer {
|
public class prog8Lexer extends Lexer {
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
||||||
package prog8.parser;
|
package prog8.parser;
|
||||||
import org.antlr.v4.runtime.atn.*;
|
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.runtime.misc.*;
|
import org.antlr.v4.runtime.atn.ATN;
|
||||||
import org.antlr.v4.runtime.tree.*;
|
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||||
|
import org.antlr.v4.runtime.atn.ParserATNSimulator;
|
||||||
|
import org.antlr.v4.runtime.atn.PredictionContextCache;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||||
public class prog8Parser extends Parser {
|
public class prog8Parser extends Parser {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package prog8.stackvm
|
package prog8.stackvm
|
||||||
|
|
||||||
import prog8.ast.*
|
import prog8.ast.DataType
|
||||||
|
import prog8.ast.IterableDatatypes
|
||||||
|
import prog8.ast.NumericDatatypes
|
||||||
import prog8.compiler.HeapValues
|
import prog8.compiler.HeapValues
|
||||||
import prog8.compiler.target.c64.Petscii
|
import prog8.compiler.target.c64.Petscii
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -130,7 +132,9 @@ enum class Opcode {
|
|||||||
// numeric type conversions
|
// numeric type conversions
|
||||||
LSB,
|
LSB,
|
||||||
MSB,
|
MSB,
|
||||||
B2WORD, // convert a byte into a word where it is the lower eight bits $00xx with sign extension
|
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
|
UB2UWORD, // convert a byte into a word where it is the lower eight bits $00xx
|
||||||
MSB2WORD, // convert a byte into a word where it is the upper eight bits $xx00
|
MSB2WORD, // convert a byte into a word where it is the upper eight bits $xx00
|
||||||
B2FLOAT, // convert byte into floating point
|
B2FLOAT, // convert byte into floating point
|
||||||
@ -284,9 +288,13 @@ enum class Syscall(val callNr: Short) {
|
|||||||
FUNC_RND(89), // push a random byte on the stack
|
FUNC_RND(89), // push a random byte on the stack
|
||||||
FUNC_RNDW(90), // push a random word 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_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
|
||||||
FUNC_STR2BYTE(92),
|
FUNC_WRD(92),
|
||||||
FUNC_STR2WORD(93),
|
FUNC_UWRD(93),
|
||||||
FUNC_STR2FLOAT(94)
|
FUNC_STR2BYTE(100),
|
||||||
|
FUNC_STR2UBYTE(101),
|
||||||
|
FUNC_STR2WORD(102),
|
||||||
|
FUNC_STR2UWORD(103),
|
||||||
|
FUNC_STR2FLOAT(104)
|
||||||
|
|
||||||
// note: not all builtin functions of the Prog8 language are present as functions:
|
// note: not all builtin functions of the Prog8 language are present as functions:
|
||||||
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL_BYTE, ROR, ROL2, ROR2, and FLT)!
|
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL_BYTE, ROR, ROL2, ROR2, and FLT)!
|
||||||
@ -1064,7 +1072,7 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
}
|
}
|
||||||
Opcode.PUSH_VAR_WORD -> {
|
Opcode.PUSH_VAR_WORD -> {
|
||||||
val value = variables[ins.callLabel] ?: throw VmExecutionException("unknown variable: ${ins.callLabel}")
|
val value = variables[ins.callLabel] ?: throw VmExecutionException("unknown variable: ${ins.callLabel}")
|
||||||
checkDt(value, setOf(DataType.UWORD, DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.MATRIX_UB))
|
checkDt(value, setOf(DataType.UWORD, DataType.WORD, DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.MATRIX_UB))
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
}
|
}
|
||||||
Opcode.PUSH_VAR_FLOAT -> {
|
Opcode.PUSH_VAR_FLOAT -> {
|
||||||
@ -1452,6 +1460,19 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
checkDt(second, DataType.FLOAT)
|
checkDt(second, DataType.FLOAT)
|
||||||
evalstack.push(Value(DataType.UBYTE, if(second != top) 1 else 0))
|
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 -> {
|
Opcode.B2WORD -> {
|
||||||
val byte = evalstack.pop()
|
val byte = evalstack.pop()
|
||||||
checkDt(byte, DataType.BYTE)
|
checkDt(byte, DataType.BYTE)
|
||||||
@ -1787,19 +1808,67 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
val strvar = evalstack.pop()
|
val strvar = evalstack.pop()
|
||||||
val str = heap.get(strvar.heapId)
|
val str = heap.get(strvar.heapId)
|
||||||
val y = str.str!!.trim().trimEnd('\u0000')
|
val y = str.str!!.trim().trimEnd('\u0000')
|
||||||
evalstack.push(Value(DataType.UBYTE, y.toShort()))
|
evalstack.push(Value(DataType.BYTE, y.toShort()))
|
||||||
|
}
|
||||||
|
Syscall.FUNC_STR2UBYTE -> {
|
||||||
|
val strvar = evalstack.pop()
|
||||||
|
val str = heap.get(strvar.heapId)
|
||||||
|
val y = str.str!!.trim().trimEnd('\u0000')
|
||||||
|
val number = (y.toInt() and 255).toShort()
|
||||||
|
evalstack.push(Value(DataType.UBYTE, number))
|
||||||
}
|
}
|
||||||
Syscall.FUNC_STR2WORD -> {
|
Syscall.FUNC_STR2WORD -> {
|
||||||
val strvar = evalstack.pop()
|
val strvar = evalstack.pop()
|
||||||
val str = heap.get(strvar.heapId)
|
val str = heap.get(strvar.heapId)
|
||||||
val y = str.str!!.trim().trimEnd('\u0000')
|
val y = str.str!!.trim().trimEnd('\u0000')
|
||||||
evalstack.push(Value(DataType.UBYTE, y.toInt()))
|
evalstack.push(Value(DataType.WORD, y.toInt()))
|
||||||
|
}
|
||||||
|
Syscall.FUNC_STR2UWORD -> {
|
||||||
|
val strvar = evalstack.pop()
|
||||||
|
val str = heap.get(strvar.heapId)
|
||||||
|
val y = str.str!!.trim().trimEnd('\u0000')
|
||||||
|
val number = y.toInt() and 65535
|
||||||
|
evalstack.push(Value(DataType.UWORD, number))
|
||||||
}
|
}
|
||||||
Syscall.FUNC_STR2FLOAT -> {
|
Syscall.FUNC_STR2FLOAT -> {
|
||||||
val strvar = evalstack.pop()
|
val strvar = evalstack.pop()
|
||||||
val str = heap.get(strvar.heapId)
|
val str = heap.get(strvar.heapId)
|
||||||
val y = str.str!!.trim().trimEnd('\u0000')
|
val y = str.str!!.trim().trimEnd('\u0000')
|
||||||
evalstack.push(Value(DataType.UBYTE, y.toDouble()))
|
evalstack.push(Value(DataType.FLOAT, y.toDouble()))
|
||||||
|
}
|
||||||
|
Syscall.FUNC_WRD -> {
|
||||||
|
val value = evalstack.pop()
|
||||||
|
checkDt(value, setOf(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, setOf(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 -> {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,14 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
|||||||
throw VmExecutionException("left and right datatypes are not the same")
|
throw VmExecutionException("left and right datatypes are not the same")
|
||||||
if(result.toDouble() < 0 ) {
|
if(result.toDouble() < 0 ) {
|
||||||
return when(leftDt) {
|
return when(leftDt) {
|
||||||
DataType.UBYTE, DataType.UWORD -> throw VmExecutionException("arithmetic error: cannot store a negative value in a $leftDt")
|
DataType.UBYTE, DataType.UWORD -> {
|
||||||
|
// storing a negative number in an unsigned one is done by storing the 2's complement instead
|
||||||
|
val number = abs(result.toDouble().toInt())
|
||||||
|
if(leftDt==DataType.UBYTE)
|
||||||
|
Value(DataType.UBYTE, (number xor 255) +1)
|
||||||
|
else
|
||||||
|
Value(DataType.UBYTE, (number xor 65535) +1)
|
||||||
|
}
|
||||||
DataType.BYTE -> Value(DataType.BYTE, result.toInt())
|
DataType.BYTE -> Value(DataType.BYTE, result.toInt())
|
||||||
DataType.WORD -> Value(DataType.WORD, result.toInt())
|
DataType.WORD -> Value(DataType.WORD, result.toInt())
|
||||||
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
||||||
|
@ -509,6 +509,36 @@ class TestStackVmOpcodes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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)
|
||||||
|
)
|
||||||
|
vm.load(makeProg(ins), null)
|
||||||
|
vm.step(3)
|
||||||
|
assertEquals(Value(DataType.UBYTE, 127), vm.evalstack.pop())
|
||||||
|
vm.step(1)
|
||||||
|
assertEquals(Value(DataType.UBYTE, 168), vm.evalstack.pop())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUB2b() {
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
vm.load(makeProg(ins), null)
|
||||||
|
vm.step(3)
|
||||||
|
assertEquals(Value(DataType.BYTE, 127), vm.evalstack.pop())
|
||||||
|
vm.step(1)
|
||||||
|
assertEquals(Value(DataType.BYTE, -88), vm.evalstack.pop())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testB2Word() {
|
fun testB2Word() {
|
||||||
val ins = mutableListOf(
|
val ins = mutableListOf(
|
||||||
@ -703,11 +733,17 @@ class TestStackVmOpcodes {
|
|||||||
@Test
|
@Test
|
||||||
fun testLess() {
|
fun testLess() {
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.LESS_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.LESS_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.LESS_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.LESS_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, 1), Opcode.LESS_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, -2), Opcode.LESS_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.LESS_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.LESS_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESS_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, 21), Opcode.LESS_W, Value(DataType.WORD, 21), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, -2), Opcode.LESS_W, Value(DataType.WORD, 1), Value(DataType.UBYTE, 1))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESS_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESS_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESS_F, Value(DataType.FLOAT, 21.001), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESS_F, Value(DataType.FLOAT, 21.001), Value(DataType.UBYTE, 1))
|
||||||
}
|
}
|
||||||
@ -716,10 +752,16 @@ class TestStackVmOpcodes {
|
|||||||
fun testLessEq() {
|
fun testLessEq() {
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.LESSEQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.LESSEQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.LESSEQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.LESSEQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, 1), Opcode.LESSEQ_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, -2), Opcode.LESSEQ_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.LESSEQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.LESSEQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.LESSEQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.LESSEQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESSEQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESSEQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESSEQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.LESSEQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, 21), Opcode.LESSEQ_W, Value(DataType.WORD, 20), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, -2), Opcode.LESSEQ_W, Value(DataType.WORD, 1), Value(DataType.UBYTE, 1))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESSEQ_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESSEQ_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESSEQ_F, Value(DataType.FLOAT, 20.999), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.LESSEQ_F, Value(DataType.FLOAT, 20.999), Value(DataType.UBYTE, 0))
|
||||||
}
|
}
|
||||||
@ -728,10 +770,16 @@ class TestStackVmOpcodes {
|
|||||||
fun testGreater() {
|
fun testGreater() {
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.GREATER_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.GREATER_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.GREATER_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.GREATER_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, 1), Opcode.GREATER_B, Value(DataType.BYTE, -1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, -1), Opcode.GREATER_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 0))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.GREATER_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.GREATER_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.GREATER_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.GREATER_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATER_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATER_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATER_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATER_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, 21), Opcode.GREATER_W, Value(DataType.WORD, -21), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, -2), Opcode.GREATER_W, Value(DataType.WORD, 21), Value(DataType.UBYTE, 0))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATER_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATER_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATER_F, Value(DataType.FLOAT, 20.999), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATER_F, Value(DataType.FLOAT, 20.999), Value(DataType.UBYTE, 1))
|
||||||
}
|
}
|
||||||
@ -740,10 +788,16 @@ class TestStackVmOpcodes {
|
|||||||
fun testGreaterEq() {
|
fun testGreaterEq() {
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.GREATEREQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UBYTE, 0), Opcode.GREATEREQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.GREATEREQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UBYTE, 1), Opcode.GREATEREQ_UB, Value(DataType.UBYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, 1), Opcode.GREATEREQ_B, Value(DataType.BYTE, 1), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.BYTE, -11), Opcode.GREATEREQ_B, Value(DataType.BYTE, 11), Value(DataType.UBYTE, 0))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 2), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.UWORD, 20), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 0))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 20), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.UWORD, 21), Opcode.GREATEREQ_UW, Value(DataType.UWORD, 21), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, 21), Opcode.GREATEREQ_W, Value(DataType.WORD, 21), Value(DataType.UBYTE, 1))
|
||||||
|
testBinaryOperator(Value(DataType.WORD, -21), Opcode.GREATEREQ_W, Value(DataType.WORD, 21), Value(DataType.UBYTE, 0))
|
||||||
|
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATEREQ_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 1))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATEREQ_F, Value(DataType.FLOAT, 21.0), Value(DataType.UBYTE, 1))
|
||||||
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATEREQ_F, Value(DataType.FLOAT, 21.001), Value(DataType.UBYTE, 0))
|
testBinaryOperator(Value(DataType.FLOAT, 21.0), Opcode.GREATEREQ_F, Value(DataType.FLOAT, 21.001), Value(DataType.UBYTE, 0))
|
||||||
}
|
}
|
||||||
|
@ -567,15 +567,21 @@ flt(x)
|
|||||||
This is required if you want calculations to have floating point precision when the values aren't float already.
|
This is required if you want calculations to have floating point precision when the values aren't float already.
|
||||||
|
|
||||||
wrd(x)
|
wrd(x)
|
||||||
Explicitly convert the byte x to a word.
|
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 bytes.
|
This is required if you want calculations to have word precision when the values are different types.
|
||||||
|
|
||||||
wrdhi(x)
|
uwrd(x)
|
||||||
Explicitly convert the byte x to a word, where x will be the high byte (msb) in the word.
|
Explicitly convert the byte x to an unsigned word.
|
||||||
This can be useful in calculations with word precision when the values are bytes.
|
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)
|
any(x)
|
||||||
1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false')
|
1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false')
|
||||||
|
|
||||||
all(x)
|
all(x)
|
||||||
1 ('true') if all of the values in the non-scalar (array or matrix) value x are 'true' (not zero), else 0 ('false')
|
1 ('true') if all of the values in the non-scalar (array or matrix) value x are 'true' (not zero), else 0 ('false')
|
||||||
@ -590,10 +596,16 @@ rndf()
|
|||||||
returns a pseudo-random float between 0.0 and 1.0
|
returns a pseudo-random float between 0.0 and 1.0
|
||||||
|
|
||||||
str2byte(s)
|
str2byte(s)
|
||||||
converts string s into the numeric value that s represents (byte).
|
converts string s into the numeric value that s represents (signed byte).
|
||||||
|
|
||||||
|
str2ubyte(s)
|
||||||
|
converts string s into the numeric value that s represents (unsigned byte).
|
||||||
|
|
||||||
str2word(s)
|
str2word(s)
|
||||||
converts string s into the numeric value that s represents (word).
|
converts string s into the numeric value that s represents (signed word).
|
||||||
|
|
||||||
|
str2uword(s)
|
||||||
|
converts string s into the numeric value that s represents (unsigned word).
|
||||||
|
|
||||||
str2float(s)
|
str2float(s)
|
||||||
converts string s into the numeric value that s represents (float).
|
converts string s into the numeric value that s represents (float).
|
||||||
|
Loading…
Reference in New Issue
Block a user