mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
adding singed integer datatypes
This commit is contained in:
parent
f5261a3425
commit
2f7d03b6ab
@ -103,7 +103,7 @@ constdecl: 'const' varinitializer ;
|
||||
|
||||
memoryvardecl: 'memory' varinitializer;
|
||||
|
||||
datatype: 'byte' | 'word' | 'float' | 'str' | 'str_p' | 'str_s' | 'str_ps' ;
|
||||
datatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'float' | 'str' | 'str_p' | 'str_s' | 'str_ps' ;
|
||||
|
||||
arrayspec: '[' expression (',' expression)? ']' ;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
%option enable_floats
|
||||
|
||||
~ irq {
|
||||
word global_time
|
||||
byte time_changed
|
||||
uword global_time
|
||||
ubyte time_changed
|
||||
|
||||
sub irq() {
|
||||
global_time++
|
||||
@ -13,8 +13,8 @@
|
||||
|
||||
~ main {
|
||||
|
||||
const word width = 320
|
||||
const word height = 200
|
||||
const uword width = 320
|
||||
const uword height = 200
|
||||
|
||||
; vertices
|
||||
float[8] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
|
||||
@ -22,7 +22,7 @@
|
||||
float[8] zcoor = [ -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ]
|
||||
|
||||
; edges (msb=from vertex, lsb=to vertex)
|
||||
word[12] edges = [$0001, $0103, $0302, $0200, $0405, $0507, $0706, $0604, $0004, $0105, $0206, $0307]
|
||||
uword[12] edges = [$0001, $0103, $0302, $0200, $0405, $0507, $0706, $0604, $0004, $0105, $0206, $0307]
|
||||
|
||||
; storage for rotated coordinates
|
||||
float[len(xcoor)] rotatedx
|
||||
@ -37,7 +37,7 @@
|
||||
_vm_gfx_text(8, 6, 1, "Spin")
|
||||
_vm_gfx_text(29, 11, 1, "to Win !")
|
||||
|
||||
for byte i in 0 to width//10 {
|
||||
for ubyte i in 0 to width//10 {
|
||||
_vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
float Azy = cosb*sinc
|
||||
float Azz = cosb*cosc
|
||||
|
||||
for byte i in 0 to len(xcoor)-1 {
|
||||
for ubyte i in 0 to len(xcoor)-1 {
|
||||
rotatedx[i] = Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i]
|
||||
rotatedy[i] = Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i]
|
||||
rotatedz[i] = Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i]
|
||||
@ -87,18 +87,18 @@
|
||||
}
|
||||
|
||||
; draw all edges of the object
|
||||
for word edge in edges {
|
||||
byte e_from = msb(edge)
|
||||
byte e_to = lsb(edge)
|
||||
for uword edge in edges {
|
||||
ubyte e_from = msb(edge)
|
||||
ubyte e_to = lsb(edge)
|
||||
_vm_gfx_line(toscreenx(rotatedx[e_from], rotatedz[e_from]), toscreeny(rotatedy[e_from], rotatedz[e_from]),
|
||||
toscreenx(rotatedx[e_to], rotatedz[e_to]), toscreeny(rotatedy[e_to], rotatedz[e_to]), e_from+e_to)
|
||||
}
|
||||
|
||||
; accentuate the vertices a bit with small boxes
|
||||
for byte i in 0 to len(xcoor)-1 {
|
||||
for ubyte i in 0 to len(xcoor)-1 {
|
||||
word sx = toscreenx(rotatedx[i], rotatedz[i])
|
||||
word sy = toscreeny(rotatedy[i], rotatedz[i])
|
||||
byte color=i+2
|
||||
ubyte color=i+2
|
||||
_vm_gfx_pixel(sx-1, sy-1, color)
|
||||
_vm_gfx_pixel(sx, sy-1, color)
|
||||
_vm_gfx_pixel(sx+1, sy-1, color)
|
||||
|
@ -1,26 +1,26 @@
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
const word width = 320 // 2
|
||||
const word height = 256 // 2
|
||||
const word xoffset = 40
|
||||
const word yoffset = 30
|
||||
const uword width = 320 // 2
|
||||
const uword height = 256 // 2
|
||||
const uword xoffset = 40
|
||||
const uword yoffset = 30
|
||||
|
||||
sub start() {
|
||||
_vm_gfx_clearscr(11)
|
||||
_vm_gfx_text(2, 1, 1, "Calculating Mandelbrot Fractal...")
|
||||
|
||||
for byte pixely in yoffset to yoffset+height-1 {
|
||||
for ubyte pixely in yoffset to yoffset+height-1 {
|
||||
float yy = flt((pixely-yoffset))/height/3.6+0.4
|
||||
|
||||
for word pixelx in xoffset to xoffset+width-1 {
|
||||
for uword pixelx in xoffset to xoffset+width-1 {
|
||||
float xx = flt((pixelx-xoffset))/width/3.0+0.2
|
||||
|
||||
float xsquared = 0.0
|
||||
float ysquared = 0.0
|
||||
float x = 0.0
|
||||
float y = 0.0
|
||||
byte iter = 0
|
||||
ubyte iter = 0
|
||||
|
||||
while (iter<32 and xsquared+ysquared<4.0) {
|
||||
y = x*y*2.0 + yy
|
||||
@ -42,9 +42,9 @@
|
||||
|
||||
~ irq {
|
||||
|
||||
memory byte jiffyclockHi = $a0
|
||||
memory byte jiffyclockMid = $a1
|
||||
memory byte jiffyclockLo = $a2
|
||||
memory ubyte jiffyclockHi = $a0
|
||||
memory ubyte jiffyclockMid = $a1
|
||||
memory ubyte jiffyclockLo = $a2
|
||||
|
||||
sub irq() {
|
||||
_vm_gfx_pixel(jiffyclockLo,190,jiffyclockHi)
|
||||
|
@ -2,7 +2,7 @@
|
||||
sub start() {
|
||||
str name = " "
|
||||
str guess = "000000"
|
||||
byte secretnumber = rnd() % 100
|
||||
ubyte secretnumber = rnd() % 100
|
||||
|
||||
_vm_write_str("Let's play a number guessing game!\n")
|
||||
_vm_write_str("Enter your name: ")
|
||||
@ -11,14 +11,14 @@
|
||||
_vm_write_str(name)
|
||||
_vm_write_str(".\nI am thinking of a number from 1 to 100! You'll have to guess it!\n")
|
||||
|
||||
for byte attempts_left in 10 to 1 step -1 {
|
||||
for ubyte attempts_left in 10 to 1 step -1 {
|
||||
_vm_write_str("\nYou have ")
|
||||
_vm_write_num(attempts_left)
|
||||
_vm_write_str(" guess")
|
||||
if attempts_left>1 _vm_write_str("es")
|
||||
_vm_write_str(" left. What is your next guess? ")
|
||||
_vm_input_str(guess)
|
||||
byte guessednumber = str2byte(guess)
|
||||
ubyte guessednumber = str2byte(guess)
|
||||
if guessednumber==secretnumber {
|
||||
_vm_write_str("\nYou guessed it, impressive!\n")
|
||||
_vm_write_str("Thanks for playing.\n")
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
~ main {
|
||||
|
||||
const word width = 320
|
||||
const word height = 200
|
||||
const uword width = 320
|
||||
const uword height = 200
|
||||
|
||||
sub start() {
|
||||
|
||||
_vm_gfx_clearscr(0)
|
||||
|
||||
float t
|
||||
byte color
|
||||
ubyte color
|
||||
|
||||
while(1) {
|
||||
float x = sin(t*1.01) + cos(t*1.1234)
|
||||
@ -21,10 +21,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
sub screenx(x: float) -> word {
|
||||
sub screenx(x: float) -> uword {
|
||||
return floor(x * flt(width)/4.1) + width // 2
|
||||
}
|
||||
sub screeny(y: float) -> word {
|
||||
sub screeny(y: float) -> uword {
|
||||
return floor(y * flt(height)/4.1) + height // 2
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,22 @@ import kotlin.math.floor
|
||||
/**************************** AST Data classes ****************************/
|
||||
|
||||
enum class DataType {
|
||||
UBYTE,
|
||||
BYTE,
|
||||
UWORD,
|
||||
WORD,
|
||||
FLOAT,
|
||||
STR,
|
||||
STR_P,
|
||||
STR_S,
|
||||
STR_PS,
|
||||
ARRAY,
|
||||
ARRAY_UB,
|
||||
ARRAY_B,
|
||||
ARRAY_UW,
|
||||
ARRAY_W,
|
||||
ARRAY_F,
|
||||
MATRIX
|
||||
MATRIX_UB,
|
||||
MATRIX_B
|
||||
}
|
||||
|
||||
enum class Register {
|
||||
@ -63,7 +68,15 @@ enum class BranchCondition {
|
||||
|
||||
val IterableDatatypes = setOf(
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX)
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B,
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W,
|
||||
DataType.ARRAY_F, DataType.MATRIX_UB, DataType.MATRIX_B)
|
||||
|
||||
val StringDatatypes = setOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS)
|
||||
val NumericDatatypes = setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT)
|
||||
val IntegerDatatypes = setOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD)
|
||||
val ArrayDatatypes = setOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX_UB, DataType.MATRIX_B)
|
||||
|
||||
|
||||
class FatalAstException (override var message: String) : Exception(message)
|
||||
|
||||
@ -586,19 +599,22 @@ class VarDecl(val type: VarDeclType,
|
||||
val datatype = when {
|
||||
arrayspec == null -> declaredDatatype
|
||||
arrayspec.y != null -> when (declaredDatatype) {
|
||||
DataType.BYTE -> DataType.MATRIX
|
||||
DataType.UBYTE -> DataType.MATRIX_UB
|
||||
DataType.BYTE -> DataType.MATRIX_B
|
||||
else -> {
|
||||
datatypeErrors.add(SyntaxError("matrix can only contain bytes", position))
|
||||
DataType.BYTE
|
||||
DataType.UBYTE
|
||||
}
|
||||
}
|
||||
else -> when (declaredDatatype) {
|
||||
DataType.BYTE -> DataType.ARRAY
|
||||
DataType.UBYTE -> DataType.ARRAY_UB
|
||||
DataType.BYTE -> DataType.ARRAY_B
|
||||
DataType.UWORD -> DataType.ARRAY_UW
|
||||
DataType.WORD -> DataType.ARRAY_W
|
||||
DataType.FLOAT -> DataType.ARRAY_F
|
||||
else -> {
|
||||
datatypeErrors.add(SyntaxError("array can only contain bytes/words/floats", position))
|
||||
DataType.BYTE
|
||||
DataType.UBYTE
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -620,7 +636,9 @@ class VarDecl(val type: VarDeclType,
|
||||
|
||||
fun asDefaultValueDecl(): VarDecl {
|
||||
val constValue = when(declaredDatatype) {
|
||||
DataType.UBYTE -> LiteralValue(DataType.UBYTE, 0, position=position)
|
||||
DataType.BYTE -> LiteralValue(DataType.BYTE, 0, position=position)
|
||||
DataType.UWORD -> LiteralValue(DataType.UWORD, wordvalue=0, position=position)
|
||||
DataType.WORD -> LiteralValue(DataType.WORD, wordvalue=0, position=position)
|
||||
DataType.FLOAT -> LiteralValue(DataType.FLOAT, floatvalue=0.0, position=position)
|
||||
else -> throw FatalAstException("can only set a default value for a numeric type")
|
||||
@ -669,8 +687,8 @@ data class AssignTarget(val register: Register?,
|
||||
fun determineDatatype(namespace: INameScope, heap: HeapValues, stmt: IStatement): DataType? {
|
||||
if(register!=null)
|
||||
return when(register){
|
||||
Register.A, Register.X, Register.Y -> DataType.BYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.WORD
|
||||
Register.A, Register.X, Register.Y -> DataType.UBYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.UWORD
|
||||
}
|
||||
|
||||
if(identifier!=null) {
|
||||
@ -742,21 +760,42 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
|
||||
"and", "or", "xor",
|
||||
"<", ">",
|
||||
"<=", ">=",
|
||||
"==", "!=" -> DataType.BYTE
|
||||
"==", "!=" -> DataType.UBYTE
|
||||
"/" -> {
|
||||
val rightNum = right.constValue(namespace, heap)?.asNumericValue?.toDouble()
|
||||
if(rightNum!=null) {
|
||||
when(leftDt) {
|
||||
DataType.UBYTE ->
|
||||
when(rightDt) {
|
||||
DataType.UBYTE -> DataType.UBYTE
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD -> if(rightNum >= 256) DataType.UBYTE else DataType.UWORD
|
||||
DataType.WORD -> {
|
||||
if(rightNum < 0)
|
||||
if(rightNum<-256) DataType.UBYTE else DataType.WORD
|
||||
else
|
||||
if(rightNum>256) DataType.UBYTE else DataType.UWORD
|
||||
}
|
||||
DataType.FLOAT -> if(rightNum <= -256 || rightNum >= 256) DataType.UBYTE else DataType.FLOAT
|
||||
else -> throw FatalAstException("invalid rightDt $rightDt")
|
||||
}
|
||||
DataType.BYTE ->
|
||||
when(rightDt) {
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.WORD -> if(rightNum <= -256 || rightNum >= 256) DataType.BYTE else DataType.WORD
|
||||
DataType.UBYTE, DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD, DataType.WORD -> if(rightNum <= -256 || rightNum >= 256) DataType.BYTE else DataType.WORD
|
||||
DataType.FLOAT -> if(rightNum <= -256 || rightNum >= 256) DataType.BYTE else DataType.FLOAT
|
||||
else -> throw FatalAstException("invalid rightDt $rightDt")
|
||||
}
|
||||
DataType.UWORD ->
|
||||
when(rightDt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> if(rightNum <= -65536 || rightNum >= 65536) DataType.UWORD else DataType.FLOAT
|
||||
else -> throw FatalAstException("invalid rightDt $rightDt")
|
||||
}
|
||||
DataType.WORD ->
|
||||
when(rightDt) {
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.UBYTE, DataType.UWORD, DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> if(rightNum <= -65536 || rightNum >= 65536) DataType.WORD else DataType.FLOAT
|
||||
else -> throw FatalAstException("invalid rightDt $rightDt")
|
||||
}
|
||||
@ -771,16 +810,26 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
|
||||
|
||||
private fun integerDivisionOpDt(leftDt: DataType, rightDt: DataType): DataType {
|
||||
return when(leftDt) {
|
||||
DataType.BYTE -> when(rightDt) {
|
||||
DataType.UBYTE -> when(rightDt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UBYTE
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> DataType.BYTE
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.WORD -> when(rightDt) {
|
||||
DataType.BYTE -> when(rightDt) {
|
||||
in NumericDatatypes -> DataType.BYTE
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.UWORD -> when(rightDt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> DataType.WORD
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.WORD -> when(rightDt) {
|
||||
in NumericDatatypes -> DataType.WORD
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.FLOAT -> when(rightDt) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> DataType.WORD
|
||||
in NumericDatatypes -> DataType.WORD
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
@ -789,23 +838,35 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
|
||||
|
||||
private fun arithmeticOpDt(leftDt: DataType, rightDt: DataType): DataType {
|
||||
return when(leftDt) {
|
||||
DataType.BYTE -> when(rightDt) {
|
||||
DataType.UBYTE -> when(rightDt) {
|
||||
DataType.UBYTE -> DataType.UBYTE
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD -> DataType.UWORD
|
||||
DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.WORD -> when(rightDt) {
|
||||
DataType.BYTE -> when(rightDt) {
|
||||
DataType.BYTE, DataType.UBYTE -> DataType.BYTE
|
||||
DataType.WORD, DataType.UWORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.UWORD -> when(rightDt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.FLOAT -> when(rightDt) {
|
||||
DataType.BYTE -> DataType.FLOAT
|
||||
DataType.WORD -> DataType.FLOAT
|
||||
DataType.WORD -> when(rightDt) {
|
||||
DataType.BYTE, DataType.UBYTE, DataType.WORD, DataType.UWORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
DataType.FLOAT -> when(rightDt) {
|
||||
in NumericDatatypes -> DataType.FLOAT
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt")
|
||||
}
|
||||
}
|
||||
@ -829,15 +890,18 @@ class ArrayIndexedExpression(val identifier: IdentifierReference?,
|
||||
|
||||
override fun resultingDatatype(namespace: INameScope, heap: HeapValues): DataType? {
|
||||
if (register != null)
|
||||
return DataType.BYTE
|
||||
return DataType.UBYTE
|
||||
val target = identifier?.targetStatement(namespace)
|
||||
if (target is VarDecl) {
|
||||
return when (target.datatype) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> null
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.BYTE
|
||||
DataType.ARRAY, DataType.MATRIX -> DataType.BYTE
|
||||
in NumericDatatypes -> null
|
||||
in StringDatatypes -> DataType.UBYTE
|
||||
DataType.ARRAY_UB, DataType.MATRIX_UB -> DataType.UBYTE
|
||||
DataType.ARRAY_B, DataType.MATRIX_B -> DataType.BYTE
|
||||
DataType.ARRAY_UW -> DataType.UWORD
|
||||
DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_F -> DataType.FLOAT
|
||||
else -> throw FatalAstException("invalid dt")
|
||||
}
|
||||
}
|
||||
throw FatalAstException("cannot get indexed element on $target")
|
||||
@ -860,18 +924,18 @@ class LiteralValue(val type: DataType,
|
||||
|
||||
override fun referencesIdentifier(name: String) = arrayvalue?.any { it.referencesIdentifier(name) } ?: false
|
||||
|
||||
val isString = type==DataType.STR || type==DataType.STR_P || type==DataType.STR_S || type==DataType.STR_PS
|
||||
val isNumeric = type==DataType.BYTE || type==DataType.WORD || type==DataType.FLOAT
|
||||
val isArray = type==DataType.ARRAY || type==DataType.ARRAY_W || type==DataType.ARRAY_F || type==DataType.MATRIX
|
||||
val isString = type in StringDatatypes
|
||||
val isNumeric = type in NumericDatatypes
|
||||
val isArray = type in ArrayDatatypes
|
||||
|
||||
companion object {
|
||||
fun fromBoolean(bool: Boolean, position: Position) =
|
||||
LiteralValue(DataType.BYTE, bytevalue = if(bool) 1 else 0, position=position)
|
||||
LiteralValue(DataType.UBYTE, bytevalue = if(bool) 1 else 0, position=position)
|
||||
|
||||
fun fromNumber(value: Number, type: DataType, position: Position) : LiteralValue {
|
||||
return when(type) {
|
||||
DataType.BYTE -> LiteralValue(type, bytevalue = value.toShort(), position = position)
|
||||
DataType.WORD -> LiteralValue(type, wordvalue = value.toInt(), position = position)
|
||||
DataType.UBYTE, DataType.BYTE -> LiteralValue(type, bytevalue = value.toShort(), position = position)
|
||||
DataType.UWORD, DataType.WORD -> LiteralValue(type, wordvalue = value.toInt(), position = position)
|
||||
DataType.FLOAT -> LiteralValue(type, floatvalue = value.toDouble(), position = position)
|
||||
else -> throw FatalAstException("non numeric datatype")
|
||||
}
|
||||
@ -882,9 +946,10 @@ class LiteralValue(val type: DataType,
|
||||
return if(floatval == floor(floatval) && floatval in -32768..65535) {
|
||||
// the floating point value is actually an integer.
|
||||
when (floatval) {
|
||||
// note: we cheat a little here and allow negative integers during expression evaluations
|
||||
in -128..255 -> LiteralValue(DataType.BYTE, bytevalue = floatval.toShort(), position = position)
|
||||
in -32768..65535 -> LiteralValue(DataType.WORD, wordvalue = floatval.toInt(), position = position)
|
||||
in 0..255 -> LiteralValue(DataType.UBYTE, bytevalue=floatval.toShort(), position = position)
|
||||
in -128..127 -> LiteralValue(DataType.BYTE, bytevalue=floatval.toShort(), position = position)
|
||||
in 0..65535 -> LiteralValue(DataType.UWORD, wordvalue = floatval.toInt(), position = position)
|
||||
in -32768..32767 -> LiteralValue(DataType.WORD, wordvalue = floatval.toInt(), position = position)
|
||||
else -> LiteralValue(DataType.FLOAT, floatvalue = floatval, position = position)
|
||||
}
|
||||
} else {
|
||||
@ -894,9 +959,9 @@ class LiteralValue(val type: DataType,
|
||||
|
||||
fun optimalInteger(value: Number, position: Position): LiteralValue {
|
||||
return when (value) {
|
||||
// note: we cheat a little here and allow negative integers during expression evaluations
|
||||
in -128..255 -> LiteralValue(DataType.BYTE, bytevalue = value.toShort(), position = position)
|
||||
in -32768..65535 -> LiteralValue(DataType.WORD, wordvalue = value.toInt(), position = position)
|
||||
in 0..255 -> LiteralValue(DataType.UBYTE, bytevalue=value.toShort(), position = position)
|
||||
in -128..127 -> LiteralValue(DataType.BYTE, bytevalue=value.toShort(), position = position)
|
||||
in 0..65535 -> LiteralValue(DataType.UWORD, wordvalue = value.toInt(), position = position)
|
||||
else -> throw FatalAstException("integer overflow: $value")
|
||||
}
|
||||
}
|
||||
@ -904,12 +969,12 @@ class LiteralValue(val type: DataType,
|
||||
|
||||
init {
|
||||
when(type){
|
||||
DataType.BYTE -> if(bytevalue==null) throw FatalAstException("literal value missing bytevalue")
|
||||
DataType.WORD -> if(wordvalue==null) throw FatalAstException("literal value missing wordvalue")
|
||||
DataType.UBYTE, DataType.BYTE -> if(bytevalue==null) throw FatalAstException("literal value missing bytevalue")
|
||||
DataType.UWORD, DataType.WORD -> if(wordvalue==null) throw FatalAstException("literal value missing wordvalue")
|
||||
DataType.FLOAT -> if(floatvalue==null) throw FatalAstException("literal value missing floatvalue")
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS ->
|
||||
in StringDatatypes ->
|
||||
if(strvalue==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId")
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX ->
|
||||
in ArrayDatatypes ->
|
||||
if(arrayvalue==null && heapId==null) throw FatalAstException("literal value missing arrayvalue/heapId")
|
||||
}
|
||||
if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null && heapId==null)
|
||||
@ -946,18 +1011,20 @@ class LiteralValue(val type: DataType,
|
||||
|
||||
override fun toString(): String {
|
||||
val vstr = when(type) {
|
||||
DataType.UBYTE -> "ubyte:$bytevalue"
|
||||
DataType.BYTE -> "byte:$bytevalue"
|
||||
DataType.UWORD -> "uword:$wordvalue"
|
||||
DataType.WORD -> "word:$wordvalue"
|
||||
DataType.FLOAT -> "float:$floatvalue"
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS-> {
|
||||
if(heapId!=null) "str:#$heapId"
|
||||
else "str:$strvalue"
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F -> {
|
||||
if(heapId!=null) "array:#$heapId"
|
||||
else "array:$arrayvalue"
|
||||
}
|
||||
DataType.MATRIX -> {
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
if(heapId!=null) "matrix:#$heapId"
|
||||
else "matrix:$arrayvalue"
|
||||
}
|
||||
@ -1020,12 +1087,15 @@ class RangeExpr(var from: IExpression,
|
||||
val toDt=to.resultingDatatype(namespace, heap)
|
||||
return when {
|
||||
fromDt==null || toDt==null -> null
|
||||
fromDt==DataType.UBYTE && toDt==DataType.UBYTE -> DataType.UBYTE
|
||||
fromDt==DataType.UWORD && toDt==DataType.UWORD -> DataType.UWORD
|
||||
fromDt==DataType.STR && toDt==DataType.STR -> DataType.STR
|
||||
fromDt==DataType.STR_P && toDt==DataType.STR_P -> DataType.STR_P
|
||||
fromDt==DataType.STR_S && toDt==DataType.STR_S -> DataType.STR_S
|
||||
fromDt==DataType.STR_PS && toDt==DataType.STR_PS -> DataType.STR_PS
|
||||
fromDt==DataType.WORD || toDt==DataType.WORD -> DataType.WORD
|
||||
fromDt==DataType.STR || toDt==DataType.STR -> DataType.STR
|
||||
fromDt==DataType.STR_P || toDt==DataType.STR_P -> DataType.STR_P
|
||||
fromDt==DataType.STR_S || toDt==DataType.STR_S -> DataType.STR_S
|
||||
fromDt==DataType.STR_PS || toDt==DataType.STR_PS -> DataType.STR_PS
|
||||
else -> DataType.BYTE
|
||||
fromDt==DataType.BYTE || toDt==DataType.BYTE -> DataType.UBYTE
|
||||
else -> DataType.UBYTE
|
||||
}
|
||||
}
|
||||
override fun toString(): String {
|
||||
@ -1090,8 +1160,8 @@ class RegisterExpr(val register: Register, override val position: Position) : IE
|
||||
|
||||
override fun resultingDatatype(namespace: INameScope, heap: HeapValues): DataType? {
|
||||
return when(register){
|
||||
Register.A, Register.X, Register.Y -> DataType.BYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.WORD
|
||||
Register.A, Register.X, Register.Y -> DataType.UBYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.UWORD
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1711,29 +1781,31 @@ private fun prog8Parser.DirectiveargContext.toAst() : DirectiveArg =
|
||||
private fun prog8Parser.IntegerliteralContext.toAst(): NumericLiteral {
|
||||
fun makeLiteral(text: String, radix: Int, forceWord: Boolean): NumericLiteral {
|
||||
val integer: Int
|
||||
var datatype = DataType.BYTE
|
||||
var datatype = DataType.UBYTE
|
||||
when (radix) {
|
||||
10 -> {
|
||||
integer = text.toInt()
|
||||
datatype = when(integer) {
|
||||
in 0..255 -> DataType.BYTE
|
||||
in 256..65535 -> DataType.WORD
|
||||
in 0..255 -> DataType.UBYTE
|
||||
in -128..127 -> DataType.BYTE
|
||||
in 0..65535 -> DataType.UWORD
|
||||
in -32768..32767 -> DataType.WORD
|
||||
else -> DataType.FLOAT
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
if(text.length>8)
|
||||
datatype = DataType.WORD
|
||||
datatype = DataType.UWORD
|
||||
integer = text.toInt(2)
|
||||
}
|
||||
16 -> {
|
||||
if(text.length>2)
|
||||
datatype = DataType.WORD
|
||||
datatype = DataType.UWORD
|
||||
integer = text.toInt(16)
|
||||
}
|
||||
else -> throw FatalAstException("invalid radix")
|
||||
}
|
||||
return NumericLiteral(integer, if(forceWord) DataType.WORD else datatype)
|
||||
return NumericLiteral(integer, if(forceWord) DataType.UWORD else datatype)
|
||||
}
|
||||
val terminal: TerminalNode = children[0] as TerminalNode
|
||||
val integerPart = this.intpart.text
|
||||
@ -1758,19 +1830,21 @@ private fun prog8Parser.ExpressionContext.toAst() : IExpression {
|
||||
val intLit = litval.integerliteral()?.toAst()
|
||||
when {
|
||||
intLit!=null -> when(intLit.datatype) {
|
||||
DataType.UBYTE -> LiteralValue(DataType.UBYTE, bytevalue = intLit.number.toShort(), position = litval.toPosition())
|
||||
DataType.BYTE -> LiteralValue(DataType.BYTE, bytevalue = intLit.number.toShort(), position = litval.toPosition())
|
||||
DataType.UWORD -> LiteralValue(DataType.UWORD, wordvalue = intLit.number.toInt(), position = litval.toPosition())
|
||||
DataType.WORD -> LiteralValue(DataType.WORD, wordvalue = intLit.number.toInt(), position = litval.toPosition())
|
||||
DataType.FLOAT -> LiteralValue(DataType.FLOAT, floatvalue= intLit.number.toDouble(), position = litval.toPosition())
|
||||
else -> throw FatalAstException("invalid datatype for numeric literal")
|
||||
}
|
||||
litval.floatliteral()!=null -> LiteralValue(DataType.FLOAT, floatvalue = litval.floatliteral().toAst(), position = litval.toPosition())
|
||||
litval.stringliteral()!=null -> LiteralValue(DataType.STR, strvalue = litval.stringliteral().text, position = litval.toPosition())
|
||||
litval.charliteral()!=null -> LiteralValue(DataType.BYTE, bytevalue = Petscii.encodePetscii(litval.charliteral().text.unescape(), true)[0], position = litval.toPosition())
|
||||
litval.charliteral()!=null -> LiteralValue(DataType.UBYTE, bytevalue = Petscii.encodePetscii(litval.charliteral().text.unescape(), true)[0], position = litval.toPosition())
|
||||
litval.arrayliteral()!=null -> {
|
||||
val array = litval.arrayliteral()?.toAst()
|
||||
// byte/word array type difference is not determined here.
|
||||
// the ConstantFolder takes care of that and converts the type if needed.
|
||||
LiteralValue(DataType.ARRAY, arrayvalue = array, position = litval.toPosition())
|
||||
LiteralValue(DataType.ARRAY_UB, arrayvalue = array, position = litval.toPosition())
|
||||
}
|
||||
else -> throw FatalAstException("invalid parsed literal")
|
||||
}
|
||||
@ -1796,7 +1870,7 @@ private fun prog8Parser.ExpressionContext.toAst() : IExpression {
|
||||
if(funcall!=null) return funcall
|
||||
|
||||
if (rangefrom!=null && rangeto!=null) {
|
||||
val step = rangestep?.toAst() ?: LiteralValue(DataType.BYTE, 1, position = toPosition())
|
||||
val step = rangestep?.toAst() ?: LiteralValue(DataType.UBYTE, 1, position = toPosition())
|
||||
return RangeExpr(rangefrom.toAst(), rangeto.toAst(), step, toPosition())
|
||||
}
|
||||
|
||||
|
@ -115,17 +115,13 @@ class AstChecker(private val namespace: INameScope,
|
||||
// loop register
|
||||
when (forLoop.loopRegister) {
|
||||
Register.A, Register.X, Register.Y -> {
|
||||
if (iterableDt != DataType.BYTE && iterableDt!=DataType.ARRAY && iterableDt!=DataType.MATRIX &&
|
||||
iterableDt != DataType.STR && iterableDt != DataType.STR_P &&
|
||||
iterableDt != DataType.STR_S && iterableDt != DataType.STR_PS)
|
||||
if (iterableDt != DataType.UBYTE && iterableDt!=DataType.ARRAY_UB && iterableDt!=DataType.MATRIX_UB && iterableDt !in StringDatatypes)
|
||||
checkResult.add(ExpressionError("register can only loop over bytes", forLoop.position))
|
||||
}
|
||||
Register.AX, Register.AY, Register.XY -> {
|
||||
if (iterableDt != DataType.WORD && iterableDt != DataType.BYTE &&
|
||||
iterableDt != DataType.STR && iterableDt != DataType.STR_P &&
|
||||
iterableDt != DataType.STR_S && iterableDt != DataType.STR_PS &&
|
||||
iterableDt !=DataType.ARRAY && iterableDt!=DataType.ARRAY_W && iterableDt!=DataType.ARRAY_F && iterableDt!=DataType.MATRIX)
|
||||
checkResult.add(ExpressionError("register pair can only loop over words", forLoop.position))
|
||||
if (iterableDt != DataType.UWORD && iterableDt != DataType.UBYTE && iterableDt !in StringDatatypes &&
|
||||
iterableDt !=DataType.ARRAY_UB && iterableDt!=DataType.ARRAY_UW && iterableDt!=DataType.MATRIX_UB)
|
||||
checkResult.add(ExpressionError("register pair can only loop over bytes or words", forLoop.position))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -136,17 +132,13 @@ class AstChecker(private val namespace: INameScope,
|
||||
|
||||
} else {
|
||||
when (loopvar.datatype) {
|
||||
DataType.BYTE -> {
|
||||
if(iterableDt!=DataType.BYTE && iterableDt!=DataType.ARRAY && iterableDt!=DataType.MATRIX &&
|
||||
iterableDt != DataType.STR && iterableDt != DataType.STR_P &&
|
||||
iterableDt != DataType.STR_S && iterableDt != DataType.STR_PS)
|
||||
DataType.UBYTE -> {
|
||||
if(iterableDt!=DataType.UBYTE && iterableDt!=DataType.ARRAY_UB && iterableDt!=DataType.MATRIX_UB && iterableDt !in StringDatatypes)
|
||||
checkResult.add(ExpressionError("byte loop variable can only loop over bytes", forLoop.position))
|
||||
}
|
||||
DataType.WORD -> {
|
||||
if(iterableDt!=DataType.BYTE && iterableDt!=DataType.WORD &&
|
||||
iterableDt !=DataType.ARRAY && iterableDt!=DataType.ARRAY_W && iterableDt!=DataType.MATRIX &&
|
||||
iterableDt != DataType.STR && iterableDt != DataType.STR_P &&
|
||||
iterableDt != DataType.STR_S && iterableDt != DataType.STR_PS)
|
||||
DataType.UWORD -> {
|
||||
if(iterableDt!=DataType.UBYTE && iterableDt!=DataType.UWORD && iterableDt !in StringDatatypes &&
|
||||
iterableDt !=DataType.ARRAY_UB && iterableDt!=DataType.ARRAY_UW && iterableDt!=DataType.MATRIX_UB)
|
||||
checkResult.add(ExpressionError("word loop variable can only loop over bytes or words", forLoop.position))
|
||||
}
|
||||
// there's no support for a floating-point loop variable
|
||||
@ -243,25 +235,26 @@ class AstChecker(private val namespace: INameScope,
|
||||
for(param in subroutine.parameters.zip(subroutine.asmParameterRegisters)) {
|
||||
if(param.second.register==Register.A || param.second.register==Register.X ||
|
||||
param.second.register==Register.Y || param.second.statusflag!=null) {
|
||||
if(param.first.type!=DataType.BYTE)
|
||||
err("parameter '${param.first.name}' should be byte")
|
||||
if(param.first.type!=DataType.UBYTE)
|
||||
err("parameter '${param.first.name}' should be ubyte")
|
||||
}
|
||||
if(param.second.register==Register.AX || param.second.register==Register.AY ||
|
||||
param.second.register==Register.XY) {
|
||||
if(param.first.type==DataType.BYTE || param.first.type==DataType.FLOAT)
|
||||
err("parameter '${param.first.name}' should be word/str/array")
|
||||
if(param.first.type!=DataType.UWORD && param.first.type !in StringDatatypes && param.first.type !in ArrayDatatypes)
|
||||
err("parameter '${param.first.name}' should be uword/str/array")
|
||||
}
|
||||
}
|
||||
for(ret in subroutine.returntypes.withIndex().zip(subroutine.asmReturnvaluesRegisters)) {
|
||||
if(ret.second.register==Register.A || ret.second.register==Register.X ||
|
||||
ret.second.register==Register.Y || ret.second.statusflag!=null) {
|
||||
if(ret.first.value!=DataType.BYTE)
|
||||
err("return value #${ret.first.index+1} should be byte")
|
||||
if(ret.first.value!=DataType.UBYTE)
|
||||
err("return value #${ret.first.index+1} should be ubyte")
|
||||
}
|
||||
if(ret.second.register==Register.AX || ret.second.register==Register.AY ||
|
||||
ret.second.register==Register.XY) {
|
||||
if(ret.first.value==DataType.BYTE || ret.first.value==DataType.FLOAT)
|
||||
err("return value #${ret.first.index+1} should be byte")
|
||||
if(ret.first.value!=DataType.UWORD && ret.first.value != DataType.UBYTE &&
|
||||
ret.first.value !in StringDatatypes && ret.first.value !in ArrayDatatypes)
|
||||
err("return value #${ret.first.index+1} should be uword/ubyte/string/array")
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,11 +327,8 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
|
||||
// it is not possible to assign a new array to something.
|
||||
when(assignment.value.resultingDatatype(namespace, heap)) {
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX ->
|
||||
if(assignment.value.resultingDatatype(namespace, heap) in ArrayDatatypes)
|
||||
checkResult.add(SyntaxError("it's not possible to assign an array literal value to something, use it as a variable decl initializer instead", assignment.position))
|
||||
else -> {}
|
||||
}
|
||||
|
||||
if(assignment.aug_op!=null) {
|
||||
// check augmented assignment:
|
||||
@ -405,17 +395,17 @@ class AstChecker(private val namespace: INameScope,
|
||||
|
||||
// CONST can only occur on simple types (byte, word, float)
|
||||
if(decl.type==VarDeclType.CONST) {
|
||||
if (decl.datatype != DataType.BYTE && decl.datatype != DataType.WORD && decl.datatype != DataType.FLOAT)
|
||||
err("const modifier can only be used on simple types (byte, word, float)")
|
||||
if (decl.datatype !in NumericDatatypes)
|
||||
err("const modifier can only be used on numeric types (byte, word, float)")
|
||||
}
|
||||
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR, VarDeclType.CONST -> {
|
||||
if (decl.value == null) {
|
||||
when {
|
||||
decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT -> {
|
||||
decl.datatype in NumericDatatypes -> {
|
||||
// initialize numeric var with value zero by default.
|
||||
val litVal = LiteralValue(DataType.BYTE, 0, position = decl.position)
|
||||
val litVal = LiteralValue(DataType.UBYTE, 0, position = decl.position)
|
||||
litVal.parent = decl
|
||||
decl.value = litVal
|
||||
}
|
||||
@ -531,15 +521,15 @@ class AstChecker(private val namespace: INameScope,
|
||||
|
||||
val lv = super.process(literalValue)
|
||||
when(lv.type) {
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
|
||||
in StringDatatypes -> {
|
||||
if(lv.heapId==null)
|
||||
throw FatalAstException("string should have been moved to heap at ${lv.position}")
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> {
|
||||
in ArrayDatatypes -> {
|
||||
if(lv.heapId==null)
|
||||
throw FatalAstException("array/matrix should have been moved to heap at ${lv.position}")
|
||||
}
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> {}
|
||||
else -> {}
|
||||
}
|
||||
return lv
|
||||
}
|
||||
@ -562,7 +552,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
super.process(range)
|
||||
val from = range.from.constValue(namespace, heap)
|
||||
val to = range.to.constValue(namespace, heap)
|
||||
val stepLv = range.step.constValue(namespace, heap) ?: LiteralValue(DataType.BYTE, 1, position = range.position)
|
||||
val stepLv = range.step.constValue(namespace, heap) ?: LiteralValue(DataType.UBYTE, 1, position = range.position)
|
||||
if (stepLv.asIntegerValue == null || stepLv.asIntegerValue == 0) {
|
||||
err("range step must be an integer != 0")
|
||||
return range
|
||||
@ -651,7 +641,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
} else {
|
||||
if(target !is VarDecl || target.type==VarDeclType.CONST) {
|
||||
checkResult.add(SyntaxError("can only increment or decrement a variable", postIncrDecr.position))
|
||||
} else if(target.datatype!=DataType.FLOAT && target.datatype!=DataType.WORD && target.datatype!=DataType.BYTE) {
|
||||
} else if(target.datatype !in NumericDatatypes) {
|
||||
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word variable", postIncrDecr.position))
|
||||
}
|
||||
}
|
||||
@ -667,7 +657,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
else {
|
||||
val dt = (target as VarDecl).datatype
|
||||
if(dt!=DataType.ARRAY && dt!=DataType.ARRAY_W && dt!=DataType.ARRAY_F)
|
||||
if(dt !in NumericDatatypes)
|
||||
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word", postIncrDecr.position))
|
||||
}
|
||||
}
|
||||
@ -680,7 +670,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(reg==null) {
|
||||
val target = arrayIndexedExpression.identifier!!.targetStatement(namespace)
|
||||
if(target is VarDecl) {
|
||||
if(target.datatype==DataType.BYTE || target.datatype==DataType.WORD || target.datatype==DataType.FLOAT)
|
||||
if(target.datatype !in IterableDatatypes)
|
||||
checkResult.add(SyntaxError("array indexing requires an iterable variable", arrayIndexedExpression.position))
|
||||
val arraysize = target.arrayspec?.size()
|
||||
if(arraysize!=null) {
|
||||
@ -720,14 +710,11 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
|
||||
when(targetDt) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> {
|
||||
in NumericDatatypes -> {
|
||||
checkResult.add(SyntaxError("can't assign a range to a scalar type", range.position))
|
||||
return false
|
||||
}
|
||||
DataType.STR,
|
||||
DataType.STR_P,
|
||||
DataType.STR_S,
|
||||
DataType.STR_PS -> {
|
||||
in StringDatatypes -> {
|
||||
// range check bytes (chars)
|
||||
if(!from.isString || !to.isString) {
|
||||
checkResult.add(ExpressionError("range for string must have single characters from and to values", range.position))
|
||||
@ -740,7 +727,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
return true
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> {
|
||||
in ArrayDatatypes -> {
|
||||
// range and length check bytes
|
||||
val expectedSize = arrayspec!!.size()
|
||||
val rangeSize=range.size()
|
||||
@ -750,6 +737,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
return true
|
||||
}
|
||||
else -> throw FatalAstException("invalid targetDt")
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,15 +749,15 @@ class AstChecker(private val namespace: INameScope,
|
||||
when (targetDt) {
|
||||
DataType.FLOAT -> {
|
||||
val number = when(value.type) {
|
||||
DataType.BYTE -> value.bytevalue!!.toDouble()
|
||||
DataType.WORD -> value.wordvalue!!.toDouble()
|
||||
DataType.UBYTE, DataType.BYTE -> value.bytevalue!!.toDouble()
|
||||
DataType.UWORD, DataType.WORD -> value.wordvalue!!.toDouble()
|
||||
DataType.FLOAT -> value.floatvalue!!
|
||||
else -> return err("numeric value expected")
|
||||
}
|
||||
if (number > 1.7014118345e+38 || number < -1.7014118345e+38)
|
||||
return err("value '$number' out of range for MFLPT format")
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
|
||||
err("unsigned byte value expected instead of float; possible loss of precision")
|
||||
else
|
||||
@ -777,7 +765,15 @@ class AstChecker(private val namespace: INameScope,
|
||||
if (number < 0 || number > 255)
|
||||
return err("value '$number' out of range for unsigned byte")
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.BYTE -> {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
|
||||
err("byte value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("byte value expected")
|
||||
if (number < -128 || number > 127)
|
||||
return err("value '$number' out of range for byte")
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
|
||||
err("unsigned word value expected instead of float; possible loss of precision")
|
||||
else
|
||||
@ -785,6 +781,14 @@ class AstChecker(private val namespace: INameScope,
|
||||
if (number < 0 || number > 65535)
|
||||
return err("value '$number' out of range for unsigned word")
|
||||
}
|
||||
DataType.WORD -> {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
|
||||
err("word value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("word value expected")
|
||||
if (number < -32768 || number > 32767)
|
||||
return err("value '$number' out of range for word")
|
||||
}
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
|
||||
if(!value.isString)
|
||||
return err("string value expected")
|
||||
@ -792,9 +796,9 @@ class AstChecker(private val namespace: INameScope,
|
||||
if (str.isEmpty() || str.length > 255)
|
||||
return err("string length must be 1 to 255")
|
||||
}
|
||||
DataType.ARRAY -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
// value may be either a single byte, or a byte array (of all constant values)
|
||||
if(value.type==DataType.ARRAY) {
|
||||
if(value.type==DataType.ARRAY_UB || value.type==DataType.ARRAY_B) {
|
||||
val arraySize = value.arrayvalue?.size ?: heap.get(value.heapId!!).array!!.size
|
||||
val arraySpecSize = arrayspec.size()
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
@ -805,20 +809,29 @@ class AstChecker(private val namespace: INameScope,
|
||||
if (arraySize != expectedSize)
|
||||
return err("initializer array size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
}
|
||||
} else if(value.type==DataType.ARRAY_W) {
|
||||
} else if(value.type==DataType.ARRAY_UW || value.type==DataType.ARRAY_W) {
|
||||
return err("initialization value must be an array of bytes")
|
||||
} else {
|
||||
val number = value.bytevalue ?: return if (value.floatvalue!=null)
|
||||
if(targetDt==DataType.ARRAY_UB) {
|
||||
val number = value.bytevalue ?: return if (value.floatvalue != null)
|
||||
err("unsigned byte value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("unsigned byte value expected")
|
||||
if (number < 0 || number > 255)
|
||||
return err("value '$number' out of range for unsigned byte")
|
||||
} else {
|
||||
val number = value.bytevalue ?: return if (value.floatvalue != null)
|
||||
err("byte value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("byte value expected")
|
||||
if (number < -128 || number > 127)
|
||||
return err("value '$number' out of range for byte")
|
||||
}
|
||||
}
|
||||
DataType.ARRAY_W -> {
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
// value may be either a single word, or a word array
|
||||
if(value.type==DataType.ARRAY || value.type==DataType.ARRAY_W) {
|
||||
if(value.type==DataType.ARRAY_UB || value.type==DataType.ARRAY_UW || value.type==DataType.ARRAY_B || value.type==DataType.ARRAY_W) {
|
||||
val arraySize = value.arrayvalue?.size ?: heap.get(value.heapId!!).array!!.size
|
||||
val arraySpecSize = arrayspec.size()
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
@ -831,17 +844,26 @@ class AstChecker(private val namespace: INameScope,
|
||||
return err("initializer array size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
}
|
||||
} else {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
|
||||
if(targetDt==DataType.ARRAY_UW) {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue != null)
|
||||
err("unsigned byte or word value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("unsigned byte or word value expected")
|
||||
if (number < 0 || number > 65535)
|
||||
return err("value '$number' out of range for unsigned word")
|
||||
} else {
|
||||
val number = value.asIntegerValue ?: return if (value.floatvalue != null)
|
||||
err("byte or word value expected instead of float; possible loss of precision")
|
||||
else
|
||||
err("byte or word value expected")
|
||||
if (number < -32768 || number > 32767)
|
||||
return err("value '$number' out of range for word")
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
// value may be either a single float, or a float array
|
||||
if(value.type==DataType.ARRAY || value.type==DataType.ARRAY_W || value.type==DataType.ARRAY_F) {
|
||||
if(value.type==DataType.ARRAY_UB || value.type==DataType.ARRAY_UW || value.type==DataType.ARRAY_F) {
|
||||
val arraySize = value.arrayvalue?.size ?: heap.get(value.heapId!!).arraysize
|
||||
val arraySpecSize = arrayspec.size()
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
@ -861,9 +883,9 @@ class AstChecker(private val namespace: INameScope,
|
||||
return err("value '$number' out of range for mfplt5 floating point")
|
||||
}
|
||||
}
|
||||
DataType.MATRIX -> {
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
// value can only be a single byte, or a byte array (which represents the matrix)
|
||||
if(value.type==DataType.ARRAY || value.type==DataType.MATRIX) {
|
||||
if(value.type==DataType.ARRAY_UB || value.type==DataType.ARRAY_B || value.type==DataType.MATRIX_UB || value.type==DataType.MATRIX_B) {
|
||||
val arraySpecSize = arrayspec.size()
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
val constX = arrayspec.x.constValue(namespace, heap)
|
||||
@ -876,10 +898,17 @@ class AstChecker(private val namespace: INameScope,
|
||||
return err("initializer matrix size mismatch (expecting $expectedSize, got ${matrix.size} elements)")
|
||||
}
|
||||
} else {
|
||||
if(targetDt==DataType.MATRIX_UB) {
|
||||
val number = value.bytevalue
|
||||
?: return err("unsigned byte value expected")
|
||||
if (number < 0 || number > 255)
|
||||
return err("value '$number' out of range for unsigned byte")
|
||||
} else {
|
||||
val number = value.bytevalue
|
||||
?: return err("byte value expected")
|
||||
if (number < -128 || number > 127)
|
||||
return err("value '$number' out of range for byte")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -896,8 +925,10 @@ class AstChecker(private val namespace: INameScope,
|
||||
|
||||
val result = when(targetDatatype) {
|
||||
DataType.BYTE -> sourceDatatype==DataType.BYTE
|
||||
DataType.UBYTE -> sourceDatatype==DataType.UBYTE
|
||||
DataType.WORD -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD
|
||||
DataType.FLOAT -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD || sourceDatatype==DataType.FLOAT
|
||||
DataType.UWORD -> sourceDatatype==DataType.UBYTE || sourceDatatype==DataType.UWORD
|
||||
DataType.FLOAT -> sourceDatatype in NumericDatatypes
|
||||
DataType.STR -> sourceDatatype==DataType.STR
|
||||
DataType.STR_S -> sourceDatatype==DataType.STR_S
|
||||
DataType.STR_P -> sourceDatatype==DataType.STR_P
|
||||
@ -908,9 +939,9 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(result)
|
||||
return true
|
||||
|
||||
if(sourceDatatype==DataType.WORD && targetDatatype==DataType.BYTE)
|
||||
if((sourceDatatype==DataType.UWORD || sourceDatatype==DataType.WORD) && (targetDatatype==DataType.UBYTE || targetDatatype==DataType.BYTE))
|
||||
checkResult.add(ExpressionError("cannot assign word to byte, use msb() or lsb()?", position))
|
||||
else if(sourceDatatype==DataType.FLOAT && (targetDatatype==DataType.BYTE || targetDatatype==DataType.WORD))
|
||||
else if(sourceDatatype==DataType.FLOAT && targetDatatype in IntegerDatatypes)
|
||||
checkResult.add(ExpressionError("cannot assign float to ${targetDatatype.toString().toLowerCase()}; possible loss of precision. Suggestion: round the value or revert to byte/word arithmetic", position))
|
||||
else
|
||||
checkResult.add(ExpressionError("cannot assign ${sourceDatatype.toString().toLowerCase()} to ${targetDatatype.toString().toLowerCase()}", position))
|
||||
|
@ -125,7 +125,7 @@ class AstIdentifiersChecker : IAstProcessor {
|
||||
val loopVar = forLoop.loopVar!!
|
||||
val varName = loopVar.nameInSource.last()
|
||||
when (forLoop.decltype) {
|
||||
DataType.BYTE, DataType.WORD -> {
|
||||
DataType.UBYTE, DataType.UWORD -> {
|
||||
val existing = if(forLoop.body.isEmpty()) null else forLoop.body.lookup(loopVar.nameInSource, forLoop.body.statements.first())
|
||||
if(existing==null) {
|
||||
val vardecl = VarDecl(VarDeclType.VAR, forLoop.decltype, null, varName, null, loopVar.position)
|
||||
|
@ -100,7 +100,7 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
||||
|
||||
// for variables that are not on the heap (so: byte, word, float),
|
||||
// replace the var decl with an assignment and add a new vardecl with the default constant value.
|
||||
if(decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT) {
|
||||
if(decl.datatype in NumericDatatypes) {
|
||||
val scope = decl.definingScope()
|
||||
if(scope !in vardeclsToAdd)
|
||||
vardeclsToAdd[scope] = mutableListOf()
|
||||
|
@ -164,26 +164,26 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
|
||||
|
||||
instructions.asSequence().withIndex().windowed(2).toList().forEach {
|
||||
when(it[0].value.opcode) {
|
||||
Opcode.PUSH_VAR ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR) {
|
||||
Opcode.PUSH_VAR_BYTE ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR_BYTE) {
|
||||
if(it[0].value.callLabel!=it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR_BYTE, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
else
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.PUSH_VAR_W ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR_W) {
|
||||
Opcode.PUSH_VAR_WORD ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR_WORD) {
|
||||
if(it[0].value.callLabel!=it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR_W, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR_WORD, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
else
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.PUSH_VAR_F ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR_F) {
|
||||
Opcode.PUSH_VAR_FLOAT ->
|
||||
if(it[1].value.opcode==Opcode.POP_VAR_FLOAT) {
|
||||
if(it[0].value.callLabel!=it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR_F, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.COPY_VAR_FLOAT, null, it[0].value.callLabel, it[1].value.callLabel)
|
||||
else
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
@ -208,9 +208,9 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
|
||||
Opcode.MSB2WORD,
|
||||
Opcode.B2FLOAT,
|
||||
Opcode.W2FLOAT,
|
||||
Opcode.DISCARD,
|
||||
Opcode.DISCARD_W,
|
||||
Opcode.DISCARD_F
|
||||
Opcode.DISCARD_BYTE,
|
||||
Opcode.DISCARD_WORD,
|
||||
Opcode.DISCARD_FLOAT
|
||||
)
|
||||
|
||||
val instructionsToReplace = mutableMapOf<Int, Instruction>()
|
||||
@ -218,40 +218,40 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
|
||||
this.instructions.asSequence().withIndex().windowed(2).toList().forEach {
|
||||
if(it[1].value.opcode in typeConversionOpcodes) {
|
||||
when(it[0].value.opcode) {
|
||||
Opcode.PUSH -> when (it[1].value.opcode) {
|
||||
Opcode.PUSH_BYTE -> when (it[1].value.opcode) {
|
||||
Opcode.LSB -> instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
Opcode.MSB -> throw CompilerException("msb of a byte")
|
||||
Opcode.B2WORD -> {
|
||||
val ins = Instruction(Opcode.PUSH_W, Value(DataType.WORD, it[0].value.arg!!.integerValue()))
|
||||
val ins = Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, it[0].value.arg!!.integerValue()))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.MSB2WORD -> {
|
||||
val ins = Instruction(Opcode.PUSH_W, Value(DataType.WORD, 256 * it[0].value.arg!!.integerValue()))
|
||||
val ins = Instruction(Opcode.PUSH_WORD, Value(DataType.UWORD, 256 * it[0].value.arg!!.integerValue()))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.B2FLOAT -> {
|
||||
val ins = Instruction(Opcode.PUSH_F, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
|
||||
val ins = Instruction(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.W2FLOAT -> throw CompilerException("invalid conversion following a byte")
|
||||
Opcode.DISCARD -> {
|
||||
Opcode.DISCARD_BYTE -> {
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD_W, Opcode.DISCARD_F -> throw CompilerException("invalid discard type following a byte")
|
||||
Opcode.DISCARD_WORD, Opcode.DISCARD_FLOAT -> throw CompilerException("invalid discard type following a byte")
|
||||
else -> {}
|
||||
}
|
||||
Opcode.PUSH_W -> when (it[1].value.opcode) {
|
||||
Opcode.PUSH_WORD -> when (it[1].value.opcode) {
|
||||
Opcode.LSB -> {
|
||||
val ins = Instruction(Opcode.PUSH, Value(DataType.BYTE, it[0].value.arg!!.integerValue() and 255))
|
||||
val ins = Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, it[0].value.arg!!.integerValue() and 255))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.MSB -> {
|
||||
val ins = Instruction(Opcode.PUSH, Value(DataType.BYTE, it[0].value.arg!!.integerValue() ushr 8 and 255))
|
||||
val ins = Instruction(Opcode.PUSH_BYTE, Value(DataType.UBYTE, it[0].value.arg!!.integerValue() ushr 8 and 255))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
@ -259,38 +259,38 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
|
||||
Opcode.MSB2WORD,
|
||||
Opcode.B2FLOAT -> throw CompilerException("invalid conversion following a word")
|
||||
Opcode.W2FLOAT -> {
|
||||
val ins = Instruction(Opcode.PUSH_F, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
|
||||
val ins = Instruction(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
|
||||
instructionsToReplace[it[0].index] = ins
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD_W -> {
|
||||
Opcode.DISCARD_WORD -> {
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD, Opcode.DISCARD_F -> throw CompilerException("invalid discard type following a byte")
|
||||
Opcode.DISCARD_BYTE, Opcode.DISCARD_FLOAT -> throw CompilerException("invalid discard type following a byte")
|
||||
else -> {}
|
||||
}
|
||||
Opcode.PUSH_F -> when (it[1].value.opcode) {
|
||||
Opcode.PUSH_FLOAT -> when (it[1].value.opcode) {
|
||||
Opcode.LSB,
|
||||
Opcode.MSB,
|
||||
Opcode.B2WORD,
|
||||
Opcode.MSB2WORD,
|
||||
Opcode.B2FLOAT,
|
||||
Opcode.W2FLOAT -> throw CompilerException("invalid conversion following a float")
|
||||
Opcode.DISCARD_F -> {
|
||||
Opcode.DISCARD_FLOAT -> {
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
Opcode.DISCARD, Opcode.DISCARD_W -> throw CompilerException("invalid discard type following a float")
|
||||
Opcode.DISCARD_BYTE, Opcode.DISCARD_WORD -> throw CompilerException("invalid discard type following a float")
|
||||
else -> {}
|
||||
}
|
||||
Opcode.PUSH_VAR_F,
|
||||
Opcode.PUSH_VAR_W,
|
||||
Opcode.PUSH_VAR,
|
||||
Opcode.PUSH_MEM,
|
||||
Opcode.PUSH_MEM_W,
|
||||
Opcode.PUSH_MEM_F -> when (it[1].value.opcode) {
|
||||
Opcode.DISCARD_F, Opcode.DISCARD_W, Opcode.DISCARD -> {
|
||||
Opcode.PUSH_VAR_FLOAT,
|
||||
Opcode.PUSH_VAR_WORD,
|
||||
Opcode.PUSH_VAR_BYTE,
|
||||
Opcode.PUSH_MEM_BYTE,
|
||||
Opcode.PUSH_MEM_WORD,
|
||||
Opcode.PUSH_MEM_FLOAT -> when (it[1].value.opcode) {
|
||||
Opcode.DISCARD_FLOAT, Opcode.DISCARD_WORD, Opcode.DISCARD_BYTE -> {
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.NOP)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
@ -308,14 +308,15 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
|
||||
|
||||
fun blockvar(scopedname: String, decl: VarDecl) {
|
||||
val value = when(decl.datatype) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> Value(decl.datatype, (decl.value as LiteralValue).asNumericValue!!)
|
||||
DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> Value(decl.datatype, (decl.value as LiteralValue).asNumericValue!!)
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
|
||||
val litval = (decl.value as LiteralValue)
|
||||
if(litval.heapId==null)
|
||||
throw CompilerException("string should already be in the heap")
|
||||
Value(decl.datatype, litval.heapId)
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> {
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F -> {
|
||||
val litval = (decl.value as LiteralValue)
|
||||
if(litval.heapId==null)
|
||||
throw CompilerException("array/matrix should already be in the heap")
|
||||
@ -471,17 +472,20 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
|
||||
private fun opcodePush(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.BYTE -> Opcode.PUSH
|
||||
DataType.WORD -> Opcode.PUSH_W
|
||||
DataType.FLOAT -> Opcode.PUSH_F
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.PUSH_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.PUSH_WORD
|
||||
DataType.FLOAT -> Opcode.PUSH_FLOAT
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> Opcode.PUSH_W
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B -> Opcode.PUSH_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeAdd(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.UBYTE -> Opcode.ADD_UB
|
||||
DataType.BYTE -> Opcode.ADD_B
|
||||
DataType.UWORD -> Opcode.ADD_UW
|
||||
DataType.WORD -> Opcode.ADD_W
|
||||
DataType.FLOAT -> Opcode.ADD_F
|
||||
else -> throw CompilerException("invalid dt $dt")
|
||||
@ -490,7 +494,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
|
||||
private fun opcodeSub(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.UBYTE -> Opcode.SUB_UB
|
||||
DataType.BYTE -> Opcode.SUB_B
|
||||
DataType.UWORD -> Opcode.SUB_UW
|
||||
DataType.WORD -> Opcode.SUB_W
|
||||
DataType.FLOAT -> Opcode.SUB_F
|
||||
else -> throw CompilerException("invalid dt $dt")
|
||||
@ -499,85 +505,90 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
|
||||
private fun opcodePushvar(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.BYTE -> Opcode.PUSH_VAR
|
||||
DataType.WORD -> Opcode.PUSH_VAR_W
|
||||
DataType.FLOAT -> Opcode.PUSH_VAR_F
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.PUSH_VAR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.PUSH_VAR_WORD
|
||||
DataType.FLOAT -> Opcode.PUSH_VAR_FLOAT
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> Opcode.PUSH_VAR_W
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B -> Opcode.PUSH_VAR_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodePushvar(reg: Register): Opcode {
|
||||
return when(reg) {
|
||||
Register.A, Register.X, Register.Y -> Opcode.PUSH_VAR
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.PUSH_VAR_W
|
||||
Register.A, Register.X, Register.Y -> Opcode.PUSH_VAR_BYTE
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.PUSH_VAR_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodePopvar(reg: Register): Opcode {
|
||||
return when(reg) {
|
||||
Register.A, Register.X, Register.Y -> Opcode.POP_VAR
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.POP_VAR_W
|
||||
Register.A, Register.X, Register.Y -> Opcode.POP_VAR_BYTE
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.POP_VAR_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeReadindexedvar(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.ARRAY -> Opcode.READ_INDEXED_VAR
|
||||
DataType.ARRAY_W -> Opcode.READ_INDEXED_VAR_W
|
||||
DataType.ARRAY_F -> Opcode.READ_INDEXED_VAR_F
|
||||
DataType.MATRIX -> Opcode.READ_INDEXED_VAR
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> Opcode.READ_INDEXED_VAR_BYTE
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.READ_INDEXED_VAR_WORD
|
||||
DataType.ARRAY_F -> Opcode.READ_INDEXED_VAR_FLOAT
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.READ_INDEXED_VAR_BYTE
|
||||
else -> throw CompilerException("invalid dt for indexed $dt")
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeWriteindexedvar(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.ARRAY -> Opcode.WRITE_INDEXED_VAR
|
||||
DataType.ARRAY_W -> Opcode.WRITE_INDEXED_VAR_W
|
||||
DataType.ARRAY_F -> Opcode.WRITE_INDEXED_VAR_F
|
||||
DataType.MATRIX -> Opcode.WRITE_INDEXED_VAR
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> Opcode.WRITE_INDEXED_VAR_BYTE
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.WRITE_INDEXED_VAR_WORD
|
||||
DataType.ARRAY_F -> Opcode.WRITE_INDEXED_VAR_FLOAT
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.WRITE_INDEXED_VAR_BYTE
|
||||
else -> throw CompilerException("invalid dt for indexed $dt")
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeDiscard(dt: DataType): Opcode {
|
||||
return when(dt) {
|
||||
DataType.BYTE -> Opcode.DISCARD
|
||||
DataType.WORD -> Opcode.DISCARD_W
|
||||
DataType.FLOAT -> Opcode.DISCARD_F
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.DISCARD_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.DISCARD_WORD
|
||||
DataType.FLOAT -> Opcode.DISCARD_FLOAT
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> Opcode.DISCARD_W
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B -> Opcode.DISCARD_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodePopvar(dt: DataType): Opcode {
|
||||
return when (dt) {
|
||||
DataType.BYTE -> Opcode.POP_VAR
|
||||
DataType.WORD -> Opcode.POP_VAR_W
|
||||
DataType.FLOAT -> Opcode.POP_VAR_F
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.POP_VAR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.POP_VAR_WORD
|
||||
DataType.FLOAT -> Opcode.POP_VAR_FLOAT
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> Opcode.POP_VAR_W
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B -> Opcode.POP_VAR_WORD
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeDecvar(reg: Register): Opcode {
|
||||
return when(reg) {
|
||||
Register.A, Register.X, Register.Y -> Opcode.DEC_VAR
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.DEC_VAR_W
|
||||
Register.A, Register.X, Register.Y -> Opcode.DEC_VAR_UB
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.DEC_VAR_UW
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeIncvar(reg: Register): Opcode {
|
||||
return when(reg) {
|
||||
Register.A, Register.X, Register.Y -> Opcode.INC_VAR
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.INC_VAR_W
|
||||
Register.A, Register.X, Register.Y -> Opcode.INC_VAR_UB
|
||||
Register.AX, Register.AY, Register.XY -> Opcode.INC_VAR_UW
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeDecvar(dt: DataType): Opcode {
|
||||
return when(dt) {
|
||||
DataType.BYTE -> Opcode.DEC_VAR
|
||||
DataType.UBYTE -> Opcode.DEC_VAR_UB
|
||||
DataType.BYTE -> Opcode.DEC_VAR_B
|
||||
DataType.UWORD -> Opcode.DEC_VAR_UW
|
||||
DataType.WORD -> Opcode.DEC_VAR_W
|
||||
else -> throw CompilerException("can't dec type $dt")
|
||||
}
|
||||
@ -585,7 +596,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
|
||||
private fun opcodeIncvar(dt: DataType): Opcode {
|
||||
return when(dt) {
|
||||
DataType.BYTE -> Opcode.INC_VAR
|
||||
DataType.UBYTE -> Opcode.INC_VAR_UB
|
||||
DataType.BYTE -> Opcode.INC_VAR_B
|
||||
DataType.UWORD -> Opcode.INC_VAR_UW
|
||||
DataType.WORD -> Opcode.INC_VAR_W
|
||||
else -> throw CompilerException("can't inc type $dt")
|
||||
}
|
||||
@ -706,10 +719,34 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
val floatWarning = "byte or word value implicitly converted to float. Suggestion: use explicit flt() conversion, a float number, or revert to byte/word arithmetic"
|
||||
|
||||
return when(leftDt) {
|
||||
DataType.UBYTE -> {
|
||||
when(rightDt) {
|
||||
DataType.UBYTE -> DataType.UBYTE
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD -> DataType.UWORD
|
||||
DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> {
|
||||
printWarning(floatWarning, leftpos)
|
||||
DataType.FLOAT
|
||||
}
|
||||
else -> throw CompilerException("non-numeric datatype $rightDt")
|
||||
}
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
when(rightDt) {
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.WORD -> DataType.WORD
|
||||
DataType.UBYTE, DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> {
|
||||
printWarning(floatWarning, leftpos)
|
||||
DataType.FLOAT
|
||||
}
|
||||
else -> throw CompilerException("non-numeric datatype $rightDt")
|
||||
}
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
when(rightDt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> {
|
||||
printWarning(floatWarning, leftpos)
|
||||
DataType.FLOAT
|
||||
@ -719,7 +756,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
DataType.WORD -> {
|
||||
when(rightDt) {
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.UBYTE, DataType.UWORD, DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> {
|
||||
printWarning(floatWarning, leftpos)
|
||||
DataType.FLOAT
|
||||
@ -780,18 +817,19 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
else -> {
|
||||
val lv = expr.constValue(namespace, heap) ?: throw CompilerException("constant expression required, not $expr")
|
||||
when(lv.type) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.PUSH, Value(DataType.BYTE, lv.bytevalue!!))
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.PUSH_W, Value(DataType.WORD, lv.wordvalue!!))
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.PUSH_F, Value(DataType.FLOAT, lv.floatvalue!!))
|
||||
DataType.UBYTE, DataType.BYTE -> stackvmProg.instr(Opcode.PUSH_BYTE, Value(DataType.UBYTE, lv.bytevalue!!))
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.PUSH_WORD, Value(DataType.UWORD, lv.wordvalue!!))
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.PUSH_FLOAT, Value(DataType.FLOAT, lv.floatvalue!!))
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
|
||||
if(lv.heapId==null)
|
||||
throw CompilerException("string should have been moved into heap ${lv.position}")
|
||||
stackvmProg.instr(Opcode.PUSH_W, Value(lv.type, lv.heapId))
|
||||
stackvmProg.instr(Opcode.PUSH_WORD, Value(lv.type, lv.heapId))
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW, DataType.ARRAY_F, DataType.MATRIX_UB,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W, DataType.MATRIX_B -> {
|
||||
if(lv.heapId==null)
|
||||
throw CompilerException("array/matrix should have been moved into heap ${lv.position}")
|
||||
stackvmProg.instr(Opcode.PUSH_W, Value(lv.type, lv.heapId))
|
||||
stackvmProg.instr(Opcode.PUSH_WORD, Value(lv.type, lv.heapId))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -802,25 +840,32 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
// only WIDENS a type, never NARROWS
|
||||
if(givenDt==targetDt)
|
||||
return
|
||||
if(givenDt!=DataType.BYTE && givenDt!=DataType.WORD && givenDt!=DataType.FLOAT)
|
||||
throw CompilerException("converting a non-numeric $givenDt")
|
||||
if(targetDt!=DataType.BYTE && targetDt!=DataType.WORD && targetDt!=DataType.FLOAT)
|
||||
throw CompilerException("converting to non-numeric $targetDt")
|
||||
if(givenDt !in NumericDatatypes)
|
||||
throw CompilerException("converting non-numeric $givenDt")
|
||||
if(targetDt !in NumericDatatypes)
|
||||
throw CompilerException("converting $givenDt to non-numeric $targetDt")
|
||||
when(givenDt) {
|
||||
DataType.BYTE -> when(targetDt) {
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.B2WORD)
|
||||
DataType.UBYTE -> when(targetDt) {
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.UB2UWORD)
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.B2FLOAT)
|
||||
else -> {}
|
||||
}
|
||||
DataType.BYTE -> when(targetDt) {
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.B2WORD)
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.B2FLOAT)
|
||||
else -> {}
|
||||
}
|
||||
DataType.UWORD -> when(targetDt) {
|
||||
DataType.UBYTE, DataType.BYTE -> throw CompilerException("narrowing type")
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.UW2FLOAT)
|
||||
else -> {}
|
||||
}
|
||||
DataType.WORD -> when(targetDt) {
|
||||
DataType.BYTE -> throw CompilerException("narrowing type")
|
||||
DataType.UBYTE, DataType.BYTE -> throw CompilerException("narrowing type")
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.W2FLOAT)
|
||||
else -> {}
|
||||
}
|
||||
DataType.FLOAT -> when(targetDt) {
|
||||
DataType.BYTE, DataType.WORD -> throw CompilerException("narrowing type")
|
||||
else -> {}
|
||||
}
|
||||
DataType.FLOAT -> if(targetDt in IntegerDatatypes) throw CompilerException("narrowing type")
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@ -838,9 +883,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
throw CompilerException("const ref should have been const-folded away")
|
||||
VarDeclType.MEMORY -> {
|
||||
when (target.datatype) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.PUSH_MEM, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.PUSH_MEM_W, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.PUSH_MEM_F, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.PUSH_MEM_BYTE, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.PUSH_MEM_WORD, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.PUSH_MEM_FLOAT, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
else -> TODO("invalid datatype for memory variable expression: $target")
|
||||
}
|
||||
}
|
||||
@ -884,8 +929,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
// 1 argument, type determines the exact opcode to use
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.B2FLOAT)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.W2FLOAT)
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.B2FLOAT)
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.W2FLOAT)
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.NOP)
|
||||
else -> throw CompilerException("wrong datatype for flt()")
|
||||
}
|
||||
@ -897,48 +942,48 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
"lsl" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.SHL)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.SHL_W)
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.SHL_BYTE)
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.SHL_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
"lsr" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.SHR)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.SHR_W)
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.SHR_BYTE)
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.SHR_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
"rol" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.ROL)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.ROL_W)
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.ROL_BYTE)
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.ROL_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
"ror" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.ROR)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.ROR_W)
|
||||
DataType.UBYTE, DataType.BYTE -> stackvmProg.instr(Opcode.ROR_BYTE)
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.ROR_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
"rol2" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.ROL2)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.ROL2_W)
|
||||
DataType.UBYTE, DataType.BYTE -> stackvmProg.instr(Opcode.ROL2_BYTE)
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.ROL2_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
"ror2" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.ROR2)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.ROR2_W)
|
||||
DataType.UBYTE, DataType.BYTE -> stackvmProg.instr(Opcode.ROR2_BYTE)
|
||||
DataType.UWORD, DataType.WORD -> stackvmProg.instr(Opcode.ROR2_WORD)
|
||||
else -> throw CompilerException("wrong datatype")
|
||||
}
|
||||
}
|
||||
@ -962,13 +1007,14 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
|
||||
private fun translateBinaryOperator(operator: String, dt: DataType) {
|
||||
val validDt = setOf(DataType.BYTE, DataType.WORD, DataType.FLOAT)
|
||||
if(dt !in validDt)
|
||||
throw CompilerException("invalid datatype for operator: $dt")
|
||||
if(dt !in NumericDatatypes)
|
||||
throw CompilerException("non-numeric datatype for operator: $dt")
|
||||
val opcode = when(operator) {
|
||||
"+" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.ADD_UB
|
||||
DataType.BYTE -> Opcode.ADD_B
|
||||
DataType.UWORD -> Opcode.ADD_UW
|
||||
DataType.WORD -> Opcode.ADD_W
|
||||
DataType.FLOAT -> Opcode.ADD_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -976,7 +1022,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"-" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.SUB_UB
|
||||
DataType.BYTE -> Opcode.SUB_B
|
||||
DataType.UWORD -> Opcode.SUB_UW
|
||||
DataType.WORD -> Opcode.SUB_W
|
||||
DataType.FLOAT -> Opcode.SUB_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -984,7 +1032,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"*" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.MUL_UB
|
||||
DataType.BYTE -> Opcode.MUL_B
|
||||
DataType.UWORD -> Opcode.MUL_UW
|
||||
DataType.WORD -> Opcode.MUL_W
|
||||
DataType.FLOAT -> Opcode.MUL_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -992,7 +1042,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"/" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.DIV_UB
|
||||
DataType.BYTE -> Opcode.DIV_B
|
||||
DataType.UWORD -> Opcode.DIV_UW
|
||||
DataType.WORD -> Opcode.DIV_W
|
||||
DataType.FLOAT -> Opcode.DIV_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -1000,7 +1052,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"//" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.FLOORDIV_UB
|
||||
DataType.BYTE -> Opcode.FLOORDIV_B
|
||||
DataType.UWORD -> Opcode.FLOORDIV_UW
|
||||
DataType.WORD -> Opcode.FLOORDIV_W
|
||||
DataType.FLOAT -> Opcode.FLOORDIV_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -1008,7 +1062,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"%" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.REMAINDER_UB
|
||||
DataType.BYTE -> Opcode.REMAINDER_B
|
||||
DataType.UWORD -> Opcode.REMAINDER_UW
|
||||
DataType.WORD -> Opcode.REMAINDER_W
|
||||
DataType.FLOAT -> Opcode.REMAINDER_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -1016,7 +1072,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"**" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> Opcode.POW_UB
|
||||
DataType.BYTE -> Opcode.POW_B
|
||||
DataType.UWORD -> Opcode.POW_UW
|
||||
DataType.WORD -> Opcode.POW_W
|
||||
DataType.FLOAT -> Opcode.POW_F
|
||||
else -> throw CompilerException("only byte/word/float possible")
|
||||
@ -1024,49 +1082,51 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"&" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.BITAND
|
||||
DataType.WORD -> Opcode.BITAND_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITAND_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITAND_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"|" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.BITOR
|
||||
DataType.WORD -> Opcode.BITOR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITOR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITOR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"^" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.BITXOR
|
||||
DataType.WORD -> Opcode.BITXOR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITXOR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITXOR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"and" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.AND
|
||||
DataType.WORD -> Opcode.AND_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.AND_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.AND_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"or" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.OR
|
||||
DataType.WORD -> Opcode.OR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.OR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.OR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"xor" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.XOR
|
||||
DataType.WORD -> Opcode.XOR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.XOR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.XOR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"<" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.LESS
|
||||
DataType.UBYTE -> Opcode.LESS_UB
|
||||
DataType.BYTE -> Opcode.LESS_B
|
||||
DataType.UWORD -> Opcode.LESS_UW
|
||||
DataType.WORD -> Opcode.LESS_W
|
||||
DataType.FLOAT -> Opcode.LESS_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
@ -1074,7 +1134,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
">" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.GREATER
|
||||
DataType.UBYTE -> Opcode.GREATER_UB
|
||||
DataType.BYTE -> Opcode.GREATER_B
|
||||
DataType.UWORD -> Opcode.GREATER_UW
|
||||
DataType.WORD -> Opcode.GREATER_W
|
||||
DataType.FLOAT -> Opcode.GREATER_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
@ -1082,7 +1144,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"<=" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.LESSEQ
|
||||
DataType.UBYTE -> Opcode.LESSEQ_UB
|
||||
DataType.BYTE -> Opcode.LESSEQ_B
|
||||
DataType.UWORD -> Opcode.LESSEQ_UW
|
||||
DataType.WORD -> Opcode.LESSEQ_W
|
||||
DataType.FLOAT -> Opcode.LESSEQ_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
@ -1090,7 +1154,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
">=" -> {
|
||||
when(dt) {
|
||||
DataType.BYTE -> Opcode.GREATEREQ
|
||||
DataType.UBYTE -> Opcode.GREATEREQ_UB
|
||||
DataType.BYTE -> Opcode.GREATEREQ_B
|
||||
DataType.UWORD -> Opcode.GREATEREQ_UW
|
||||
DataType.WORD -> Opcode.GREATEREQ_W
|
||||
DataType.FLOAT -> Opcode.GREATEREQ_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
@ -1098,16 +1164,16 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"==" -> {
|
||||
when (dt) {
|
||||
DataType.BYTE -> Opcode.EQUAL
|
||||
DataType.WORD -> Opcode.EQUAL_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.EQUAL_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.EQUAL_WORD
|
||||
DataType.FLOAT -> Opcode.EQUAL_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"!=" -> {
|
||||
when (dt) {
|
||||
DataType.BYTE -> Opcode.NOTEQUAL
|
||||
DataType.WORD -> Opcode.NOTEQUAL_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.NOTEQUAL_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.NOTEQUAL_WORD
|
||||
DataType.FLOAT -> Opcode.NOTEQUAL_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
@ -1127,20 +1193,20 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
DataType.BYTE -> Opcode.NEG_B
|
||||
DataType.WORD -> Opcode.NEG_W
|
||||
DataType.FLOAT -> Opcode.NEG_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
else -> throw CompilerException("only byte/word/foat possible")
|
||||
}
|
||||
}
|
||||
"~" -> {
|
||||
when(operandDt) {
|
||||
DataType.BYTE -> Opcode.INV
|
||||
DataType.WORD -> Opcode.INV_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.INV_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.INV_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"not" -> {
|
||||
when(operandDt) {
|
||||
DataType.BYTE -> Opcode.NOT
|
||||
DataType.WORD -> Opcode.NOT_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.NOT_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.NOT_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
@ -1168,9 +1234,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
// calc matrix index i=y*columns+x
|
||||
// (the const-folding will have removed this for us when both x and y are constants)
|
||||
translate(y)
|
||||
stackvmProg.instr(Opcode.PUSH, Value(DataType.WORD, (variable!!.arrayspec!!.x as LiteralValue).asIntegerValue!!))
|
||||
stackvmProg.instr(Opcode.MUL_W)
|
||||
stackvmProg.instr(Opcode.ADD_W)
|
||||
stackvmProg.instr(Opcode.PUSH_BYTE, Value(DataType.UWORD, (variable!!.arrayspec!!.x as LiteralValue).asIntegerValue!!))
|
||||
stackvmProg.instr(Opcode.MUL_UW)
|
||||
stackvmProg.instr(Opcode.ADD_UW)
|
||||
}
|
||||
|
||||
if(variable!=null) {
|
||||
@ -1181,9 +1247,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
} else {
|
||||
// register indexed
|
||||
if (write)
|
||||
stackvmProg.instr(opcodeWriteindexedvar(DataType.ARRAY), callLabel = arrayindexed.register!!.toString())
|
||||
stackvmProg.instr(opcodeWriteindexedvar(DataType.ARRAY_UB), callLabel = arrayindexed.register!!.toString())
|
||||
else
|
||||
stackvmProg.instr(opcodeReadindexedvar(DataType.ARRAY), callLabel = arrayindexed.register!!.toString())
|
||||
stackvmProg.instr(opcodeReadindexedvar(DataType.ARRAY_UB), callLabel = arrayindexed.register!!.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1261,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
"FUNC_$funcname"
|
||||
).toUpperCase()
|
||||
val callNr = Syscall.valueOf(function).callNr
|
||||
stackvmProg.instr(Opcode.SYSCALL, Value(DataType.BYTE, callNr))
|
||||
stackvmProg.instr(Opcode.SYSCALL, Value(DataType.UBYTE, callNr))
|
||||
}
|
||||
|
||||
private fun translate(stmt: Jump) {
|
||||
@ -1204,7 +1270,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
|
||||
when {
|
||||
stmt.generatedLabel!=null -> jumpLabel = stmt.generatedLabel
|
||||
stmt.address!=null -> jumpAddress = Value(DataType.WORD, stmt.address)
|
||||
stmt.address!=null -> jumpAddress = Value(DataType.UWORD, stmt.address)
|
||||
else -> {
|
||||
val target = stmt.identifier!!.targetStatement(namespace)!!
|
||||
jumpLabel = when(target) {
|
||||
@ -1263,23 +1329,27 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
if(valueDt!=targetDt) {
|
||||
// convert value to target datatype if possible
|
||||
when(targetDt) {
|
||||
DataType.BYTE -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.WORD -> {
|
||||
if(valueDt==DataType.BYTE)
|
||||
stackvmProg.instr(Opcode.B2WORD)
|
||||
else
|
||||
throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.UBYTE, DataType.BYTE -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.UWORD, DataType.WORD -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.UB2UWORD)
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.B2WORD)
|
||||
else -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
}
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
when (valueDt) {
|
||||
DataType.UBYTE -> stackvmProg.instr(Opcode.UB2FLOAT)
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.B2FLOAT)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.W2FLOAT)
|
||||
DataType.UWORD -> stackvmProg.instr(Opcode.W2FLOAT)
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.UW2FLOAT)
|
||||
else -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
}
|
||||
}
|
||||
// todo: maybe if you assign byte or word to array/matrix, clear it with that value?
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W,
|
||||
DataType.ARRAY_F, DataType.MATRIX_UB, DataType.MATRIX_B -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
null -> throw CompilerException("could not determine targetdt")
|
||||
}
|
||||
}
|
||||
@ -1330,76 +1400,76 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
private fun translateAugAssignOperator(aug_op: String, valueDt: DataType?) {
|
||||
if(valueDt==null)
|
||||
throw CompilerException("value datatype not known")
|
||||
val validDt = setOf(DataType.BYTE, DataType.WORD, DataType.FLOAT)
|
||||
val validDt = setOf(DataType.UBYTE, DataType.UWORD, DataType.FLOAT)
|
||||
if(valueDt !in validDt)
|
||||
throw CompilerException("invalid datatype(s) for operand(s)")
|
||||
val opcode = when(aug_op) {
|
||||
"+=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.ADD_B
|
||||
DataType.WORD -> Opcode.ADD_W
|
||||
DataType.UBYTE -> Opcode.ADD_UB
|
||||
DataType.UWORD -> Opcode.ADD_UW
|
||||
DataType.FLOAT -> Opcode.ADD_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"-=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.SUB_B
|
||||
DataType.WORD -> Opcode.SUB_W
|
||||
DataType.UBYTE -> Opcode.SUB_UB
|
||||
DataType.UWORD -> Opcode.SUB_UW
|
||||
DataType.FLOAT -> Opcode.SUB_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"/=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.DIV_B
|
||||
DataType.WORD -> Opcode.DIV_W
|
||||
DataType.UBYTE -> Opcode.DIV_UB
|
||||
DataType.UWORD -> Opcode.DIV_UW
|
||||
DataType.FLOAT -> Opcode.DIV_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"//=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.FLOORDIV_B
|
||||
DataType.WORD -> Opcode.FLOORDIV_W
|
||||
DataType.UBYTE -> Opcode.FLOORDIV_UB
|
||||
DataType.UWORD -> Opcode.FLOORDIV_UW
|
||||
DataType.FLOAT -> Opcode.FLOORDIV_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"*=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.MUL_B
|
||||
DataType.WORD -> Opcode.MUL_W
|
||||
DataType.UBYTE -> Opcode.MUL_UB
|
||||
DataType.UWORD -> Opcode.MUL_UW
|
||||
DataType.FLOAT -> Opcode.MUL_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"**=" -> {
|
||||
when (valueDt) {
|
||||
DataType.BYTE -> Opcode.POW_B
|
||||
DataType.WORD -> Opcode.POW_W
|
||||
DataType.UBYTE -> Opcode.POW_UB
|
||||
DataType.UWORD -> Opcode.POW_UW
|
||||
DataType.FLOAT -> Opcode.POW_F
|
||||
else -> throw CompilerException("only byte/word/lfoat possible")
|
||||
}
|
||||
}
|
||||
"&=" -> {
|
||||
when(valueDt) {
|
||||
DataType.BYTE -> Opcode.BITAND
|
||||
DataType.WORD -> Opcode.BITAND_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITAND_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITAND_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"|=" -> {
|
||||
when(valueDt) {
|
||||
DataType.BYTE -> Opcode.BITOR
|
||||
DataType.WORD -> Opcode.BITOR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITOR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITOR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
"^=" -> {
|
||||
when(valueDt) {
|
||||
DataType.BYTE -> Opcode.BITXOR
|
||||
DataType.WORD -> Opcode.BITXOR_W
|
||||
DataType.UBYTE, DataType.BYTE -> Opcode.BITXOR_BYTE
|
||||
DataType.UWORD, DataType.WORD -> Opcode.BITXOR_WORD
|
||||
else -> throw CompilerException("only byte/word possible")
|
||||
}
|
||||
}
|
||||
@ -1431,8 +1501,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
val reg = loop.loopRegister
|
||||
loopVarName = reg.toString()
|
||||
loopVarDt = when (reg) {
|
||||
Register.A, Register.X, Register.Y -> DataType.BYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.WORD
|
||||
Register.A, Register.X, Register.Y -> DataType.UBYTE
|
||||
Register.AX, Register.AY, Register.XY -> DataType.UWORD
|
||||
}
|
||||
} else {
|
||||
val loopvar = (loop.loopVar!!.targetStatement(namespace) as VarDecl)
|
||||
@ -1451,11 +1521,11 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
if((range.last-range.first) % range.step != 0)
|
||||
throw CompilerException("range first and last must be exactly inclusive")
|
||||
when (loopVarDt) {
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
if (range.first < 0 || range.first > 255 || range.last < 0 || range.last > 255)
|
||||
throw CompilerException("range out of bounds for byte")
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.UWORD -> {
|
||||
if (range.first < 0 || range.first > 65535 || range.last < 0 || range.last > 65535)
|
||||
throw CompilerException("range out of bounds for word")
|
||||
}
|
||||
@ -1492,17 +1562,17 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
|
||||
private fun translateForOverIterableVar(loop: ForLoop, loopvarDt: DataType, iterableValue: LiteralValue) {
|
||||
if(loopvarDt==DataType.BYTE && iterableValue.type !in setOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.ARRAY, DataType.MATRIX))
|
||||
if(loopvarDt==DataType.UBYTE && iterableValue.type !in setOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.ARRAY_UB, DataType.MATRIX_UB))
|
||||
throw CompilerException("loop variable type doesn't match iterableValue type")
|
||||
else if(loopvarDt==DataType.WORD && iterableValue.type != DataType.ARRAY_W)
|
||||
else if(loopvarDt==DataType.UWORD && iterableValue.type != DataType.ARRAY_UW)
|
||||
throw CompilerException("loop variable type doesn't match iterableValue type")
|
||||
else if(loopvarDt==DataType.FLOAT && iterableValue.type != DataType.ARRAY_F)
|
||||
throw CompilerException("loop variable type doesn't match iterableValue type")
|
||||
val numElements: Int
|
||||
val indexVar: String
|
||||
when(iterableValue.type) {
|
||||
DataType.BYTE,
|
||||
DataType.WORD,
|
||||
DataType.UBYTE, DataType.BYTE,
|
||||
DataType.UWORD, DataType.WORD,
|
||||
DataType.FLOAT -> throw CompilerException("non-iterableValue type")
|
||||
DataType.STR,
|
||||
DataType.STR_P,
|
||||
@ -1511,9 +1581,9 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
numElements = iterableValue.strvalue?.length ?: heap.get(iterableValue.heapId!!).str!!.length
|
||||
indexVar = if(numElements>255) "XY" else "X"
|
||||
}
|
||||
DataType.ARRAY,
|
||||
DataType.ARRAY_W,
|
||||
DataType.MATRIX -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B,
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W,
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
numElements = iterableValue.arrayvalue?.size ?: heap.get(iterableValue.heapId!!).array!!.size
|
||||
indexVar = if(numElements>255) "XY" else "X"
|
||||
}
|
||||
@ -1549,7 +1619,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
continueStmtLabelStack.push(continueLabel)
|
||||
breakStmtLabelStack.push(breakLabel)
|
||||
|
||||
val zero = Value(if(numElements<=255) DataType.BYTE else DataType.WORD, 0)
|
||||
val zero = Value(if(numElements<=255) DataType.UBYTE else DataType.UWORD, 0)
|
||||
stackvmProg.instr(opcodePush(zero.type), zero)
|
||||
stackvmProg.instr(opcodePopvar(zero.type), callLabel = indexVar)
|
||||
stackvmProg.label(loopLabel)
|
||||
@ -1565,7 +1635,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
stackvmProg.label(continueLabel)
|
||||
stackvmProg.instr(opcodeIncvar(zero.type), callLabel = indexVar)
|
||||
|
||||
// TODO: optimize edge cases if last value = 255 or 0 (for bytes) etc. to avoid PUSH / SUB opcodes and make use of the wrapping around of the value.
|
||||
// TODO: optimize edge cases if last value = 255 or 0 (for bytes) etc. to avoid PUSH_BYTE / SUB opcodes and make use of the wrapping around of the value.
|
||||
stackvmProg.instr(opcodePush(zero.type), Value(zero.type, numElements))
|
||||
stackvmProg.instr(opcodePushvar(zero.type), callLabel = indexVar)
|
||||
stackvmProg.instr(opcodeSub(zero.type))
|
||||
@ -1627,7 +1697,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: optimize edge cases if last value = 255 or 0 (for bytes) etc. to avoid PUSH / SUB opcodes and make use of the wrapping around of the value.
|
||||
// TODO: optimize edge cases if last value = 255 or 0 (for bytes) etc. to avoid PUSH_BYTE / SUB opcodes and make use of the wrapping around of the value.
|
||||
stackvmProg.instr(opcodePush(varDt), Value(varDt, range.last+range.step))
|
||||
stackvmProg.instr(opcodePushvar(varDt), callLabel = varname)
|
||||
stackvmProg.instr(opcodeSub(varDt))
|
||||
|
@ -21,22 +21,22 @@ abstract class Zeropage(private val options: CompilationOptions) {
|
||||
if(y==null) {
|
||||
// 1 dimensional array
|
||||
when(vardecl.datatype) {
|
||||
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!!
|
||||
DataType.WORD -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 2
|
||||
DataType.UBYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!!
|
||||
DataType.UWORD -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 2
|
||||
DataType.FLOAT -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 5
|
||||
else -> throw CompilerException("array can only be of byte, word, float")
|
||||
}
|
||||
} else {
|
||||
// 2 dimensional matrix (only bytes for now)
|
||||
when(vardecl.datatype) {
|
||||
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * y
|
||||
DataType.UBYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * y
|
||||
else -> throw CompilerException("matrix can only contain bytes")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
when (vardecl.datatype) {
|
||||
DataType.BYTE -> 1
|
||||
DataType.WORD -> 2
|
||||
DataType.UBYTE -> 1
|
||||
DataType.UWORD -> 2
|
||||
DataType.FLOAT -> {
|
||||
if (options.floats) {
|
||||
printWarning("allocating a large value (float) in zeropage", vardecl.position)
|
||||
|
@ -15,12 +15,12 @@ class FunctionSignature(val pure: Boolean, // does it have side effects?
|
||||
|
||||
|
||||
val BuiltinFunctions = mapOf(
|
||||
"rol" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"rol" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(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) },
|
||||
"cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(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) },
|
||||
@ -33,54 +33,59 @@ val BuiltinFunctions = mapOf(
|
||||
"sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(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) },
|
||||
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
||||
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), DataType.FLOAT, ::builtinAvg),
|
||||
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes.toList())), DataType.FLOAT, ::builtinAvg),
|
||||
"abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT, ::builtinAbs),
|
||||
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::round) }, // type depends on arg
|
||||
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // type depends on arg
|
||||
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // type depends on arg
|
||||
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
||||
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
||||
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
|
||||
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), null, ::builtinLen), // type depends on args
|
||||
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
||||
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX))), DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
||||
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
|
||||
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
|
||||
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE, DataType.WORD))), DataType.FLOAT, ::builtinFlt),
|
||||
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrd),
|
||||
"wrdhi" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrdHi),
|
||||
"rnd" to FunctionSignature(true, emptyList(), DataType.BYTE),
|
||||
"rndw" to FunctionSignature(true, emptyList(), DataType.WORD),
|
||||
"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
|
||||
"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
|
||||
"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
|
||||
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes.toList())), null, ::builtinLen), // type depends on args
|
||||
"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} }},
|
||||
"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} }},
|
||||
"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 }},
|
||||
"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}},
|
||||
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes.toList())), DataType.FLOAT, ::builtinFlt),
|
||||
"uwrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(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),
|
||||
"uwrdhi" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.UBYTE, DataType.BYTE))), DataType.UWORD, ::builtinWrdHi),
|
||||
"b2ub" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.UBYTE, ::builtinB2ub),
|
||||
"ub2b" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(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),
|
||||
"set_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))), DataType.BYTE),
|
||||
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))), DataType.WORD),
|
||||
"str2float" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))), DataType.FLOAT),
|
||||
"_vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.WORD))), null),
|
||||
"_vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.WORD))), null),
|
||||
"_vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", listOf(DataType.BYTE, DataType.WORD, DataType.FLOAT))), null),
|
||||
"_vm_write_char" to FunctionSignature(false, listOf(BuiltinFunctionParam("char", listOf(DataType.BYTE))), null),
|
||||
"_vm_write_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("string", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))), null),
|
||||
"_vm_input_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("intovar", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))), null),
|
||||
"_vm_gfx_clearscr" to FunctionSignature(false, listOf(BuiltinFunctionParam("color", listOf(DataType.BYTE))), null),
|
||||
"str2byte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.BYTE),
|
||||
"str2ubyte" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.UBYTE),
|
||||
"str2word" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.WORD),
|
||||
"str2uword" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.UWORD),
|
||||
"str2float" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), DataType.FLOAT),
|
||||
"_vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.UWORD))), null),
|
||||
"_vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", listOf(DataType.UWORD))), null),
|
||||
"_vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes.toList())), null),
|
||||
"_vm_write_char" to FunctionSignature(false, listOf(BuiltinFunctionParam("char", listOf(DataType.UBYTE))), null),
|
||||
"_vm_write_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("string", StringDatatypes.toList())), null),
|
||||
"_vm_input_str" to FunctionSignature(false, listOf(BuiltinFunctionParam("intovar", StringDatatypes.toList())), null),
|
||||
"_vm_gfx_clearscr" to FunctionSignature(false, listOf(BuiltinFunctionParam("color", listOf(DataType.UBYTE))), null),
|
||||
"_vm_gfx_pixel" to FunctionSignature(false, listOf(
|
||||
BuiltinFunctionParam("x", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("y", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("color", listOf(DataType.BYTE))), null),
|
||||
BuiltinFunctionParam("x", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("y", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("color", IntegerDatatypes.toList())), null),
|
||||
"_vm_gfx_line" to FunctionSignature(false, listOf(
|
||||
BuiltinFunctionParam("x1", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("y1", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("x2", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("y2", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("color", listOf(DataType.BYTE))), null),
|
||||
BuiltinFunctionParam("x1", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("y1", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("x2", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("y2", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("color", IntegerDatatypes.toList())), null),
|
||||
"_vm_gfx_text" to FunctionSignature(false, listOf(
|
||||
BuiltinFunctionParam("x", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("y", listOf(DataType.BYTE, DataType.WORD)),
|
||||
BuiltinFunctionParam("color", listOf(DataType.BYTE)),
|
||||
BuiltinFunctionParam("text", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))),
|
||||
BuiltinFunctionParam("x", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("y", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("color", IntegerDatatypes.toList()),
|
||||
BuiltinFunctionParam("text", StringDatatypes.toList())),
|
||||
null)
|
||||
)
|
||||
|
||||
@ -89,25 +94,28 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
|
||||
fun datatypeFromListArg(arglist: IExpression): DataType {
|
||||
if(arglist is LiteralValue) {
|
||||
if(arglist.type==DataType.ARRAY || arglist.type==DataType.ARRAY_W || arglist.type==DataType.ARRAY_F || arglist.type==DataType.MATRIX) {
|
||||
if(arglist.type==DataType.ARRAY_UB || arglist.type==DataType.ARRAY_UW || arglist.type==DataType.ARRAY_F || arglist.type==DataType.MATRIX_UB) {
|
||||
val dt = arglist.arrayvalue!!.map {it.resultingDatatype(namespace, heap)}
|
||||
if(dt.any { it!=DataType.BYTE && it!=DataType.WORD && it!=DataType.FLOAT}) {
|
||||
if(dt.any { it!=DataType.UBYTE && it!=DataType.UWORD && it!=DataType.FLOAT}) {
|
||||
throw FatalAstException("fuction $function only accepts array of numeric values")
|
||||
}
|
||||
if(dt.any { it==DataType.FLOAT }) return DataType.FLOAT
|
||||
if(dt.any { it==DataType.WORD }) return DataType.WORD
|
||||
return DataType.BYTE
|
||||
if(dt.any { it==DataType.UWORD }) return DataType.UWORD
|
||||
return DataType.UBYTE
|
||||
}
|
||||
}
|
||||
if(arglist is IdentifierReference) {
|
||||
val dt = arglist.resultingDatatype(namespace, heap)
|
||||
return when(dt) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT,
|
||||
DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT,
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> dt
|
||||
DataType.ARRAY -> DataType.BYTE
|
||||
DataType.ARRAY_UB -> DataType.UBYTE
|
||||
DataType.ARRAY_B -> DataType.BYTE
|
||||
DataType.ARRAY_UW -> DataType.UWORD
|
||||
DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_F -> DataType.FLOAT
|
||||
DataType.MATRIX -> DataType.BYTE
|
||||
DataType.MATRIX_UB -> DataType.UBYTE
|
||||
DataType.MATRIX_B -> DataType.BYTE
|
||||
null -> throw FatalAstException("function requires one argument which is an array $function")
|
||||
}
|
||||
}
|
||||
@ -123,18 +131,23 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
"max", "min" -> {
|
||||
val dt = datatypeFromListArg(args.single())
|
||||
when(dt) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> dt
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.BYTE
|
||||
DataType.ARRAY -> DataType.BYTE
|
||||
DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> dt
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.UBYTE
|
||||
DataType.ARRAY_UB -> DataType.UBYTE
|
||||
DataType.ARRAY_B -> DataType.BYTE
|
||||
DataType.ARRAY_UW -> DataType.UWORD
|
||||
DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_F -> DataType.FLOAT
|
||||
DataType.MATRIX -> DataType.BYTE
|
||||
DataType.MATRIX_UB -> DataType.UBYTE
|
||||
DataType.MATRIX_B -> DataType.BYTE
|
||||
}
|
||||
}
|
||||
"round", "floor", "ceil" -> {
|
||||
val dt=args.single().resultingDatatype(namespace, heap)
|
||||
when(dt) {
|
||||
DataType.UBYTE -> DataType.UBYTE
|
||||
DataType.BYTE -> DataType.BYTE
|
||||
DataType.UWORD -> DataType.UWORD
|
||||
DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.WORD
|
||||
else -> null
|
||||
@ -143,12 +156,15 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
"sum" -> {
|
||||
val dt=datatypeFromListArg(args.single())
|
||||
when(dt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
DataType.ARRAY, DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_UB, DataType.ARRAY_UW -> DataType.UWORD
|
||||
DataType.ARRAY_B, DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_F -> DataType.FLOAT
|
||||
DataType.MATRIX -> DataType.WORD
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.WORD
|
||||
DataType.MATRIX_UB -> DataType.UWORD
|
||||
DataType.MATRIX_B -> DataType.WORD
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.UWORD
|
||||
}
|
||||
}
|
||||
"len" -> {
|
||||
@ -162,14 +178,14 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
is VarDecl -> {
|
||||
val value = stmt.value
|
||||
if(value is LiteralValue) {
|
||||
if(value.isString) return DataType.BYTE // strings are 0..255
|
||||
if(value.isString) return DataType.UBYTE // strings are 0..255
|
||||
}
|
||||
}
|
||||
}
|
||||
DataType.WORD // assume other lengths are words for now.
|
||||
DataType.UWORD // assume other lengths are words for now.
|
||||
}
|
||||
is LiteralValue -> throw FatalAstException("len of literalvalue should have been const-folded away already")
|
||||
else -> DataType.WORD
|
||||
else -> DataType.UWORD
|
||||
}
|
||||
}
|
||||
else -> throw FatalAstException("unknown result type for builtin function $function")
|
||||
@ -196,7 +212,7 @@ private fun oneDoubleArgOutputInt(args: List<IExpression>, position: Position, n
|
||||
throw SyntaxError("built-in function requires one floating point argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
val float: Double = when(constval.type) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> constval.asNumericValue!!.toDouble()
|
||||
DataType.UBYTE, DataType.UWORD, DataType.FLOAT -> constval.asNumericValue!!.toDouble()
|
||||
else -> throw SyntaxError("built-in function requires one floating point argument", position)
|
||||
}
|
||||
return numericLiteral(function(float).toInt(), args[0].position)
|
||||
@ -206,7 +222,7 @@ private fun oneIntArgOutputInt(args: List<IExpression>, position: Position, name
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("built-in function requires one integer argument", position)
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE && constval.type!=DataType.WORD)
|
||||
if(constval.type!=DataType.UBYTE && constval.type!=DataType.UWORD)
|
||||
throw SyntaxError("built-in function requires one integer argument", position)
|
||||
|
||||
val integer = constval.asNumericValue?.toInt()!!
|
||||
@ -227,7 +243,7 @@ private fun collectionArgOutputNumber(args: List<IExpression>, position: Positio
|
||||
function(constants.map { it!!.toDouble() }).toDouble()
|
||||
} else {
|
||||
when(iterable.type) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> throw SyntaxError("function expects an iterable type", position)
|
||||
DataType.UBYTE, DataType.UWORD, DataType.FLOAT -> throw SyntaxError("function expects an iterable type", position)
|
||||
else -> {
|
||||
if(iterable.heapId==null)
|
||||
throw FatalAstException("iterable value should be on the heap")
|
||||
@ -274,20 +290,53 @@ private fun builtinWrd(args: List<IExpression>, position: Position, namespace:IN
|
||||
throw SyntaxError("wrd requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE)
|
||||
throw SyntaxError("wrd requires one byte argument", position)
|
||||
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.bytevalue!!.toInt(), 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.bytevalue!!.toInt(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinWrdHi(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to word (in hi byte)
|
||||
// 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.BYTE)
|
||||
if(constval.type!=DataType.UBYTE)
|
||||
throw SyntaxError("wrdhi requires one byte argument", position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = constval.bytevalue!!.toInt() shl 8, position = 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 {
|
||||
// 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)
|
||||
throw SyntaxError("b2ub requires one argument of type byte", position)
|
||||
return LiteralValue(DataType.UBYTE, bytevalue=constval.bytevalue!!, 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!!, position = position)
|
||||
}
|
||||
|
||||
private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
@ -333,7 +382,7 @@ private fun builtinLen(args: List<IExpression>, position: Position, namespace:IN
|
||||
?: throw SyntaxError("len over weird argument ${args[0]}", position)
|
||||
}
|
||||
return when(argument.type) {
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
val arraySize = argument.arrayvalue?.size ?: heap.get(argument.heapId!!).array!!.size
|
||||
numericLiteral(arraySize, args[0].position)
|
||||
}
|
||||
@ -345,8 +394,8 @@ private fun builtinLen(args: List<IExpression>, position: Position, namespace:IN
|
||||
val str = argument.strvalue ?: heap.get(argument.heapId!!).str!!
|
||||
numericLiteral(str.length, args[0].position)
|
||||
}
|
||||
DataType.BYTE,
|
||||
DataType.WORD,
|
||||
DataType.UBYTE, DataType.BYTE,
|
||||
DataType.UWORD, DataType.WORD,
|
||||
DataType.FLOAT -> throw SyntaxError("len of weird argument ${args[0]}", position)
|
||||
}
|
||||
}
|
||||
@ -362,7 +411,7 @@ private fun numericLiteral(value: Number, position: Position): LiteralValue {
|
||||
return when(tweakedValue) {
|
||||
is Int -> LiteralValue.optimalNumeric(value.toInt(), position)
|
||||
is Short -> LiteralValue.optimalNumeric(value.toInt(), position)
|
||||
is Byte -> LiteralValue(DataType.BYTE, bytevalue = value.toShort(), position = position)
|
||||
is Byte -> LiteralValue(DataType.UBYTE, bytevalue = value.toShort(), position = position)
|
||||
is Double -> LiteralValue(DataType.FLOAT, floatvalue = value.toDouble(), position = position)
|
||||
is Float -> LiteralValue(DataType.FLOAT, floatvalue = value.toDouble(), position = position)
|
||||
else -> throw FatalAstException("invalid number type ${value::class}")
|
||||
|
@ -86,39 +86,39 @@ class ConstExprEvaluator {
|
||||
}
|
||||
|
||||
private fun bitwisexor(left: LiteralValue, right: LiteralValue): LiteralValue {
|
||||
if(left.type== DataType.BYTE) {
|
||||
if(left.type== DataType.UBYTE) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (left.bytevalue!!.toInt() xor (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
return LiteralValue(DataType.UBYTE, bytevalue = (left.bytevalue!!.toInt() xor (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
}
|
||||
} else if(left.type== DataType.WORD) {
|
||||
} else if(left.type== DataType.UWORD) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.WORD, wordvalue = left.wordvalue!! xor right.asIntegerValue, position = left.position)
|
||||
return LiteralValue(DataType.UWORD, wordvalue = left.wordvalue!! xor right.asIntegerValue, position = left.position)
|
||||
}
|
||||
}
|
||||
throw ExpressionError("cannot calculate $left ^ $right", left.position)
|
||||
}
|
||||
|
||||
private fun bitwiseor(left: LiteralValue, right: LiteralValue): LiteralValue {
|
||||
if(left.type== DataType.BYTE) {
|
||||
if(left.type== DataType.UBYTE) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
return LiteralValue(DataType.UBYTE, bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
}
|
||||
} else if(left.type== DataType.WORD) {
|
||||
} else if(left.type== DataType.UWORD) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.WORD, wordvalue = left.wordvalue!! or right.asIntegerValue, position = left.position)
|
||||
return LiteralValue(DataType.UWORD, wordvalue = left.wordvalue!! or right.asIntegerValue, position = left.position)
|
||||
}
|
||||
}
|
||||
throw ExpressionError("cannot calculate $left | $right", left.position)
|
||||
}
|
||||
|
||||
private fun bitwiseand(left: LiteralValue, right: LiteralValue): LiteralValue {
|
||||
if(left.type== DataType.BYTE) {
|
||||
if(left.type== DataType.UBYTE) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.BYTE, bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
return LiteralValue(DataType.UBYTE, bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort(), position = left.position)
|
||||
}
|
||||
} else if(left.type== DataType.WORD) {
|
||||
} else if(left.type== DataType.UWORD) {
|
||||
if(right.asIntegerValue!=null) {
|
||||
return LiteralValue(DataType.WORD, wordvalue = left.wordvalue!! or right.asIntegerValue, position = left.position)
|
||||
return LiteralValue(DataType.UWORD, wordvalue = left.wordvalue!! or right.asIntegerValue, position = left.position)
|
||||
}
|
||||
}
|
||||
throw ExpressionError("cannot calculate $left & $right", left.position)
|
||||
|
@ -38,33 +38,33 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
DataType.FLOAT -> {
|
||||
// vardecl: for float vars, promote constant integer initialization values to floats
|
||||
val literal = decl.value as? LiteralValue
|
||||
if (literal != null && (literal.type == DataType.BYTE || literal.type==DataType.WORD)) {
|
||||
if (literal != null && literal.type in IntegerDatatypes) {
|
||||
val newValue = LiteralValue(DataType.FLOAT, floatvalue = literal.asNumericValue!!.toDouble(), position = literal.position)
|
||||
decl.value = newValue
|
||||
}
|
||||
}
|
||||
DataType.BYTE, DataType.WORD -> {
|
||||
in IntegerDatatypes -> {
|
||||
// vardecl: for byte/word vars, convert char/string of length 1 initialization values to integer
|
||||
val literal = decl.value as? LiteralValue
|
||||
if (literal != null && literal.isString && literal.strvalue?.length == 1) {
|
||||
val petscii = Petscii.encodePetscii(literal.strvalue)[0]
|
||||
val newValue = LiteralValue(DataType.BYTE, bytevalue = petscii, position = literal.position)
|
||||
val newValue = LiteralValue(DataType.UBYTE, bytevalue = petscii, position = literal.position)
|
||||
decl.value = newValue
|
||||
}
|
||||
}
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
val litval = decl.value as? LiteralValue
|
||||
val size = decl.arrayspec!!.size()
|
||||
if(litval!=null && litval.isArray) {
|
||||
// array initializer value is an array already, keep as-is (or convert to WORDs if needed)
|
||||
if(litval.heapId!=null) {
|
||||
if (decl.datatype == DataType.MATRIX && litval.type != DataType.MATRIX) {
|
||||
val array = heap.get(litval.heapId).copy(type = DataType.MATRIX)
|
||||
if (decl.datatype == DataType.MATRIX_UB && litval.type != DataType.MATRIX_UB) {
|
||||
val array = heap.get(litval.heapId).copy(type = DataType.MATRIX_UB)
|
||||
heap.update(litval.heapId, array)
|
||||
} else if(decl.datatype==DataType.ARRAY_W && litval.type == DataType.ARRAY) {
|
||||
} else if(decl.datatype==DataType.ARRAY_UW && litval.type == DataType.ARRAY_UB) {
|
||||
val array = heap.get(litval.heapId)
|
||||
if(array.array!=null) {
|
||||
heap.update(litval.heapId, HeapValues.HeapValue(DataType.ARRAY_W, null, array.array, null))
|
||||
heap.update(litval.heapId, HeapValues.HeapValue(DataType.ARRAY_UW, null, array.array, null))
|
||||
decl.value = LiteralValue(decl.datatype, heapId = litval.heapId, position = litval.position)
|
||||
}
|
||||
}
|
||||
@ -426,6 +426,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
return super.process(range)
|
||||
}
|
||||
|
||||
// todo datatypes
|
||||
override fun process(literalValue: LiteralValue): LiteralValue {
|
||||
if(literalValue.strvalue!=null) {
|
||||
// intern the string; move it into the heap
|
||||
@ -438,9 +439,9 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
}
|
||||
} else if(literalValue.arrayvalue!=null) {
|
||||
val newArray = literalValue.arrayvalue.map { it.process(this) }.toTypedArray()
|
||||
var arrayDt = DataType.ARRAY
|
||||
if(newArray.any { it.resultingDatatype(namespace, heap) == DataType.WORD })
|
||||
arrayDt = DataType.ARRAY_W
|
||||
var arrayDt = DataType.ARRAY_UB
|
||||
if(newArray.any { it.resultingDatatype(namespace, heap) == DataType.UWORD })
|
||||
arrayDt = DataType.ARRAY_UW
|
||||
if(newArray.any { it.resultingDatatype(namespace, heap) == DataType.FLOAT })
|
||||
arrayDt = DataType.ARRAY_F
|
||||
|
||||
@ -452,7 +453,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
addError(ExpressionError("array/matrix literal can contain only constant values", literalValue.position))
|
||||
return super.process(literalValue)
|
||||
}
|
||||
if(arrayDt==DataType.ARRAY || arrayDt==DataType.MATRIX) {
|
||||
if(arrayDt==DataType.ARRAY_UB || arrayDt==DataType.MATRIX_UB) {
|
||||
// all values should be bytes
|
||||
val integerArray = litArray.map { (it as LiteralValue).bytevalue }
|
||||
if(integerArray.any { it==null || it.toInt() !in 0..255 }) {
|
||||
@ -463,7 +464,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
val heapId = heap.add(arrayDt, array)
|
||||
val newValue = LiteralValue(arrayDt, heapId=heapId, position = literalValue.position)
|
||||
return super.process(newValue)
|
||||
} else if(arrayDt==DataType.ARRAY_W) {
|
||||
} else if(arrayDt==DataType.ARRAY_UW) {
|
||||
// all values should be bytes or words
|
||||
val integerArray = litArray.map { (it as LiteralValue).asIntegerValue }
|
||||
if(integerArray.any {it==null || it !in 0..65535 }) {
|
||||
@ -472,7 +473,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
}
|
||||
val array = integerArray.filterNotNull().toIntArray()
|
||||
val heapId = heap.add(arrayDt, array)
|
||||
val newValue = LiteralValue(DataType.ARRAY_W, heapId=heapId, position = literalValue.position)
|
||||
val newValue = LiteralValue(DataType.ARRAY_UW, heapId=heapId, position = literalValue.position)
|
||||
return super.process(newValue)
|
||||
} else if(arrayDt==DataType.ARRAY_F) {
|
||||
// all values should be bytes, words or floats
|
||||
@ -523,13 +524,13 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
val targetDt = assignment.target.determineDatatype(namespace, heap, assignment)
|
||||
// see if we can promote/convert a literal value to the required datatype
|
||||
when(targetDt) {
|
||||
DataType.WORD -> {
|
||||
if(lv.type==DataType.BYTE)
|
||||
assignment.value = LiteralValue(DataType.WORD, wordvalue = lv.asIntegerValue, position=lv.position)
|
||||
DataType.UWORD -> {
|
||||
if(lv.type==DataType.UBYTE)
|
||||
assignment.value = LiteralValue(DataType.UWORD, wordvalue = lv.asIntegerValue, position=lv.position)
|
||||
else if(lv.type==DataType.FLOAT) {
|
||||
val d = lv.floatvalue!!
|
||||
if(floor(d)==d && d in 0..65535) {
|
||||
assignment.value = LiteralValue(DataType.WORD, wordvalue=floor(d).toInt(), position=lv.position)
|
||||
assignment.value = LiteralValue(DataType.UWORD, wordvalue=floor(d).toInt(), position=lv.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -537,13 +538,13 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
if(lv.isNumeric)
|
||||
assignment.value = LiteralValue(DataType.FLOAT, floatvalue= lv.asNumericValue?.toDouble(), position=lv.position)
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
if(lv.type==DataType.WORD && lv.asIntegerValue in 0..255) {
|
||||
assignment.value = LiteralValue(DataType.BYTE, lv.asIntegerValue?.toShort(), position=lv.position)
|
||||
DataType.UBYTE -> {
|
||||
if(lv.type==DataType.UWORD && lv.asIntegerValue in 0..255) {
|
||||
assignment.value = LiteralValue(DataType.UBYTE, lv.asIntegerValue?.toShort(), position=lv.position)
|
||||
} else if(lv.type==DataType.FLOAT) {
|
||||
val d = lv.floatvalue!!
|
||||
if(floor(d)==d && d in 0..255) {
|
||||
assignment.value = LiteralValue(DataType.BYTE, floor(d).toShort(), position=lv.position)
|
||||
assignment.value = LiteralValue(DataType.UBYTE, floor(d).toShort(), position=lv.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,16 +284,16 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.left.resultingDatatype(namespace, heap) == DataType.BYTE) {
|
||||
if (expr.left.resultingDatatype(namespace, heap) == DataType.UBYTE) {
|
||||
if(abs(rightConst.asNumericValue!!.toDouble()) >= 256.0) {
|
||||
optimizationsDone++
|
||||
return LiteralValue(DataType.BYTE, 0, position = expr.position)
|
||||
return LiteralValue(DataType.UBYTE, 0, position = expr.position)
|
||||
}
|
||||
}
|
||||
else if (expr.left.resultingDatatype(namespace, heap) == DataType.WORD) {
|
||||
else if (expr.left.resultingDatatype(namespace, heap) == DataType.UWORD) {
|
||||
if(abs(rightConst.asNumericValue!!.toDouble()) >= 65536.0) {
|
||||
optimizationsDone++
|
||||
return LiteralValue(DataType.BYTE, 0, position = expr.position)
|
||||
return LiteralValue(DataType.UBYTE, 0, position = expr.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,10 @@ public class prog8Lexer extends Lexer {
|
||||
T__80=81, T__81=82, T__82=83, T__83=84, T__84=85, T__85=86, T__86=87,
|
||||
T__87=88, T__88=89, T__89=90, T__90=91, T__91=92, T__92=93, T__93=94,
|
||||
T__94=95, T__95=96, T__96=97, T__97=98, T__98=99, T__99=100, T__100=101,
|
||||
T__101=102, T__102=103, T__103=104, T__104=105, LINECOMMENT=106, COMMENT=107,
|
||||
WS=108, EOL=109, NAME=110, DEC_INTEGER=111, HEX_INTEGER=112, BIN_INTEGER=113,
|
||||
FLOAT_NUMBER=114, STRING=115, INLINEASMBLOCK=116, SINGLECHAR=117;
|
||||
T__101=102, T__102=103, T__103=104, T__104=105, T__105=106, T__106=107,
|
||||
LINECOMMENT=108, COMMENT=109, WS=110, EOL=111, NAME=112, DEC_INTEGER=113,
|
||||
HEX_INTEGER=114, BIN_INTEGER=115, FLOAT_NUMBER=116, STRING=117, INLINEASMBLOCK=118,
|
||||
SINGLECHAR=119;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
@ -56,26 +57,26 @@ public class prog8Lexer extends Lexer {
|
||||
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88",
|
||||
"T__89", "T__90", "T__91", "T__92", "T__93", "T__94", "T__95", "T__96",
|
||||
"T__97", "T__98", "T__99", "T__100", "T__101", "T__102", "T__103", "T__104",
|
||||
"LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER",
|
||||
"BIN_INTEGER", "FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING",
|
||||
"INLINEASMBLOCK", "SINGLECHAR"
|
||||
"T__105", "T__106", "LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER",
|
||||
"HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ",
|
||||
"STRING", "INLINEASMBLOCK", "SINGLECHAR"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'~'", "':'", "'goto'", "'%output'", "'%launcher'", "'%zeropage'",
|
||||
"'%zpreserved'", "'%address'", "'%import'", "'%breakpoint'", "'%asminclude'",
|
||||
"'%asmbinary'", "'%option'", "','", "'='", "'const'", "'memory'", "'byte'",
|
||||
"'word'", "'float'", "'str'", "'str_p'", "'str_s'", "'str_ps'", "'['",
|
||||
"']'", "'+='", "'-='", "'/='", "'//='", "'*='", "'**='", "'&='", "'|='",
|
||||
"'^='", "'++'", "'--'", "'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'",
|
||||
"'//'", "'%'", "'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "'&'", "'^'",
|
||||
"'|'", "'to'", "'step'", "'and'", "'or'", "'xor'", "'not'", "'return'",
|
||||
"'break'", "'continue'", "'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'",
|
||||
"'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'", "'true'", "'false'", "'%asm'",
|
||||
"'sub'", "'->'", "'{'", "'}'", "'asmsub'", "'clobbers'", "'@'", "'if'",
|
||||
"'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_ne'", "'if_nz'",
|
||||
"'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'", "'for'",
|
||||
"'in'", "'while'", "'repeat'", "'until'"
|
||||
"'%asmbinary'", "'%option'", "','", "'='", "'const'", "'memory'", "'ubyte'",
|
||||
"'byte'", "'uword'", "'word'", "'float'", "'str'", "'str_p'", "'str_s'",
|
||||
"'str_ps'", "'['", "']'", "'+='", "'-='", "'/='", "'//='", "'*='", "'**='",
|
||||
"'&='", "'|='", "'^='", "'++'", "'--'", "'('", "')'", "'+'", "'-'", "'**'",
|
||||
"'*'", "'/'", "'//'", "'%'", "'<'", "'>'", "'<='", "'>='", "'=='", "'!='",
|
||||
"'&'", "'^'", "'|'", "'to'", "'step'", "'and'", "'or'", "'xor'", "'not'",
|
||||
"'return'", "'break'", "'continue'", "'.'", "'A'", "'X'", "'Y'", "'AX'",
|
||||
"'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'", "'true'", "'false'",
|
||||
"'%asm'", "'sub'", "'->'", "'{'", "'}'", "'asmsub'", "'clobbers'", "'@'",
|
||||
"'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_ne'",
|
||||
"'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'",
|
||||
"'for'", "'in'", "'while'", "'repeat'", "'until'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
@ -86,9 +87,9 @@ public class prog8Lexer extends Lexer {
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, "LINECOMMENT",
|
||||
"COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER",
|
||||
"FLOAT_NUMBER", "STRING", "INLINEASMBLOCK", "SINGLECHAR"
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
"LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER",
|
||||
"BIN_INTEGER", "FLOAT_NUMBER", "STRING", "INLINEASMBLOCK", "SINGLECHAR"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
@ -150,13 +151,13 @@ public class prog8Lexer extends Lexer {
|
||||
@Override
|
||||
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
|
||||
switch (ruleIndex) {
|
||||
case 116:
|
||||
case 118:
|
||||
STRING_action((RuleContext)_localctx, actionIndex);
|
||||
break;
|
||||
case 117:
|
||||
case 119:
|
||||
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
|
||||
break;
|
||||
case 118:
|
||||
case 120:
|
||||
SINGLECHAR_action((RuleContext)_localctx, actionIndex);
|
||||
break;
|
||||
}
|
||||
@ -196,7 +197,7 @@ public class prog8Lexer extends Lexer {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2w\u0340\b\1\4\2\t"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2y\u0350\b\1\4\2\t"+
|
||||
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
|
||||
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
@ -209,50 +210,51 @@ public class prog8Lexer extends Lexer {
|
||||
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
|
||||
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
|
||||
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv\4"+
|
||||
"w\tw\4x\tx\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5"+
|
||||
"\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3"+
|
||||
"\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t"+
|
||||
"\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13"+
|
||||
"\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3"+
|
||||
"\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r"+
|
||||
"\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3"+
|
||||
"\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3"+
|
||||
"\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3"+
|
||||
"\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3"+
|
||||
"\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\33\3\33\3"+
|
||||
"\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 "+
|
||||
"\3 \3!\3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3"+
|
||||
"\'\3(\3(\3)\3)\3*\3*\3+\3+\3+\3,\3,\3-\3-\3.\3.\3.\3/\3/\3\60\3\60\3\61"+
|
||||
"\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66"+
|
||||
"\3\66\3\67\3\67\38\38\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3="+
|
||||
"\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3@\3A\3A\3A"+
|
||||
"\3A\3A\3A\3A\3A\3A\3B\3B\3C\3C\3D\3D\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H"+
|
||||
"\3I\3I\3I\3J\3J\3J\3K\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O"+
|
||||
"\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3S\3S\3T\3T\3U\3U\3U\3U"+
|
||||
"\3U\3U\3U\3V\3V\3V\3V\3V\3V\3V\3V\3V\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Z"+
|
||||
"\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]"+
|
||||
"\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3`\3a\3a\3a\3a"+
|
||||
"\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3e"+
|
||||
"\3e\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3h\3h\3h\3h\3h\3h\3i\3i\3i\3i\3i"+
|
||||
"\3i\3i\3j\3j\3j\3j\3j\3j\3k\3k\7k\u02cf\nk\fk\16k\u02d2\13k\3k\3k\3k\3"+
|
||||
"k\3l\3l\7l\u02da\nl\fl\16l\u02dd\13l\3l\3l\3m\3m\3m\3m\3n\6n\u02e6\nn"+
|
||||
"\rn\16n\u02e7\3o\3o\7o\u02ec\no\fo\16o\u02ef\13o\3p\3p\3p\6p\u02f4\np"+
|
||||
"\rp\16p\u02f5\5p\u02f8\np\3q\3q\6q\u02fc\nq\rq\16q\u02fd\3r\3r\6r\u0302"+
|
||||
"\nr\rr\16r\u0303\3s\3s\3s\5s\u0309\ns\3s\5s\u030c\ns\3t\6t\u030f\nt\r"+
|
||||
"t\16t\u0310\3t\3t\6t\u0315\nt\rt\16t\u0316\5t\u0319\nt\3u\3u\3u\3u\5u"+
|
||||
"\u031f\nu\3v\3v\3v\7v\u0324\nv\fv\16v\u0327\13v\3v\3v\3v\3w\3w\3w\3w\6"+
|
||||
"w\u0330\nw\rw\16w\u0331\3w\3w\3w\3w\3w\3x\3x\3x\5x\u033c\nx\3x\3x\3x\3"+
|
||||
"\u0331\2y\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
|
||||
"\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
|
||||
"\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65"+
|
||||
"i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008b"+
|
||||
"G\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009f"+
|
||||
"Q\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3"+
|
||||
"[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7"+
|
||||
"e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00db"+
|
||||
"o\u00ddp\u00dfq\u00e1r\u00e3s\u00e5t\u00e7\2\u00e9\2\u00ebu\u00edv\u00ef"+
|
||||
"w\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aac|\5\2\62;"+
|
||||
"CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u034f\2\3\3\2\2\2\2\5\3\2\2\2"+
|
||||
"w\tw\4x\tx\4y\ty\4z\tz\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5"+
|
||||
"\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3"+
|
||||
"\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b"+
|
||||
"\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3"+
|
||||
"\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f"+
|
||||
"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3"+
|
||||
"\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3"+
|
||||
"\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3"+
|
||||
"\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3"+
|
||||
"\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3"+
|
||||
"\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3"+
|
||||
"\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\35\3\35\3"+
|
||||
"\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3#\3#\3"+
|
||||
"#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3+\3"+
|
||||
"+\3,\3,\3-\3-\3-\3.\3.\3/\3/\3\60\3\60\3\60\3\61\3\61\3\62\3\62\3\63\3"+
|
||||
"\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\3\67\38\38"+
|
||||
"\39\39\3:\3:\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3?\3?\3?\3?"+
|
||||
"\3@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C"+
|
||||
"\3C\3C\3C\3D\3D\3E\3E\3F\3F\3G\3G\3H\3H\3H\3I\3I\3I\3J\3J\3J\3K\3K\3K"+
|
||||
"\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q"+
|
||||
"\3R\3R\3R\3R\3R\3S\3S\3S\3S\3T\3T\3T\3U\3U\3V\3V\3W\3W\3W\3W\3W\3W\3W"+
|
||||
"\3X\3X\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Z\3Z\3Z\3[\3[\3[\3[\3[\3\\\3\\\3\\"+
|
||||
"\3\\\3\\\3\\\3]\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3`\3`"+
|
||||
"\3`\3`\3`\3`\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c"+
|
||||
"\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g"+
|
||||
"\3g\3g\3h\3h\3h\3h\3i\3i\3i\3j\3j\3j\3j\3j\3j\3k\3k\3k\3k\3k\3k\3k\3l"+
|
||||
"\3l\3l\3l\3l\3l\3m\3m\7m\u02df\nm\fm\16m\u02e2\13m\3m\3m\3m\3m\3n\3n\7"+
|
||||
"n\u02ea\nn\fn\16n\u02ed\13n\3n\3n\3o\3o\3o\3o\3p\6p\u02f6\np\rp\16p\u02f7"+
|
||||
"\3q\3q\7q\u02fc\nq\fq\16q\u02ff\13q\3r\3r\3r\6r\u0304\nr\rr\16r\u0305"+
|
||||
"\5r\u0308\nr\3s\3s\6s\u030c\ns\rs\16s\u030d\3t\3t\6t\u0312\nt\rt\16t\u0313"+
|
||||
"\3u\3u\3u\5u\u0319\nu\3u\5u\u031c\nu\3v\6v\u031f\nv\rv\16v\u0320\3v\3"+
|
||||
"v\6v\u0325\nv\rv\16v\u0326\5v\u0329\nv\3w\3w\3w\3w\5w\u032f\nw\3x\3x\3"+
|
||||
"x\7x\u0334\nx\fx\16x\u0337\13x\3x\3x\3x\3y\3y\3y\3y\6y\u0340\ny\ry\16"+
|
||||
"y\u0341\3y\3y\3y\3y\3y\3z\3z\3z\5z\u034c\nz\3z\3z\3z\3\u0341\2{\3\3\5"+
|
||||
"\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21"+
|
||||
"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+
|
||||
"A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s"+
|
||||
";u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008f"+
|
||||
"I\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3"+
|
||||
"S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7"+
|
||||
"]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cb"+
|
||||
"g\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00ddp\u00df"+
|
||||
"q\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00eb\2\u00ed\2\u00efw\u00f1x\u00f3"+
|
||||
"y\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aac|\5\2\62;"+
|
||||
"CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u035f\2\3\3\2\2\2\2\5\3\2\2\2"+
|
||||
"\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3"+
|
||||
"\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2"+
|
||||
"\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2"+
|
||||
@ -274,204 +276,208 @@ public class prog8Lexer extends Lexer {
|
||||
"\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2"+
|
||||
"\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9"+
|
||||
"\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2"+
|
||||
"\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef"+
|
||||
"\3\2\2\2\3\u00f1\3\2\2\2\5\u00f3\3\2\2\2\7\u00f5\3\2\2\2\t\u00fa\3\2\2"+
|
||||
"\2\13\u0102\3\2\2\2\r\u010c\3\2\2\2\17\u0116\3\2\2\2\21\u0122\3\2\2\2"+
|
||||
"\23\u012b\3\2\2\2\25\u0133\3\2\2\2\27\u013f\3\2\2\2\31\u014b\3\2\2\2\33"+
|
||||
"\u0156\3\2\2\2\35\u015e\3\2\2\2\37\u0160\3\2\2\2!\u0162\3\2\2\2#\u0168"+
|
||||
"\3\2\2\2%\u016f\3\2\2\2\'\u0174\3\2\2\2)\u0179\3\2\2\2+\u017f\3\2\2\2"+
|
||||
"-\u0183\3\2\2\2/\u0189\3\2\2\2\61\u018f\3\2\2\2\63\u0196\3\2\2\2\65\u0198"+
|
||||
"\3\2\2\2\67\u019a\3\2\2\29\u019d\3\2\2\2;\u01a0\3\2\2\2=\u01a3\3\2\2\2"+
|
||||
"?\u01a7\3\2\2\2A\u01aa\3\2\2\2C\u01ae\3\2\2\2E\u01b1\3\2\2\2G\u01b4\3"+
|
||||
"\2\2\2I\u01b7\3\2\2\2K\u01ba\3\2\2\2M\u01bd\3\2\2\2O\u01bf\3\2\2\2Q\u01c1"+
|
||||
"\3\2\2\2S\u01c3\3\2\2\2U\u01c5\3\2\2\2W\u01c8\3\2\2\2Y\u01ca\3\2\2\2["+
|
||||
"\u01cc\3\2\2\2]\u01cf\3\2\2\2_\u01d1\3\2\2\2a\u01d3\3\2\2\2c\u01d5\3\2"+
|
||||
"\2\2e\u01d8\3\2\2\2g\u01db\3\2\2\2i\u01de\3\2\2\2k\u01e1\3\2\2\2m\u01e3"+
|
||||
"\3\2\2\2o\u01e5\3\2\2\2q\u01e7\3\2\2\2s\u01ea\3\2\2\2u\u01ef\3\2\2\2w"+
|
||||
"\u01f3\3\2\2\2y\u01f6\3\2\2\2{\u01fa\3\2\2\2}\u01fe\3\2\2\2\177\u0205"+
|
||||
"\3\2\2\2\u0081\u020b\3\2\2\2\u0083\u0214\3\2\2\2\u0085\u0216\3\2\2\2\u0087"+
|
||||
"\u0218\3\2\2\2\u0089\u021a\3\2\2\2\u008b\u021c\3\2\2\2\u008d\u021f\3\2"+
|
||||
"\2\2\u008f\u0222\3\2\2\2\u0091\u0225\3\2\2\2\u0093\u0228\3\2\2\2\u0095"+
|
||||
"\u022b\3\2\2\2\u0097\u022e\3\2\2\2\u0099\u0231\3\2\2\2\u009b\u0234\3\2"+
|
||||
"\2\2\u009d\u0239\3\2\2\2\u009f\u023f\3\2\2\2\u00a1\u0244\3\2\2\2\u00a3"+
|
||||
"\u0248\3\2\2\2\u00a5\u024b\3\2\2\2\u00a7\u024d\3\2\2\2\u00a9\u024f\3\2"+
|
||||
"\2\2\u00ab\u0256\3\2\2\2\u00ad\u025f\3\2\2\2\u00af\u0261\3\2\2\2\u00b1"+
|
||||
"\u0264\3\2\2\2\u00b3\u0269\3\2\2\2\u00b5\u026f\3\2\2\2\u00b7\u0275\3\2"+
|
||||
"\2\2\u00b9\u027b\3\2\2\2\u00bb\u0280\3\2\2\2\u00bd\u0286\3\2\2\2\u00bf"+
|
||||
"\u028c\3\2\2\2\u00c1\u0292\3\2\2\2\u00c3\u0299\3\2\2\2\u00c5\u029f\3\2"+
|
||||
"\2\2\u00c7\u02a6\3\2\2\2\u00c9\u02ac\3\2\2\2\u00cb\u02b2\3\2\2\2\u00cd"+
|
||||
"\u02b6\3\2\2\2\u00cf\u02b9\3\2\2\2\u00d1\u02bf\3\2\2\2\u00d3\u02c6\3\2"+
|
||||
"\2\2\u00d5\u02cc\3\2\2\2\u00d7\u02d7\3\2\2\2\u00d9\u02e0\3\2\2\2\u00db"+
|
||||
"\u02e5\3\2\2\2\u00dd\u02e9\3\2\2\2\u00df\u02f7\3\2\2\2\u00e1\u02f9\3\2"+
|
||||
"\2\2\u00e3\u02ff\3\2\2\2\u00e5\u0305\3\2\2\2\u00e7\u030e\3\2\2\2\u00e9"+
|
||||
"\u031e\3\2\2\2\u00eb\u0320\3\2\2\2\u00ed\u032b\3\2\2\2\u00ef\u0338\3\2"+
|
||||
"\2\2\u00f1\u00f2\7\u0080\2\2\u00f2\4\3\2\2\2\u00f3\u00f4\7<\2\2\u00f4"+
|
||||
"\6\3\2\2\2\u00f5\u00f6\7i\2\2\u00f6\u00f7\7q\2\2\u00f7\u00f8\7v\2\2\u00f8"+
|
||||
"\u00f9\7q\2\2\u00f9\b\3\2\2\2\u00fa\u00fb\7\'\2\2\u00fb\u00fc\7q\2\2\u00fc"+
|
||||
"\u00fd\7w\2\2\u00fd\u00fe\7v\2\2\u00fe\u00ff\7r\2\2\u00ff\u0100\7w\2\2"+
|
||||
"\u0100\u0101\7v\2\2\u0101\n\3\2\2\2\u0102\u0103\7\'\2\2\u0103\u0104\7"+
|
||||
"n\2\2\u0104\u0105\7c\2\2\u0105\u0106\7w\2\2\u0106\u0107\7p\2\2\u0107\u0108"+
|
||||
"\7e\2\2\u0108\u0109\7j\2\2\u0109\u010a\7g\2\2\u010a\u010b\7t\2\2\u010b"+
|
||||
"\f\3\2\2\2\u010c\u010d\7\'\2\2\u010d\u010e\7|\2\2\u010e\u010f\7g\2\2\u010f"+
|
||||
"\u0110\7t\2\2\u0110\u0111\7q\2\2\u0111\u0112\7r\2\2\u0112\u0113\7c\2\2"+
|
||||
"\u0113\u0114\7i\2\2\u0114\u0115\7g\2\2\u0115\16\3\2\2\2\u0116\u0117\7"+
|
||||
"\'\2\2\u0117\u0118\7|\2\2\u0118\u0119\7r\2\2\u0119\u011a\7t\2\2\u011a"+
|
||||
"\u011b\7g\2\2\u011b\u011c\7u\2\2\u011c\u011d\7g\2\2\u011d\u011e\7t\2\2"+
|
||||
"\u011e\u011f\7x\2\2\u011f\u0120\7g\2\2\u0120\u0121\7f\2\2\u0121\20\3\2"+
|
||||
"\2\2\u0122\u0123\7\'\2\2\u0123\u0124\7c\2\2\u0124\u0125\7f\2\2\u0125\u0126"+
|
||||
"\7f\2\2\u0126\u0127\7t\2\2\u0127\u0128\7g\2\2\u0128\u0129\7u\2\2\u0129"+
|
||||
"\u012a\7u\2\2\u012a\22\3\2\2\2\u012b\u012c\7\'\2\2\u012c\u012d\7k\2\2"+
|
||||
"\u012d\u012e\7o\2\2\u012e\u012f\7r\2\2\u012f\u0130\7q\2\2\u0130\u0131"+
|
||||
"\7t\2\2\u0131\u0132\7v\2\2\u0132\24\3\2\2\2\u0133\u0134\7\'\2\2\u0134"+
|
||||
"\u0135\7d\2\2\u0135\u0136\7t\2\2\u0136\u0137\7g\2\2\u0137\u0138\7c\2\2"+
|
||||
"\u0138\u0139\7m\2\2\u0139\u013a\7r\2\2\u013a\u013b\7q\2\2\u013b\u013c"+
|
||||
"\7k\2\2\u013c\u013d\7p\2\2\u013d\u013e\7v\2\2\u013e\26\3\2\2\2\u013f\u0140"+
|
||||
"\7\'\2\2\u0140\u0141\7c\2\2\u0141\u0142\7u\2\2\u0142\u0143\7o\2\2\u0143"+
|
||||
"\u0144\7k\2\2\u0144\u0145\7p\2\2\u0145\u0146\7e\2\2\u0146\u0147\7n\2\2"+
|
||||
"\u0147\u0148\7w\2\2\u0148\u0149\7f\2\2\u0149\u014a\7g\2\2\u014a\30\3\2"+
|
||||
"\2\2\u014b\u014c\7\'\2\2\u014c\u014d\7c\2\2\u014d\u014e\7u\2\2\u014e\u014f"+
|
||||
"\7o\2\2\u014f\u0150\7d\2\2\u0150\u0151\7k\2\2\u0151\u0152\7p\2\2\u0152"+
|
||||
"\u0153\7c\2\2\u0153\u0154\7t\2\2\u0154\u0155\7{\2\2\u0155\32\3\2\2\2\u0156"+
|
||||
"\u0157\7\'\2\2\u0157\u0158\7q\2\2\u0158\u0159\7r\2\2\u0159\u015a\7v\2"+
|
||||
"\2\u015a\u015b\7k\2\2\u015b\u015c\7q\2\2\u015c\u015d\7p\2\2\u015d\34\3"+
|
||||
"\2\2\2\u015e\u015f\7.\2\2\u015f\36\3\2\2\2\u0160\u0161\7?\2\2\u0161 \3"+
|
||||
"\2\2\2\u0162\u0163\7e\2\2\u0163\u0164\7q\2\2\u0164\u0165\7p\2\2\u0165"+
|
||||
"\u0166\7u\2\2\u0166\u0167\7v\2\2\u0167\"\3\2\2\2\u0168\u0169\7o\2\2\u0169"+
|
||||
"\u016a\7g\2\2\u016a\u016b\7o\2\2\u016b\u016c\7q\2\2\u016c\u016d\7t\2\2"+
|
||||
"\u016d\u016e\7{\2\2\u016e$\3\2\2\2\u016f\u0170\7d\2\2\u0170\u0171\7{\2"+
|
||||
"\2\u0171\u0172\7v\2\2\u0172\u0173\7g\2\2\u0173&\3\2\2\2\u0174\u0175\7"+
|
||||
"y\2\2\u0175\u0176\7q\2\2\u0176\u0177\7t\2\2\u0177\u0178\7f\2\2\u0178("+
|
||||
"\3\2\2\2\u0179\u017a\7h\2\2\u017a\u017b\7n\2\2\u017b\u017c\7q\2\2\u017c"+
|
||||
"\u017d\7c\2\2\u017d\u017e\7v\2\2\u017e*\3\2\2\2\u017f\u0180\7u\2\2\u0180"+
|
||||
"\u0181\7v\2\2\u0181\u0182\7t\2\2\u0182,\3\2\2\2\u0183\u0184\7u\2\2\u0184"+
|
||||
"\u0185\7v\2\2\u0185\u0186\7t\2\2\u0186\u0187\7a\2\2\u0187\u0188\7r\2\2"+
|
||||
"\u0188.\3\2\2\2\u0189\u018a\7u\2\2\u018a\u018b\7v\2\2\u018b\u018c\7t\2"+
|
||||
"\2\u018c\u018d\7a\2\2\u018d\u018e\7u\2\2\u018e\60\3\2\2\2\u018f\u0190"+
|
||||
"\7u\2\2\u0190\u0191\7v\2\2\u0191\u0192\7t\2\2\u0192\u0193\7a\2\2\u0193"+
|
||||
"\u0194\7r\2\2\u0194\u0195\7u\2\2\u0195\62\3\2\2\2\u0196\u0197\7]\2\2\u0197"+
|
||||
"\64\3\2\2\2\u0198\u0199\7_\2\2\u0199\66\3\2\2\2\u019a\u019b\7-\2\2\u019b"+
|
||||
"\u019c\7?\2\2\u019c8\3\2\2\2\u019d\u019e\7/\2\2\u019e\u019f\7?\2\2\u019f"+
|
||||
":\3\2\2\2\u01a0\u01a1\7\61\2\2\u01a1\u01a2\7?\2\2\u01a2<\3\2\2\2\u01a3"+
|
||||
"\u01a4\7\61\2\2\u01a4\u01a5\7\61\2\2\u01a5\u01a6\7?\2\2\u01a6>\3\2\2\2"+
|
||||
"\u01a7\u01a8\7,\2\2\u01a8\u01a9\7?\2\2\u01a9@\3\2\2\2\u01aa\u01ab\7,\2"+
|
||||
"\2\u01ab\u01ac\7,\2\2\u01ac\u01ad\7?\2\2\u01adB\3\2\2\2\u01ae\u01af\7"+
|
||||
"(\2\2\u01af\u01b0\7?\2\2\u01b0D\3\2\2\2\u01b1\u01b2\7~\2\2\u01b2\u01b3"+
|
||||
"\7?\2\2\u01b3F\3\2\2\2\u01b4\u01b5\7`\2\2\u01b5\u01b6\7?\2\2\u01b6H\3"+
|
||||
"\2\2\2\u01b7\u01b8\7-\2\2\u01b8\u01b9\7-\2\2\u01b9J\3\2\2\2\u01ba\u01bb"+
|
||||
"\7/\2\2\u01bb\u01bc\7/\2\2\u01bcL\3\2\2\2\u01bd\u01be\7*\2\2\u01beN\3"+
|
||||
"\2\2\2\u01bf\u01c0\7+\2\2\u01c0P\3\2\2\2\u01c1\u01c2\7-\2\2\u01c2R\3\2"+
|
||||
"\2\2\u01c3\u01c4\7/\2\2\u01c4T\3\2\2\2\u01c5\u01c6\7,\2\2\u01c6\u01c7"+
|
||||
"\7,\2\2\u01c7V\3\2\2\2\u01c8\u01c9\7,\2\2\u01c9X\3\2\2\2\u01ca\u01cb\7"+
|
||||
"\61\2\2\u01cbZ\3\2\2\2\u01cc\u01cd\7\61\2\2\u01cd\u01ce\7\61\2\2\u01ce"+
|
||||
"\\\3\2\2\2\u01cf\u01d0\7\'\2\2\u01d0^\3\2\2\2\u01d1\u01d2\7>\2\2\u01d2"+
|
||||
"`\3\2\2\2\u01d3\u01d4\7@\2\2\u01d4b\3\2\2\2\u01d5\u01d6\7>\2\2\u01d6\u01d7"+
|
||||
"\7?\2\2\u01d7d\3\2\2\2\u01d8\u01d9\7@\2\2\u01d9\u01da\7?\2\2\u01daf\3"+
|
||||
"\2\2\2\u01db\u01dc\7?\2\2\u01dc\u01dd\7?\2\2\u01ddh\3\2\2\2\u01de\u01df"+
|
||||
"\7#\2\2\u01df\u01e0\7?\2\2\u01e0j\3\2\2\2\u01e1\u01e2\7(\2\2\u01e2l\3"+
|
||||
"\2\2\2\u01e3\u01e4\7`\2\2\u01e4n\3\2\2\2\u01e5\u01e6\7~\2\2\u01e6p\3\2"+
|
||||
"\2\2\u01e7\u01e8\7v\2\2\u01e8\u01e9\7q\2\2\u01e9r\3\2\2\2\u01ea\u01eb"+
|
||||
"\7u\2\2\u01eb\u01ec\7v\2\2\u01ec\u01ed\7g\2\2\u01ed\u01ee\7r\2\2\u01ee"+
|
||||
"t\3\2\2\2\u01ef\u01f0\7c\2\2\u01f0\u01f1\7p\2\2\u01f1\u01f2\7f\2\2\u01f2"+
|
||||
"v\3\2\2\2\u01f3\u01f4\7q\2\2\u01f4\u01f5\7t\2\2\u01f5x\3\2\2\2\u01f6\u01f7"+
|
||||
"\7z\2\2\u01f7\u01f8\7q\2\2\u01f8\u01f9\7t\2\2\u01f9z\3\2\2\2\u01fa\u01fb"+
|
||||
"\7p\2\2\u01fb\u01fc\7q\2\2\u01fc\u01fd\7v\2\2\u01fd|\3\2\2\2\u01fe\u01ff"+
|
||||
"\7t\2\2\u01ff\u0200\7g\2\2\u0200\u0201\7v\2\2\u0201\u0202\7w\2\2\u0202"+
|
||||
"\u0203\7t\2\2\u0203\u0204\7p\2\2\u0204~\3\2\2\2\u0205\u0206\7d\2\2\u0206"+
|
||||
"\u0207\7t\2\2\u0207\u0208\7g\2\2\u0208\u0209\7c\2\2\u0209\u020a\7m\2\2"+
|
||||
"\u020a\u0080\3\2\2\2\u020b\u020c\7e\2\2\u020c\u020d\7q\2\2\u020d\u020e"+
|
||||
"\7p\2\2\u020e\u020f\7v\2\2\u020f\u0210\7k\2\2\u0210\u0211\7p\2\2\u0211"+
|
||||
"\u0212\7w\2\2\u0212\u0213\7g\2\2\u0213\u0082\3\2\2\2\u0214\u0215\7\60"+
|
||||
"\2\2\u0215\u0084\3\2\2\2\u0216\u0217\7C\2\2\u0217\u0086\3\2\2\2\u0218"+
|
||||
"\u0219\7Z\2\2\u0219\u0088\3\2\2\2\u021a\u021b\7[\2\2\u021b\u008a\3\2\2"+
|
||||
"\2\u021c\u021d\7C\2\2\u021d\u021e\7Z\2\2\u021e\u008c\3\2\2\2\u021f\u0220"+
|
||||
"\7C\2\2\u0220\u0221\7[\2\2\u0221\u008e\3\2\2\2\u0222\u0223\7Z\2\2\u0223"+
|
||||
"\u0224\7[\2\2\u0224\u0090\3\2\2\2\u0225\u0226\7R\2\2\u0226\u0227\7e\2"+
|
||||
"\2\u0227\u0092\3\2\2\2\u0228\u0229\7R\2\2\u0229\u022a\7|\2\2\u022a\u0094"+
|
||||
"\3\2\2\2\u022b\u022c\7R\2\2\u022c\u022d\7p\2\2\u022d\u0096\3\2\2\2\u022e"+
|
||||
"\u022f\7R\2\2\u022f\u0230\7x\2\2\u0230\u0098\3\2\2\2\u0231\u0232\7\60"+
|
||||
"\2\2\u0232\u0233\7y\2\2\u0233\u009a\3\2\2\2\u0234\u0235\7v\2\2\u0235\u0236"+
|
||||
"\7t\2\2\u0236\u0237\7w\2\2\u0237\u0238\7g\2\2\u0238\u009c\3\2\2\2\u0239"+
|
||||
"\u023a\7h\2\2\u023a\u023b\7c\2\2\u023b\u023c\7n\2\2\u023c\u023d\7u\2\2"+
|
||||
"\u023d\u023e\7g\2\2\u023e\u009e\3\2\2\2\u023f\u0240\7\'\2\2\u0240\u0241"+
|
||||
"\7c\2\2\u0241\u0242\7u\2\2\u0242\u0243\7o\2\2\u0243\u00a0\3\2\2\2\u0244"+
|
||||
"\u0245\7u\2\2\u0245\u0246\7w\2\2\u0246\u0247\7d\2\2\u0247\u00a2\3\2\2"+
|
||||
"\2\u0248\u0249\7/\2\2\u0249\u024a\7@\2\2\u024a\u00a4\3\2\2\2\u024b\u024c"+
|
||||
"\7}\2\2\u024c\u00a6\3\2\2\2\u024d\u024e\7\177\2\2\u024e\u00a8\3\2\2\2"+
|
||||
"\u024f\u0250\7c\2\2\u0250\u0251\7u\2\2\u0251\u0252\7o\2\2\u0252\u0253"+
|
||||
"\7u\2\2\u0253\u0254\7w\2\2\u0254\u0255\7d\2\2\u0255\u00aa\3\2\2\2\u0256"+
|
||||
"\u0257\7e\2\2\u0257\u0258\7n\2\2\u0258\u0259\7q\2\2\u0259\u025a\7d\2\2"+
|
||||
"\u025a\u025b\7d\2\2\u025b\u025c\7g\2\2\u025c\u025d\7t\2\2\u025d\u025e"+
|
||||
"\7u\2\2\u025e\u00ac\3\2\2\2\u025f\u0260\7B\2\2\u0260\u00ae\3\2\2\2\u0261"+
|
||||
"\u0262\7k\2\2\u0262\u0263\7h\2\2\u0263\u00b0\3\2\2\2\u0264\u0265\7g\2"+
|
||||
"\2\u0265\u0266\7n\2\2\u0266\u0267\7u\2\2\u0267\u0268\7g\2\2\u0268\u00b2"+
|
||||
"\3\2\2\2\u0269\u026a\7k\2\2\u026a\u026b\7h\2\2\u026b\u026c\7a\2\2\u026c"+
|
||||
"\u026d\7e\2\2\u026d\u026e\7u\2\2\u026e\u00b4\3\2\2\2\u026f\u0270\7k\2"+
|
||||
"\2\u0270\u0271\7h\2\2\u0271\u0272\7a\2\2\u0272\u0273\7e\2\2\u0273\u0274"+
|
||||
"\7e\2\2\u0274\u00b6\3\2\2\2\u0275\u0276\7k\2\2\u0276\u0277\7h\2\2\u0277"+
|
||||
"\u0278\7a\2\2\u0278\u0279\7g\2\2\u0279\u027a\7s\2\2\u027a\u00b8\3\2\2"+
|
||||
"\2\u027b\u027c\7k\2\2\u027c\u027d\7h\2\2\u027d\u027e\7a\2\2\u027e\u027f"+
|
||||
"\7|\2\2\u027f\u00ba\3\2\2\2\u0280\u0281\7k\2\2\u0281\u0282\7h\2\2\u0282"+
|
||||
"\u0283\7a\2\2\u0283\u0284\7p\2\2\u0284\u0285\7g\2\2\u0285\u00bc\3\2\2"+
|
||||
"\2\u0286\u0287\7k\2\2\u0287\u0288\7h\2\2\u0288\u0289\7a\2\2\u0289\u028a"+
|
||||
"\7p\2\2\u028a\u028b\7|\2\2\u028b\u00be\3\2\2\2\u028c\u028d\7k\2\2\u028d"+
|
||||
"\u028e\7h\2\2\u028e\u028f\7a\2\2\u028f\u0290\7r\2\2\u0290\u0291\7n\2\2"+
|
||||
"\u0291\u00c0\3\2\2\2\u0292\u0293\7k\2\2\u0293\u0294\7h\2\2\u0294\u0295"+
|
||||
"\7a\2\2\u0295\u0296\7r\2\2\u0296\u0297\7q\2\2\u0297\u0298\7u\2\2\u0298"+
|
||||
"\u00c2\3\2\2\2\u0299\u029a\7k\2\2\u029a\u029b\7h\2\2\u029b\u029c\7a\2"+
|
||||
"\2\u029c\u029d\7o\2\2\u029d\u029e\7k\2\2\u029e\u00c4\3\2\2\2\u029f\u02a0"+
|
||||
"\7k\2\2\u02a0\u02a1\7h\2\2\u02a1\u02a2\7a\2\2\u02a2\u02a3\7p\2\2\u02a3"+
|
||||
"\u02a4\7g\2\2\u02a4\u02a5\7i\2\2\u02a5\u00c6\3\2\2\2\u02a6\u02a7\7k\2"+
|
||||
"\2\u02a7\u02a8\7h\2\2\u02a8\u02a9\7a\2\2\u02a9\u02aa\7x\2\2\u02aa\u02ab"+
|
||||
"\7u\2\2\u02ab\u00c8\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae"+
|
||||
"\u02af\7a\2\2\u02af\u02b0\7x\2\2\u02b0\u02b1\7e\2\2\u02b1\u00ca\3\2\2"+
|
||||
"\2\u02b2\u02b3\7h\2\2\u02b3\u02b4\7q\2\2\u02b4\u02b5\7t\2\2\u02b5\u00cc"+
|
||||
"\3\2\2\2\u02b6\u02b7\7k\2\2\u02b7\u02b8\7p\2\2\u02b8\u00ce\3\2\2\2\u02b9"+
|
||||
"\u02ba\7y\2\2\u02ba\u02bb\7j\2\2\u02bb\u02bc\7k\2\2\u02bc\u02bd\7n\2\2"+
|
||||
"\u02bd\u02be\7g\2\2\u02be\u00d0\3\2\2\2\u02bf\u02c0\7t\2\2\u02c0\u02c1"+
|
||||
"\7g\2\2\u02c1\u02c2\7r\2\2\u02c2\u02c3\7g\2\2\u02c3\u02c4\7c\2\2\u02c4"+
|
||||
"\u02c5\7v\2\2\u02c5\u00d2\3\2\2\2\u02c6\u02c7\7w\2\2\u02c7\u02c8\7p\2"+
|
||||
"\2\u02c8\u02c9\7v\2\2\u02c9\u02ca\7k\2\2\u02ca\u02cb\7n\2\2\u02cb\u00d4"+
|
||||
"\3\2\2\2\u02cc\u02d0\t\2\2\2\u02cd\u02cf\t\3\2\2\u02ce\u02cd\3\2\2\2\u02cf"+
|
||||
"\u02d2\3\2\2\2\u02d0\u02ce\3\2\2\2\u02d0\u02d1\3\2\2\2\u02d1\u02d3\3\2"+
|
||||
"\2\2\u02d2\u02d0\3\2\2\2\u02d3\u02d4\5\u00d7l\2\u02d4\u02d5\3\2\2\2\u02d5"+
|
||||
"\u02d6\bk\2\2\u02d6\u00d6\3\2\2\2\u02d7\u02db\7=\2\2\u02d8\u02da\n\2\2"+
|
||||
"\2\u02d9\u02d8\3\2\2\2\u02da\u02dd\3\2\2\2\u02db\u02d9\3\2\2\2\u02db\u02dc"+
|
||||
"\3\2\2\2\u02dc\u02de\3\2\2\2\u02dd\u02db\3\2\2\2\u02de\u02df\bl\2\2\u02df"+
|
||||
"\u00d8\3\2\2\2\u02e0\u02e1\t\3\2\2\u02e1\u02e2\3\2\2\2\u02e2\u02e3\bm"+
|
||||
"\3\2\u02e3\u00da\3\2\2\2\u02e4\u02e6\t\2\2\2\u02e5\u02e4\3\2\2\2\u02e6"+
|
||||
"\u02e7\3\2\2\2\u02e7\u02e5\3\2\2\2\u02e7\u02e8\3\2\2\2\u02e8\u00dc\3\2"+
|
||||
"\2\2\u02e9\u02ed\t\4\2\2\u02ea\u02ec\t\5\2\2\u02eb\u02ea\3\2\2\2\u02ec"+
|
||||
"\u02ef\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ed\u02ee\3\2\2\2\u02ee\u00de\3\2"+
|
||||
"\2\2\u02ef\u02ed\3\2\2\2\u02f0\u02f8\4\62;\2\u02f1\u02f3\4\63;\2\u02f2"+
|
||||
"\u02f4\4\62;\2\u02f3\u02f2\3\2\2\2\u02f4\u02f5\3\2\2\2\u02f5\u02f3\3\2"+
|
||||
"\2\2\u02f5\u02f6\3\2\2\2\u02f6\u02f8\3\2\2\2\u02f7\u02f0\3\2\2\2\u02f7"+
|
||||
"\u02f1\3\2\2\2\u02f8\u00e0\3\2\2\2\u02f9\u02fb\7&\2\2\u02fa\u02fc\t\6"+
|
||||
"\2\2\u02fb\u02fa\3\2\2\2\u02fc\u02fd\3\2\2\2\u02fd\u02fb\3\2\2\2\u02fd"+
|
||||
"\u02fe\3\2\2\2\u02fe\u00e2\3\2\2\2\u02ff\u0301\7\'\2\2\u0300\u0302\4\62"+
|
||||
"\63\2\u0301\u0300\3\2\2\2\u0302\u0303\3\2\2\2\u0303\u0301\3\2\2\2\u0303"+
|
||||
"\u0304\3\2\2\2\u0304\u00e4\3\2\2\2\u0305\u030b\5\u00e7t\2\u0306\u0308"+
|
||||
"\t\7\2\2\u0307\u0309\t\b\2\2\u0308\u0307\3\2\2\2\u0308\u0309\3\2\2\2\u0309"+
|
||||
"\u030a\3\2\2\2\u030a\u030c\5\u00e7t\2\u030b\u0306\3\2\2\2\u030b\u030c"+
|
||||
"\3\2\2\2\u030c\u00e6\3\2\2\2\u030d\u030f\4\62;\2\u030e\u030d\3\2\2\2\u030f"+
|
||||
"\u0310\3\2\2\2\u0310\u030e\3\2\2\2\u0310\u0311\3\2\2\2\u0311\u0318\3\2"+
|
||||
"\2\2\u0312\u0314\7\60\2\2\u0313\u0315\4\62;\2\u0314\u0313\3\2\2\2\u0315"+
|
||||
"\u0316\3\2\2\2\u0316\u0314\3\2\2\2\u0316\u0317\3\2\2\2\u0317\u0319\3\2"+
|
||||
"\2\2\u0318\u0312\3\2\2\2\u0318\u0319\3\2\2\2\u0319\u00e8\3\2\2\2\u031a"+
|
||||
"\u031b\7^\2\2\u031b\u031f\13\2\2\2\u031c\u031d\7^\2\2\u031d\u031f\5\u00db"+
|
||||
"n\2\u031e\u031a\3\2\2\2\u031e\u031c\3\2\2\2\u031f\u00ea\3\2\2\2\u0320"+
|
||||
"\u0325\7$\2\2\u0321\u0324\5\u00e9u\2\u0322\u0324\n\t\2\2\u0323\u0321\3"+
|
||||
"\2\2\2\u0323\u0322\3\2\2\2\u0324\u0327\3\2\2\2\u0325\u0323\3\2\2\2\u0325"+
|
||||
"\u0326\3\2\2\2\u0326\u0328\3\2\2\2\u0327\u0325\3\2\2\2\u0328\u0329\7$"+
|
||||
"\2\2\u0329\u032a\bv\4\2\u032a\u00ec\3\2\2\2\u032b\u032c\7}\2\2\u032c\u032d"+
|
||||
"\7}\2\2\u032d\u032f\3\2\2\2\u032e\u0330\13\2\2\2\u032f\u032e\3\2\2\2\u0330"+
|
||||
"\u0331\3\2\2\2\u0331\u0332\3\2\2\2\u0331\u032f\3\2\2\2\u0332\u0333\3\2"+
|
||||
"\2\2\u0333\u0334\7\177\2\2\u0334\u0335\7\177\2\2\u0335\u0336\3\2\2\2\u0336"+
|
||||
"\u0337\bw\5\2\u0337\u00ee\3\2\2\2\u0338\u033b\7)\2\2\u0339\u033c\5\u00e9"+
|
||||
"u\2\u033a\u033c\n\t\2\2\u033b\u0339\3\2\2\2\u033b\u033a\3\2\2\2\u033c"+
|
||||
"\u033d\3\2\2\2\u033d\u033e\7)\2\2\u033e\u033f\bx\6\2\u033f\u00f0\3\2\2"+
|
||||
"\2\26\2\u02d0\u02db\u02e7\u02ed\u02f5\u02f7\u02fb\u02fd\u0303\u0308\u030b"+
|
||||
"\u0310\u0316\u0318\u031e\u0323\u0325\u0331\u033b\7\2\3\2\b\2\2\3v\2\3"+
|
||||
"w\3\3x\4";
|
||||
"\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00ef"+
|
||||
"\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\3\u00f5\3\2\2\2\5\u00f7\3\2\2"+
|
||||
"\2\7\u00f9\3\2\2\2\t\u00fe\3\2\2\2\13\u0106\3\2\2\2\r\u0110\3\2\2\2\17"+
|
||||
"\u011a\3\2\2\2\21\u0126\3\2\2\2\23\u012f\3\2\2\2\25\u0137\3\2\2\2\27\u0143"+
|
||||
"\3\2\2\2\31\u014f\3\2\2\2\33\u015a\3\2\2\2\35\u0162\3\2\2\2\37\u0164\3"+
|
||||
"\2\2\2!\u0166\3\2\2\2#\u016c\3\2\2\2%\u0173\3\2\2\2\'\u0179\3\2\2\2)\u017e"+
|
||||
"\3\2\2\2+\u0184\3\2\2\2-\u0189\3\2\2\2/\u018f\3\2\2\2\61\u0193\3\2\2\2"+
|
||||
"\63\u0199\3\2\2\2\65\u019f\3\2\2\2\67\u01a6\3\2\2\29\u01a8\3\2\2\2;\u01aa"+
|
||||
"\3\2\2\2=\u01ad\3\2\2\2?\u01b0\3\2\2\2A\u01b3\3\2\2\2C\u01b7\3\2\2\2E"+
|
||||
"\u01ba\3\2\2\2G\u01be\3\2\2\2I\u01c1\3\2\2\2K\u01c4\3\2\2\2M\u01c7\3\2"+
|
||||
"\2\2O\u01ca\3\2\2\2Q\u01cd\3\2\2\2S\u01cf\3\2\2\2U\u01d1\3\2\2\2W\u01d3"+
|
||||
"\3\2\2\2Y\u01d5\3\2\2\2[\u01d8\3\2\2\2]\u01da\3\2\2\2_\u01dc\3\2\2\2a"+
|
||||
"\u01df\3\2\2\2c\u01e1\3\2\2\2e\u01e3\3\2\2\2g\u01e5\3\2\2\2i\u01e8\3\2"+
|
||||
"\2\2k\u01eb\3\2\2\2m\u01ee\3\2\2\2o\u01f1\3\2\2\2q\u01f3\3\2\2\2s\u01f5"+
|
||||
"\3\2\2\2u\u01f7\3\2\2\2w\u01fa\3\2\2\2y\u01ff\3\2\2\2{\u0203\3\2\2\2}"+
|
||||
"\u0206\3\2\2\2\177\u020a\3\2\2\2\u0081\u020e\3\2\2\2\u0083\u0215\3\2\2"+
|
||||
"\2\u0085\u021b\3\2\2\2\u0087\u0224\3\2\2\2\u0089\u0226\3\2\2\2\u008b\u0228"+
|
||||
"\3\2\2\2\u008d\u022a\3\2\2\2\u008f\u022c\3\2\2\2\u0091\u022f\3\2\2\2\u0093"+
|
||||
"\u0232\3\2\2\2\u0095\u0235\3\2\2\2\u0097\u0238\3\2\2\2\u0099\u023b\3\2"+
|
||||
"\2\2\u009b\u023e\3\2\2\2\u009d\u0241\3\2\2\2\u009f\u0244\3\2\2\2\u00a1"+
|
||||
"\u0249\3\2\2\2\u00a3\u024f\3\2\2\2\u00a5\u0254\3\2\2\2\u00a7\u0258\3\2"+
|
||||
"\2\2\u00a9\u025b\3\2\2\2\u00ab\u025d\3\2\2\2\u00ad\u025f\3\2\2\2\u00af"+
|
||||
"\u0266\3\2\2\2\u00b1\u026f\3\2\2\2\u00b3\u0271\3\2\2\2\u00b5\u0274\3\2"+
|
||||
"\2\2\u00b7\u0279\3\2\2\2\u00b9\u027f\3\2\2\2\u00bb\u0285\3\2\2\2\u00bd"+
|
||||
"\u028b\3\2\2\2\u00bf\u0290\3\2\2\2\u00c1\u0296\3\2\2\2\u00c3\u029c\3\2"+
|
||||
"\2\2\u00c5\u02a2\3\2\2\2\u00c7\u02a9\3\2\2\2\u00c9\u02af\3\2\2\2\u00cb"+
|
||||
"\u02b6\3\2\2\2\u00cd\u02bc\3\2\2\2\u00cf\u02c2\3\2\2\2\u00d1\u02c6\3\2"+
|
||||
"\2\2\u00d3\u02c9\3\2\2\2\u00d5\u02cf\3\2\2\2\u00d7\u02d6\3\2\2\2\u00d9"+
|
||||
"\u02dc\3\2\2\2\u00db\u02e7\3\2\2\2\u00dd\u02f0\3\2\2\2\u00df\u02f5\3\2"+
|
||||
"\2\2\u00e1\u02f9\3\2\2\2\u00e3\u0307\3\2\2\2\u00e5\u0309\3\2\2\2\u00e7"+
|
||||
"\u030f\3\2\2\2\u00e9\u0315\3\2\2\2\u00eb\u031e\3\2\2\2\u00ed\u032e\3\2"+
|
||||
"\2\2\u00ef\u0330\3\2\2\2\u00f1\u033b\3\2\2\2\u00f3\u0348\3\2\2\2\u00f5"+
|
||||
"\u00f6\7\u0080\2\2\u00f6\4\3\2\2\2\u00f7\u00f8\7<\2\2\u00f8\6\3\2\2\2"+
|
||||
"\u00f9\u00fa\7i\2\2\u00fa\u00fb\7q\2\2\u00fb\u00fc\7v\2\2\u00fc\u00fd"+
|
||||
"\7q\2\2\u00fd\b\3\2\2\2\u00fe\u00ff\7\'\2\2\u00ff\u0100\7q\2\2\u0100\u0101"+
|
||||
"\7w\2\2\u0101\u0102\7v\2\2\u0102\u0103\7r\2\2\u0103\u0104\7w\2\2\u0104"+
|
||||
"\u0105\7v\2\2\u0105\n\3\2\2\2\u0106\u0107\7\'\2\2\u0107\u0108\7n\2\2\u0108"+
|
||||
"\u0109\7c\2\2\u0109\u010a\7w\2\2\u010a\u010b\7p\2\2\u010b\u010c\7e\2\2"+
|
||||
"\u010c\u010d\7j\2\2\u010d\u010e\7g\2\2\u010e\u010f\7t\2\2\u010f\f\3\2"+
|
||||
"\2\2\u0110\u0111\7\'\2\2\u0111\u0112\7|\2\2\u0112\u0113\7g\2\2\u0113\u0114"+
|
||||
"\7t\2\2\u0114\u0115\7q\2\2\u0115\u0116\7r\2\2\u0116\u0117\7c\2\2\u0117"+
|
||||
"\u0118\7i\2\2\u0118\u0119\7g\2\2\u0119\16\3\2\2\2\u011a\u011b\7\'\2\2"+
|
||||
"\u011b\u011c\7|\2\2\u011c\u011d\7r\2\2\u011d\u011e\7t\2\2\u011e\u011f"+
|
||||
"\7g\2\2\u011f\u0120\7u\2\2\u0120\u0121\7g\2\2\u0121\u0122\7t\2\2\u0122"+
|
||||
"\u0123\7x\2\2\u0123\u0124\7g\2\2\u0124\u0125\7f\2\2\u0125\20\3\2\2\2\u0126"+
|
||||
"\u0127\7\'\2\2\u0127\u0128\7c\2\2\u0128\u0129\7f\2\2\u0129\u012a\7f\2"+
|
||||
"\2\u012a\u012b\7t\2\2\u012b\u012c\7g\2\2\u012c\u012d\7u\2\2\u012d\u012e"+
|
||||
"\7u\2\2\u012e\22\3\2\2\2\u012f\u0130\7\'\2\2\u0130\u0131\7k\2\2\u0131"+
|
||||
"\u0132\7o\2\2\u0132\u0133\7r\2\2\u0133\u0134\7q\2\2\u0134\u0135\7t\2\2"+
|
||||
"\u0135\u0136\7v\2\2\u0136\24\3\2\2\2\u0137\u0138\7\'\2\2\u0138\u0139\7"+
|
||||
"d\2\2\u0139\u013a\7t\2\2\u013a\u013b\7g\2\2\u013b\u013c\7c\2\2\u013c\u013d"+
|
||||
"\7m\2\2\u013d\u013e\7r\2\2\u013e\u013f\7q\2\2\u013f\u0140\7k\2\2\u0140"+
|
||||
"\u0141\7p\2\2\u0141\u0142\7v\2\2\u0142\26\3\2\2\2\u0143\u0144\7\'\2\2"+
|
||||
"\u0144\u0145\7c\2\2\u0145\u0146\7u\2\2\u0146\u0147\7o\2\2\u0147\u0148"+
|
||||
"\7k\2\2\u0148\u0149\7p\2\2\u0149\u014a\7e\2\2\u014a\u014b\7n\2\2\u014b"+
|
||||
"\u014c\7w\2\2\u014c\u014d\7f\2\2\u014d\u014e\7g\2\2\u014e\30\3\2\2\2\u014f"+
|
||||
"\u0150\7\'\2\2\u0150\u0151\7c\2\2\u0151\u0152\7u\2\2\u0152\u0153\7o\2"+
|
||||
"\2\u0153\u0154\7d\2\2\u0154\u0155\7k\2\2\u0155\u0156\7p\2\2\u0156\u0157"+
|
||||
"\7c\2\2\u0157\u0158\7t\2\2\u0158\u0159\7{\2\2\u0159\32\3\2\2\2\u015a\u015b"+
|
||||
"\7\'\2\2\u015b\u015c\7q\2\2\u015c\u015d\7r\2\2\u015d\u015e\7v\2\2\u015e"+
|
||||
"\u015f\7k\2\2\u015f\u0160\7q\2\2\u0160\u0161\7p\2\2\u0161\34\3\2\2\2\u0162"+
|
||||
"\u0163\7.\2\2\u0163\36\3\2\2\2\u0164\u0165\7?\2\2\u0165 \3\2\2\2\u0166"+
|
||||
"\u0167\7e\2\2\u0167\u0168\7q\2\2\u0168\u0169\7p\2\2\u0169\u016a\7u\2\2"+
|
||||
"\u016a\u016b\7v\2\2\u016b\"\3\2\2\2\u016c\u016d\7o\2\2\u016d\u016e\7g"+
|
||||
"\2\2\u016e\u016f\7o\2\2\u016f\u0170\7q\2\2\u0170\u0171\7t\2\2\u0171\u0172"+
|
||||
"\7{\2\2\u0172$\3\2\2\2\u0173\u0174\7w\2\2\u0174\u0175\7d\2\2\u0175\u0176"+
|
||||
"\7{\2\2\u0176\u0177\7v\2\2\u0177\u0178\7g\2\2\u0178&\3\2\2\2\u0179\u017a"+
|
||||
"\7d\2\2\u017a\u017b\7{\2\2\u017b\u017c\7v\2\2\u017c\u017d\7g\2\2\u017d"+
|
||||
"(\3\2\2\2\u017e\u017f\7w\2\2\u017f\u0180\7y\2\2\u0180\u0181\7q\2\2\u0181"+
|
||||
"\u0182\7t\2\2\u0182\u0183\7f\2\2\u0183*\3\2\2\2\u0184\u0185\7y\2\2\u0185"+
|
||||
"\u0186\7q\2\2\u0186\u0187\7t\2\2\u0187\u0188\7f\2\2\u0188,\3\2\2\2\u0189"+
|
||||
"\u018a\7h\2\2\u018a\u018b\7n\2\2\u018b\u018c\7q\2\2\u018c\u018d\7c\2\2"+
|
||||
"\u018d\u018e\7v\2\2\u018e.\3\2\2\2\u018f\u0190\7u\2\2\u0190\u0191\7v\2"+
|
||||
"\2\u0191\u0192\7t\2\2\u0192\60\3\2\2\2\u0193\u0194\7u\2\2\u0194\u0195"+
|
||||
"\7v\2\2\u0195\u0196\7t\2\2\u0196\u0197\7a\2\2\u0197\u0198\7r\2\2\u0198"+
|
||||
"\62\3\2\2\2\u0199\u019a\7u\2\2\u019a\u019b\7v\2\2\u019b\u019c\7t\2\2\u019c"+
|
||||
"\u019d\7a\2\2\u019d\u019e\7u\2\2\u019e\64\3\2\2\2\u019f\u01a0\7u\2\2\u01a0"+
|
||||
"\u01a1\7v\2\2\u01a1\u01a2\7t\2\2\u01a2\u01a3\7a\2\2\u01a3\u01a4\7r\2\2"+
|
||||
"\u01a4\u01a5\7u\2\2\u01a5\66\3\2\2\2\u01a6\u01a7\7]\2\2\u01a78\3\2\2\2"+
|
||||
"\u01a8\u01a9\7_\2\2\u01a9:\3\2\2\2\u01aa\u01ab\7-\2\2\u01ab\u01ac\7?\2"+
|
||||
"\2\u01ac<\3\2\2\2\u01ad\u01ae\7/\2\2\u01ae\u01af\7?\2\2\u01af>\3\2\2\2"+
|
||||
"\u01b0\u01b1\7\61\2\2\u01b1\u01b2\7?\2\2\u01b2@\3\2\2\2\u01b3\u01b4\7"+
|
||||
"\61\2\2\u01b4\u01b5\7\61\2\2\u01b5\u01b6\7?\2\2\u01b6B\3\2\2\2\u01b7\u01b8"+
|
||||
"\7,\2\2\u01b8\u01b9\7?\2\2\u01b9D\3\2\2\2\u01ba\u01bb\7,\2\2\u01bb\u01bc"+
|
||||
"\7,\2\2\u01bc\u01bd\7?\2\2\u01bdF\3\2\2\2\u01be\u01bf\7(\2\2\u01bf\u01c0"+
|
||||
"\7?\2\2\u01c0H\3\2\2\2\u01c1\u01c2\7~\2\2\u01c2\u01c3\7?\2\2\u01c3J\3"+
|
||||
"\2\2\2\u01c4\u01c5\7`\2\2\u01c5\u01c6\7?\2\2\u01c6L\3\2\2\2\u01c7\u01c8"+
|
||||
"\7-\2\2\u01c8\u01c9\7-\2\2\u01c9N\3\2\2\2\u01ca\u01cb\7/\2\2\u01cb\u01cc"+
|
||||
"\7/\2\2\u01ccP\3\2\2\2\u01cd\u01ce\7*\2\2\u01ceR\3\2\2\2\u01cf\u01d0\7"+
|
||||
"+\2\2\u01d0T\3\2\2\2\u01d1\u01d2\7-\2\2\u01d2V\3\2\2\2\u01d3\u01d4\7/"+
|
||||
"\2\2\u01d4X\3\2\2\2\u01d5\u01d6\7,\2\2\u01d6\u01d7\7,\2\2\u01d7Z\3\2\2"+
|
||||
"\2\u01d8\u01d9\7,\2\2\u01d9\\\3\2\2\2\u01da\u01db\7\61\2\2\u01db^\3\2"+
|
||||
"\2\2\u01dc\u01dd\7\61\2\2\u01dd\u01de\7\61\2\2\u01de`\3\2\2\2\u01df\u01e0"+
|
||||
"\7\'\2\2\u01e0b\3\2\2\2\u01e1\u01e2\7>\2\2\u01e2d\3\2\2\2\u01e3\u01e4"+
|
||||
"\7@\2\2\u01e4f\3\2\2\2\u01e5\u01e6\7>\2\2\u01e6\u01e7\7?\2\2\u01e7h\3"+
|
||||
"\2\2\2\u01e8\u01e9\7@\2\2\u01e9\u01ea\7?\2\2\u01eaj\3\2\2\2\u01eb\u01ec"+
|
||||
"\7?\2\2\u01ec\u01ed\7?\2\2\u01edl\3\2\2\2\u01ee\u01ef\7#\2\2\u01ef\u01f0"+
|
||||
"\7?\2\2\u01f0n\3\2\2\2\u01f1\u01f2\7(\2\2\u01f2p\3\2\2\2\u01f3\u01f4\7"+
|
||||
"`\2\2\u01f4r\3\2\2\2\u01f5\u01f6\7~\2\2\u01f6t\3\2\2\2\u01f7\u01f8\7v"+
|
||||
"\2\2\u01f8\u01f9\7q\2\2\u01f9v\3\2\2\2\u01fa\u01fb\7u\2\2\u01fb\u01fc"+
|
||||
"\7v\2\2\u01fc\u01fd\7g\2\2\u01fd\u01fe\7r\2\2\u01fex\3\2\2\2\u01ff\u0200"+
|
||||
"\7c\2\2\u0200\u0201\7p\2\2\u0201\u0202\7f\2\2\u0202z\3\2\2\2\u0203\u0204"+
|
||||
"\7q\2\2\u0204\u0205\7t\2\2\u0205|\3\2\2\2\u0206\u0207\7z\2\2\u0207\u0208"+
|
||||
"\7q\2\2\u0208\u0209\7t\2\2\u0209~\3\2\2\2\u020a\u020b\7p\2\2\u020b\u020c"+
|
||||
"\7q\2\2\u020c\u020d\7v\2\2\u020d\u0080\3\2\2\2\u020e\u020f\7t\2\2\u020f"+
|
||||
"\u0210\7g\2\2\u0210\u0211\7v\2\2\u0211\u0212\7w\2\2\u0212\u0213\7t\2\2"+
|
||||
"\u0213\u0214\7p\2\2\u0214\u0082\3\2\2\2\u0215\u0216\7d\2\2\u0216\u0217"+
|
||||
"\7t\2\2\u0217\u0218\7g\2\2\u0218\u0219\7c\2\2\u0219\u021a\7m\2\2\u021a"+
|
||||
"\u0084\3\2\2\2\u021b\u021c\7e\2\2\u021c\u021d\7q\2\2\u021d\u021e\7p\2"+
|
||||
"\2\u021e\u021f\7v\2\2\u021f\u0220\7k\2\2\u0220\u0221\7p\2\2\u0221\u0222"+
|
||||
"\7w\2\2\u0222\u0223\7g\2\2\u0223\u0086\3\2\2\2\u0224\u0225\7\60\2\2\u0225"+
|
||||
"\u0088\3\2\2\2\u0226\u0227\7C\2\2\u0227\u008a\3\2\2\2\u0228\u0229\7Z\2"+
|
||||
"\2\u0229\u008c\3\2\2\2\u022a\u022b\7[\2\2\u022b\u008e\3\2\2\2\u022c\u022d"+
|
||||
"\7C\2\2\u022d\u022e\7Z\2\2\u022e\u0090\3\2\2\2\u022f\u0230\7C\2\2\u0230"+
|
||||
"\u0231\7[\2\2\u0231\u0092\3\2\2\2\u0232\u0233\7Z\2\2\u0233\u0234\7[\2"+
|
||||
"\2\u0234\u0094\3\2\2\2\u0235\u0236\7R\2\2\u0236\u0237\7e\2\2\u0237\u0096"+
|
||||
"\3\2\2\2\u0238\u0239\7R\2\2\u0239\u023a\7|\2\2\u023a\u0098\3\2\2\2\u023b"+
|
||||
"\u023c\7R\2\2\u023c\u023d\7p\2\2\u023d\u009a\3\2\2\2\u023e\u023f\7R\2"+
|
||||
"\2\u023f\u0240\7x\2\2\u0240\u009c\3\2\2\2\u0241\u0242\7\60\2\2\u0242\u0243"+
|
||||
"\7y\2\2\u0243\u009e\3\2\2\2\u0244\u0245\7v\2\2\u0245\u0246\7t\2\2\u0246"+
|
||||
"\u0247\7w\2\2\u0247\u0248\7g\2\2\u0248\u00a0\3\2\2\2\u0249\u024a\7h\2"+
|
||||
"\2\u024a\u024b\7c\2\2\u024b\u024c\7n\2\2\u024c\u024d\7u\2\2\u024d\u024e"+
|
||||
"\7g\2\2\u024e\u00a2\3\2\2\2\u024f\u0250\7\'\2\2\u0250\u0251\7c\2\2\u0251"+
|
||||
"\u0252\7u\2\2\u0252\u0253\7o\2\2\u0253\u00a4\3\2\2\2\u0254\u0255\7u\2"+
|
||||
"\2\u0255\u0256\7w\2\2\u0256\u0257\7d\2\2\u0257\u00a6\3\2\2\2\u0258\u0259"+
|
||||
"\7/\2\2\u0259\u025a\7@\2\2\u025a\u00a8\3\2\2\2\u025b\u025c\7}\2\2\u025c"+
|
||||
"\u00aa\3\2\2\2\u025d\u025e\7\177\2\2\u025e\u00ac\3\2\2\2\u025f\u0260\7"+
|
||||
"c\2\2\u0260\u0261\7u\2\2\u0261\u0262\7o\2\2\u0262\u0263\7u\2\2\u0263\u0264"+
|
||||
"\7w\2\2\u0264\u0265\7d\2\2\u0265\u00ae\3\2\2\2\u0266\u0267\7e\2\2\u0267"+
|
||||
"\u0268\7n\2\2\u0268\u0269\7q\2\2\u0269\u026a\7d\2\2\u026a\u026b\7d\2\2"+
|
||||
"\u026b\u026c\7g\2\2\u026c\u026d\7t\2\2\u026d\u026e\7u\2\2\u026e\u00b0"+
|
||||
"\3\2\2\2\u026f\u0270\7B\2\2\u0270\u00b2\3\2\2\2\u0271\u0272\7k\2\2\u0272"+
|
||||
"\u0273\7h\2\2\u0273\u00b4\3\2\2\2\u0274\u0275\7g\2\2\u0275\u0276\7n\2"+
|
||||
"\2\u0276\u0277\7u\2\2\u0277\u0278\7g\2\2\u0278\u00b6\3\2\2\2\u0279\u027a"+
|
||||
"\7k\2\2\u027a\u027b\7h\2\2\u027b\u027c\7a\2\2\u027c\u027d\7e\2\2\u027d"+
|
||||
"\u027e\7u\2\2\u027e\u00b8\3\2\2\2\u027f\u0280\7k\2\2\u0280\u0281\7h\2"+
|
||||
"\2\u0281\u0282\7a\2\2\u0282\u0283\7e\2\2\u0283\u0284\7e\2\2\u0284\u00ba"+
|
||||
"\3\2\2\2\u0285\u0286\7k\2\2\u0286\u0287\7h\2\2\u0287\u0288\7a\2\2\u0288"+
|
||||
"\u0289\7g\2\2\u0289\u028a\7s\2\2\u028a\u00bc\3\2\2\2\u028b\u028c\7k\2"+
|
||||
"\2\u028c\u028d\7h\2\2\u028d\u028e\7a\2\2\u028e\u028f\7|\2\2\u028f\u00be"+
|
||||
"\3\2\2\2\u0290\u0291\7k\2\2\u0291\u0292\7h\2\2\u0292\u0293\7a\2\2\u0293"+
|
||||
"\u0294\7p\2\2\u0294\u0295\7g\2\2\u0295\u00c0\3\2\2\2\u0296\u0297\7k\2"+
|
||||
"\2\u0297\u0298\7h\2\2\u0298\u0299\7a\2\2\u0299\u029a\7p\2\2\u029a\u029b"+
|
||||
"\7|\2\2\u029b\u00c2\3\2\2\2\u029c\u029d\7k\2\2\u029d\u029e\7h\2\2\u029e"+
|
||||
"\u029f\7a\2\2\u029f\u02a0\7r\2\2\u02a0\u02a1\7n\2\2\u02a1\u00c4\3\2\2"+
|
||||
"\2\u02a2\u02a3\7k\2\2\u02a3\u02a4\7h\2\2\u02a4\u02a5\7a\2\2\u02a5\u02a6"+
|
||||
"\7r\2\2\u02a6\u02a7\7q\2\2\u02a7\u02a8\7u\2\2\u02a8\u00c6\3\2\2\2\u02a9"+
|
||||
"\u02aa\7k\2\2\u02aa\u02ab\7h\2\2\u02ab\u02ac\7a\2\2\u02ac\u02ad\7o\2\2"+
|
||||
"\u02ad\u02ae\7k\2\2\u02ae\u00c8\3\2\2\2\u02af\u02b0\7k\2\2\u02b0\u02b1"+
|
||||
"\7h\2\2\u02b1\u02b2\7a\2\2\u02b2\u02b3\7p\2\2\u02b3\u02b4\7g\2\2\u02b4"+
|
||||
"\u02b5\7i\2\2\u02b5\u00ca\3\2\2\2\u02b6\u02b7\7k\2\2\u02b7\u02b8\7h\2"+
|
||||
"\2\u02b8\u02b9\7a\2\2\u02b9\u02ba\7x\2\2\u02ba\u02bb\7u\2\2\u02bb\u00cc"+
|
||||
"\3\2\2\2\u02bc\u02bd\7k\2\2\u02bd\u02be\7h\2\2\u02be\u02bf\7a\2\2\u02bf"+
|
||||
"\u02c0\7x\2\2\u02c0\u02c1\7e\2\2\u02c1\u00ce\3\2\2\2\u02c2\u02c3\7h\2"+
|
||||
"\2\u02c3\u02c4\7q\2\2\u02c4\u02c5\7t\2\2\u02c5\u00d0\3\2\2\2\u02c6\u02c7"+
|
||||
"\7k\2\2\u02c7\u02c8\7p\2\2\u02c8\u00d2\3\2\2\2\u02c9\u02ca\7y\2\2\u02ca"+
|
||||
"\u02cb\7j\2\2\u02cb\u02cc\7k\2\2\u02cc\u02cd\7n\2\2\u02cd\u02ce\7g\2\2"+
|
||||
"\u02ce\u00d4\3\2\2\2\u02cf\u02d0\7t\2\2\u02d0\u02d1\7g\2\2\u02d1\u02d2"+
|
||||
"\7r\2\2\u02d2\u02d3\7g\2\2\u02d3\u02d4\7c\2\2\u02d4\u02d5\7v\2\2\u02d5"+
|
||||
"\u00d6\3\2\2\2\u02d6\u02d7\7w\2\2\u02d7\u02d8\7p\2\2\u02d8\u02d9\7v\2"+
|
||||
"\2\u02d9\u02da\7k\2\2\u02da\u02db\7n\2\2\u02db\u00d8\3\2\2\2\u02dc\u02e0"+
|
||||
"\t\2\2\2\u02dd\u02df\t\3\2\2\u02de\u02dd\3\2\2\2\u02df\u02e2\3\2\2\2\u02e0"+
|
||||
"\u02de\3\2\2\2\u02e0\u02e1\3\2\2\2\u02e1\u02e3\3\2\2\2\u02e2\u02e0\3\2"+
|
||||
"\2\2\u02e3\u02e4\5\u00dbn\2\u02e4\u02e5\3\2\2\2\u02e5\u02e6\bm\2\2\u02e6"+
|
||||
"\u00da\3\2\2\2\u02e7\u02eb\7=\2\2\u02e8\u02ea\n\2\2\2\u02e9\u02e8\3\2"+
|
||||
"\2\2\u02ea\u02ed\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ec\3\2\2\2\u02ec"+
|
||||
"\u02ee\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ee\u02ef\bn\2\2\u02ef\u00dc\3\2"+
|
||||
"\2\2\u02f0\u02f1\t\3\2\2\u02f1\u02f2\3\2\2\2\u02f2\u02f3\bo\3\2\u02f3"+
|
||||
"\u00de\3\2\2\2\u02f4\u02f6\t\2\2\2\u02f5\u02f4\3\2\2\2\u02f6\u02f7\3\2"+
|
||||
"\2\2\u02f7\u02f5\3\2\2\2\u02f7\u02f8\3\2\2\2\u02f8\u00e0\3\2\2\2\u02f9"+
|
||||
"\u02fd\t\4\2\2\u02fa\u02fc\t\5\2\2\u02fb\u02fa\3\2\2\2\u02fc\u02ff\3\2"+
|
||||
"\2\2\u02fd\u02fb\3\2\2\2\u02fd\u02fe\3\2\2\2\u02fe\u00e2\3\2\2\2\u02ff"+
|
||||
"\u02fd\3\2\2\2\u0300\u0308\4\62;\2\u0301\u0303\4\63;\2\u0302\u0304\4\62"+
|
||||
";\2\u0303\u0302\3\2\2\2\u0304\u0305\3\2\2\2\u0305\u0303\3\2\2\2\u0305"+
|
||||
"\u0306\3\2\2\2\u0306\u0308\3\2\2\2\u0307\u0300\3\2\2\2\u0307\u0301\3\2"+
|
||||
"\2\2\u0308\u00e4\3\2\2\2\u0309\u030b\7&\2\2\u030a\u030c\t\6\2\2\u030b"+
|
||||
"\u030a\3\2\2\2\u030c\u030d\3\2\2\2\u030d\u030b\3\2\2\2\u030d\u030e\3\2"+
|
||||
"\2\2\u030e\u00e6\3\2\2\2\u030f\u0311\7\'\2\2\u0310\u0312\4\62\63\2\u0311"+
|
||||
"\u0310\3\2\2\2\u0312\u0313\3\2\2\2\u0313\u0311\3\2\2\2\u0313\u0314\3\2"+
|
||||
"\2\2\u0314\u00e8\3\2\2\2\u0315\u031b\5\u00ebv\2\u0316\u0318\t\7\2\2\u0317"+
|
||||
"\u0319\t\b\2\2\u0318\u0317\3\2\2\2\u0318\u0319\3\2\2\2\u0319\u031a\3\2"+
|
||||
"\2\2\u031a\u031c\5\u00ebv\2\u031b\u0316\3\2\2\2\u031b\u031c\3\2\2\2\u031c"+
|
||||
"\u00ea\3\2\2\2\u031d\u031f\4\62;\2\u031e\u031d\3\2\2\2\u031f\u0320\3\2"+
|
||||
"\2\2\u0320\u031e\3\2\2\2\u0320\u0321\3\2\2\2\u0321\u0328\3\2\2\2\u0322"+
|
||||
"\u0324\7\60\2\2\u0323\u0325\4\62;\2\u0324\u0323\3\2\2\2\u0325\u0326\3"+
|
||||
"\2\2\2\u0326\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327\u0329\3\2\2\2\u0328"+
|
||||
"\u0322\3\2\2\2\u0328\u0329\3\2\2\2\u0329\u00ec\3\2\2\2\u032a\u032b\7^"+
|
||||
"\2\2\u032b\u032f\13\2\2\2\u032c\u032d\7^\2\2\u032d\u032f\5\u00dfp\2\u032e"+
|
||||
"\u032a\3\2\2\2\u032e\u032c\3\2\2\2\u032f\u00ee\3\2\2\2\u0330\u0335\7$"+
|
||||
"\2\2\u0331\u0334\5\u00edw\2\u0332\u0334\n\t\2\2\u0333\u0331\3\2\2\2\u0333"+
|
||||
"\u0332\3\2\2\2\u0334\u0337\3\2\2\2\u0335\u0333\3\2\2\2\u0335\u0336\3\2"+
|
||||
"\2\2\u0336\u0338\3\2\2\2\u0337\u0335\3\2\2\2\u0338\u0339\7$\2\2\u0339"+
|
||||
"\u033a\bx\4\2\u033a\u00f0\3\2\2\2\u033b\u033c\7}\2\2\u033c\u033d\7}\2"+
|
||||
"\2\u033d\u033f\3\2\2\2\u033e\u0340\13\2\2\2\u033f\u033e\3\2\2\2\u0340"+
|
||||
"\u0341\3\2\2\2\u0341\u0342\3\2\2\2\u0341\u033f\3\2\2\2\u0342\u0343\3\2"+
|
||||
"\2\2\u0343\u0344\7\177\2\2\u0344\u0345\7\177\2\2\u0345\u0346\3\2\2\2\u0346"+
|
||||
"\u0347\by\5\2\u0347\u00f2\3\2\2\2\u0348\u034b\7)\2\2\u0349\u034c\5\u00ed"+
|
||||
"w\2\u034a\u034c\n\t\2\2\u034b\u0349\3\2\2\2\u034b\u034a\3\2\2\2\u034c"+
|
||||
"\u034d\3\2\2\2\u034d\u034e\7)\2\2\u034e\u034f\bz\6\2\u034f\u00f4\3\2\2"+
|
||||
"\2\26\2\u02e0\u02eb\u02f7\u02fd\u0305\u0307\u030b\u030d\u0313\u0318\u031b"+
|
||||
"\u0320\u0326\u0328\u032e\u0333\u0335\u0341\u034b\7\2\3\2\b\2\2\3x\2\3"+
|
||||
"y\3\3z\4";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -60,9 +60,9 @@ class Program (val name: String,
|
||||
DataType.STR_P,
|
||||
DataType.STR_S,
|
||||
DataType.STR_PS -> heap.add(it.second, it.third.substring(1, it.third.length-1).unescape())
|
||||
DataType.ARRAY,
|
||||
DataType.ARRAY_W,
|
||||
DataType.MATRIX -> {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B,
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W,
|
||||
DataType.MATRIX_UB, DataType.MATRIX_B -> {
|
||||
val numbers = it.third.substring(1, it.third.length-1).split(',')
|
||||
val intarray = numbers.map{number->number.trim().toInt()}.toIntArray()
|
||||
heap.add(it.second, intarray)
|
||||
@ -72,7 +72,7 @@ class Program (val name: String,
|
||||
val doublearray = numbers.map{number->number.trim().toDouble()}.toDoubleArray()
|
||||
heap.add(it.second, doublearray)
|
||||
}
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> throw VmExecutionException("invalid heap value type ${it.second}")
|
||||
DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> throw VmExecutionException("invalid heap value type ${it.second}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,14 +98,14 @@ class Program (val name: String,
|
||||
val args = if(parts.size==2) parts[1] else null
|
||||
val instruction = when(opcode) {
|
||||
Opcode.LINE -> Instruction(opcode, null, callLabel = args)
|
||||
Opcode.COPY_VAR, Opcode.COPY_VAR_W, Opcode.COPY_VAR_F -> {
|
||||
Opcode.COPY_VAR_BYTE, Opcode.COPY_VAR_WORD, Opcode.COPY_VAR_FLOAT -> {
|
||||
val (v1, v2) = args!!.split(splitpattern, limit = 2)
|
||||
Instruction(opcode, null, v1, v2)
|
||||
}
|
||||
Opcode.JUMP, Opcode.CALL, Opcode.BNEG, Opcode.BPOS,
|
||||
Opcode.BZ, Opcode.BNZ, Opcode.BCS, Opcode.BCC -> {
|
||||
if(args!!.startsWith('$')) {
|
||||
Instruction(opcode, Value(DataType.WORD, args.substring(1).toInt(16)))
|
||||
Instruction(opcode, Value(DataType.UWORD, args.substring(1).toInt(16)))
|
||||
} else {
|
||||
Instruction(opcode, callLabel = args)
|
||||
}
|
||||
@ -119,7 +119,7 @@ class Program (val name: String,
|
||||
}
|
||||
Opcode.SYSCALL -> {
|
||||
val call = Syscall.valueOf(args!!)
|
||||
Instruction(opcode, Value(DataType.BYTE, call.callNr))
|
||||
Instruction(opcode, Value(DataType.UBYTE, call.callNr))
|
||||
}
|
||||
else -> {
|
||||
Instruction(opcode, getArgValue(args, heap))
|
||||
@ -142,8 +142,8 @@ class Program (val name: String,
|
||||
}
|
||||
val (type, valueStr) = args.split(':')
|
||||
return when(type) {
|
||||
"b" -> Value(DataType.BYTE, valueStr.toShort(16))
|
||||
"w" -> Value(DataType.WORD, valueStr.toInt(16))
|
||||
"b" -> Value(DataType.UBYTE, valueStr.toShort(16))
|
||||
"w" -> Value(DataType.UWORD, valueStr.toInt(16))
|
||||
"f" -> Value(DataType.FLOAT, valueStr.toDouble())
|
||||
"heap" -> {
|
||||
val heapId = valueStr.toInt()
|
||||
@ -165,7 +165,9 @@ class Program (val name: String,
|
||||
throw VmExecutionException("missing value type character")
|
||||
val type = DataType.valueOf(typeStr.toUpperCase())
|
||||
val value = when(type) {
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, valueStr.substring(2).toShort(16))
|
||||
DataType.BYTE -> Value(DataType.BYTE, valueStr.substring(2).toShort(16))
|
||||
DataType.UWORD -> Value(DataType.UWORD, valueStr.substring(2).toInt(16))
|
||||
DataType.WORD -> Value(DataType.WORD, valueStr.substring(2).toInt(16))
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, valueStr.substring(2).toDouble())
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
|
||||
@ -178,10 +180,13 @@ class Program (val name: String,
|
||||
Value(type, heapId)
|
||||
}
|
||||
}
|
||||
DataType.ARRAY,
|
||||
DataType.ARRAY_UB,
|
||||
DataType.ARRAY_B,
|
||||
DataType.ARRAY_UW,
|
||||
DataType.ARRAY_W,
|
||||
DataType.ARRAY_F,
|
||||
DataType.MATRIX -> {
|
||||
DataType.MATRIX_UB,
|
||||
DataType.MATRIX_B -> {
|
||||
if(!valueStr.startsWith("heap:"))
|
||||
throw VmExecutionException("invalid array/matrix value, should be a heap reference")
|
||||
else {
|
||||
@ -211,8 +216,8 @@ class Program (val name: String,
|
||||
val values = mutableListOf<Value>()
|
||||
valueStrings.forEach {
|
||||
when(it.length) {
|
||||
2 -> values.add(Value(DataType.BYTE, it.toShort(16)))
|
||||
4 -> values.add(Value(DataType.WORD, it.toInt(16)))
|
||||
2 -> values.add(Value(DataType.UBYTE, it.toShort(16)))
|
||||
4 -> values.add(Value(DataType.UWORD, it.toInt(16)))
|
||||
else -> throw VmExecutionException("invalid value at line $lineNr+1")
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,9 @@
|
||||
package prog8.stackvm
|
||||
|
||||
import prog8.ast.DataType
|
||||
import prog8.ast.IterableDatatypes
|
||||
import prog8.ast.NumericDatatypes
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.floor
|
||||
import kotlin.math.pow
|
||||
|
||||
@ -14,12 +17,20 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
init {
|
||||
when(type) {
|
||||
DataType.BYTE -> {
|
||||
byteval = (numericvalueOrHeapId.toInt() and 255).toShort() // byte wrap around 0..255
|
||||
DataType.UBYTE -> {
|
||||
byteval = (numericvalueOrHeapId.toInt() and 255).toShort() // ubyte wrap around 0..255
|
||||
asBooleanValue = byteval != (0.toShort())
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
byteval = limitByte(numericvalueOrHeapId.toInt())
|
||||
asBooleanValue = byteval != (0.toShort())
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
wordval = numericvalueOrHeapId.toInt() and 65535 // uword wrap around 0..65535
|
||||
asBooleanValue = wordval != 0
|
||||
}
|
||||
DataType.WORD -> {
|
||||
wordval = numericvalueOrHeapId.toInt() and 65535 // word wrap around 0..65535
|
||||
wordval = limitWord(numericvalueOrHeapId.toInt())
|
||||
asBooleanValue = wordval != 0
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
@ -35,9 +46,34 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun limitByte(value: Int): Short {
|
||||
var bval: Int
|
||||
if(value < 0) {
|
||||
bval = -(abs(value) and 127)
|
||||
if(bval==0) bval=-128
|
||||
}
|
||||
else
|
||||
bval = value and 127
|
||||
return bval.toShort()
|
||||
}
|
||||
fun limitWord(value: Int): Int {
|
||||
var bval: Int
|
||||
if(value < 0) {
|
||||
bval = -(abs(value) and 32767)
|
||||
if(bval==0) bval=-32768
|
||||
}
|
||||
else
|
||||
bval = value and 32767
|
||||
return bval
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return when(type) {
|
||||
DataType.UBYTE -> "ub:%02x".format(byteval)
|
||||
DataType.BYTE -> "b:%02x".format(byteval)
|
||||
DataType.UWORD -> "uw:%04x".format(wordval)
|
||||
DataType.WORD -> "w:%04x".format(wordval)
|
||||
DataType.FLOAT -> "f:$floatval"
|
||||
else -> "heap:$heapId"
|
||||
@ -46,8 +82,8 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun numericValue(): Number {
|
||||
return when(type) {
|
||||
DataType.BYTE -> byteval!!
|
||||
DataType.WORD -> wordval!!
|
||||
DataType.UBYTE, DataType.BYTE -> byteval!!
|
||||
DataType.UWORD, DataType.WORD -> wordval!!
|
||||
DataType.FLOAT -> floatval!!
|
||||
else -> throw VmExecutionException("invalid datatype for numeric value: $type")
|
||||
}
|
||||
@ -55,8 +91,8 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun integerValue(): Int {
|
||||
return when(type) {
|
||||
DataType.BYTE -> byteval!!.toInt()
|
||||
DataType.WORD -> wordval!!
|
||||
DataType.UBYTE, DataType.BYTE -> byteval!!.toInt()
|
||||
DataType.UWORD, DataType.WORD -> wordval!!
|
||||
DataType.FLOAT -> throw VmExecutionException("float to integer loss of precision")
|
||||
else -> throw VmExecutionException("invalid datatype for integer value: $type")
|
||||
}
|
||||
@ -72,28 +108,15 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other==null || other !is Value)
|
||||
return false
|
||||
if(type==other.type) {
|
||||
return when (type) {
|
||||
DataType.STR, DataType.STR_S, DataType.STR_P, DataType.STR_PS,
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> heapId==other.heapId
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> compareTo(other)==0
|
||||
}
|
||||
}
|
||||
if(type==other.type)
|
||||
return if (type in IterableDatatypes) heapId==other.heapId else compareTo(other)==0
|
||||
return compareTo(other)==0 // note: datatype doesn't matter
|
||||
}
|
||||
|
||||
operator fun compareTo(other: Value): Int {
|
||||
return when(type) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> {
|
||||
when(other.type) {
|
||||
DataType.BYTE, DataType.WORD, DataType.FLOAT -> {
|
||||
return if (type in NumericDatatypes && other.type in NumericDatatypes)
|
||||
numericValue().toDouble().compareTo(other.numericValue().toDouble())
|
||||
}
|
||||
else -> throw VmExecutionException("comparison can only be done between two numeric values")
|
||||
}
|
||||
}
|
||||
else -> throw VmExecutionException("comparison can only be done between two numeric values")
|
||||
}
|
||||
else throw VmExecutionException("comparison can only be done between two numeric values")
|
||||
}
|
||||
|
||||
private fun arithResult(leftDt: DataType, result: Number, rightDt: DataType, op: String): Value {
|
||||
@ -101,16 +124,19 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
throw VmExecutionException("left and right datatypes are not the same")
|
||||
if(result.toDouble() < 0 ) {
|
||||
return when(leftDt) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, result.toInt() and 255)
|
||||
DataType.WORD -> Value(DataType.WORD, result.toInt() and 65535)
|
||||
DataType.UBYTE, DataType.UWORD -> throw VmExecutionException("arithmetic error: cannot store a negative value in a $leftDt")
|
||||
DataType.BYTE -> Value(DataType.BYTE, limitByte(result.toInt()))
|
||||
DataType.WORD -> Value(DataType.WORD, limitWord(result.toInt()))
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
||||
else -> throw VmExecutionException("$op on non-numeric type")
|
||||
}
|
||||
}
|
||||
|
||||
return when(leftDt) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, result.toInt() and 255)
|
||||
DataType.WORD -> Value(DataType.WORD, result.toInt() and 65535)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, result.toInt() and 255)
|
||||
DataType.BYTE -> Value(DataType.BYTE, limitByte(result.toInt()))
|
||||
DataType.UWORD -> Value(DataType.UWORD, result.toInt() and 65535)
|
||||
DataType.WORD -> Value(DataType.WORD, limitWord(result.toInt()))
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
||||
else -> throw VmExecutionException("$op on non-numeric type")
|
||||
}
|
||||
@ -149,16 +175,16 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
val v1 = numericValue()
|
||||
val v2 = other.numericValue()
|
||||
if(v2.toDouble()==0.0) {
|
||||
if (type == DataType.BYTE)
|
||||
return Value(DataType.BYTE, 255)
|
||||
else if(type == DataType.WORD)
|
||||
return Value(DataType.WORD, 65535)
|
||||
if (type == DataType.UBYTE)
|
||||
return Value(DataType.UBYTE, 255)
|
||||
else if(type == DataType.UWORD)
|
||||
return Value(DataType.UWORD, 65535)
|
||||
}
|
||||
val result = v1.toDouble() / v2.toDouble()
|
||||
// NOTE: integer division returns integer result!
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, result)
|
||||
DataType.WORD -> Value(DataType.WORD, result)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, result)
|
||||
DataType.UWORD -> Value(DataType.UWORD, result)
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
||||
else -> throw VmExecutionException("div on non-numeric type")
|
||||
}
|
||||
@ -172,8 +198,8 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
val result = floor(v1.toDouble() / v2.toDouble())
|
||||
// NOTE: integer division returns integer result!
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, result)
|
||||
DataType.WORD -> Value(DataType.WORD, result)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, result)
|
||||
DataType.UWORD -> Value(DataType.UWORD, result)
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, result)
|
||||
else -> throw VmExecutionException("div on non-numeric type")
|
||||
}
|
||||
@ -206,17 +232,17 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
fun rol(carry: Boolean): Pair<Value, Boolean> {
|
||||
// 9 or 17 bit rotate left (with carry))
|
||||
return when(type) {
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
val v = byteval!!.toInt()
|
||||
val newCarry = (v and 0x80) != 0
|
||||
val newval = (v and 0x7f shl 1) or (if(carry) 1 else 0)
|
||||
Pair(Value(DataType.BYTE, newval), newCarry)
|
||||
Pair(Value(DataType.UBYTE, newval), newCarry)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.UWORD -> {
|
||||
val v = wordval!!
|
||||
val newCarry = (v and 0x8000) != 0
|
||||
val newval = (v and 0x7fff shl 1) or (if(carry) 1 else 0)
|
||||
Pair(Value(DataType.WORD, newval), newCarry)
|
||||
Pair(Value(DataType.UWORD, newval), newCarry)
|
||||
}
|
||||
else -> throw VmExecutionException("rol can only work on byte/word")
|
||||
}
|
||||
@ -225,17 +251,17 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
fun ror(carry: Boolean): Pair<Value, Boolean> {
|
||||
// 9 or 17 bit rotate right (with carry)
|
||||
return when(type) {
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
val v = byteval!!.toInt()
|
||||
val newCarry = v and 1 != 0
|
||||
val newval = (v ushr 1) or (if(carry) 0x80 else 0)
|
||||
Pair(Value(DataType.BYTE, newval), newCarry)
|
||||
Pair(Value(DataType.UBYTE, newval), newCarry)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.UWORD -> {
|
||||
val v = wordval!!
|
||||
val newCarry = v and 1 != 0
|
||||
val newval = (v ushr 1) or (if(carry) 0x8000 else 0)
|
||||
Pair(Value(DataType.WORD, newval), newCarry)
|
||||
Pair(Value(DataType.UWORD, newval), newCarry)
|
||||
}
|
||||
else -> throw VmExecutionException("ror2 can only work on byte/word")
|
||||
}
|
||||
@ -244,17 +270,17 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
fun rol2(): Value {
|
||||
// 8 or 16 bit rotate left
|
||||
return when(type) {
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
val v = byteval!!.toInt()
|
||||
val carry = (v and 0x80) ushr 7
|
||||
val newval = (v and 0x7f shl 1) or carry
|
||||
Value(DataType.BYTE, newval)
|
||||
Value(DataType.UBYTE, newval)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.UWORD -> {
|
||||
val v = wordval!!
|
||||
val carry = (v and 0x8000) ushr 15
|
||||
val newval = (v and 0x7fff shl 1) or carry
|
||||
Value(DataType.WORD, newval)
|
||||
Value(DataType.UWORD, newval)
|
||||
}
|
||||
else -> throw VmExecutionException("rol2 can only work on byte/word")
|
||||
}
|
||||
@ -263,17 +289,17 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
fun ror2(): Value {
|
||||
// 8 or 16 bit rotate right
|
||||
return when(type) {
|
||||
DataType.BYTE -> {
|
||||
DataType.UBYTE -> {
|
||||
val v = byteval!!.toInt()
|
||||
val carry = v and 1 shl 7
|
||||
val newval = (v ushr 1) or carry
|
||||
Value(DataType.BYTE, newval)
|
||||
Value(DataType.UBYTE, newval)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
DataType.UWORD -> {
|
||||
val v = wordval!!
|
||||
val carry = v and 1 shl 15
|
||||
val newval = (v ushr 1) or carry
|
||||
Value(DataType.WORD, newval)
|
||||
Value(DataType.UWORD, newval)
|
||||
}
|
||||
else -> throw VmExecutionException("ror2 can only work on byte/word")
|
||||
}
|
||||
@ -281,8 +307,8 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun neg(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, -(byteval!!))
|
||||
DataType.WORD -> Value(DataType.WORD, -(wordval!!))
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, -(byteval!!))
|
||||
DataType.UWORD -> Value(DataType.UWORD, -(wordval!!))
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, -(floatval)!!)
|
||||
else -> throw VmExecutionException("neg can only work on byte/word/float")
|
||||
}
|
||||
@ -309,23 +335,23 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
return Value(type, result)
|
||||
}
|
||||
|
||||
fun and(other: Value) = Value(DataType.BYTE, if (this.asBooleanValue && other.asBooleanValue) 1 else 0)
|
||||
fun or(other: Value) = Value(DataType.BYTE, if (this.asBooleanValue || other.asBooleanValue) 1 else 0)
|
||||
fun xor(other: Value) = Value(DataType.BYTE, if (this.asBooleanValue xor other.asBooleanValue) 1 else 0)
|
||||
fun not() = Value(DataType.BYTE, if (this.asBooleanValue) 0 else 1)
|
||||
fun and(other: Value) = Value(DataType.UBYTE, if (this.asBooleanValue && other.asBooleanValue) 1 else 0)
|
||||
fun or(other: Value) = Value(DataType.UBYTE, if (this.asBooleanValue || other.asBooleanValue) 1 else 0)
|
||||
fun xor(other: Value) = Value(DataType.UBYTE, if (this.asBooleanValue xor other.asBooleanValue) 1 else 0)
|
||||
fun not() = Value(DataType.UBYTE, if (this.asBooleanValue) 0 else 1)
|
||||
|
||||
fun inv(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, byteval!!.toInt().inv() and 255)
|
||||
DataType.WORD -> Value(DataType.WORD, wordval!!.inv() and 65535)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, byteval!!.toInt().inv() and 255)
|
||||
DataType.UWORD -> Value(DataType.UWORD, wordval!!.inv() and 65535)
|
||||
else -> throw VmExecutionException("inv can only work on byte/word")
|
||||
}
|
||||
}
|
||||
|
||||
fun inc(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, (byteval!! + 1) and 255)
|
||||
DataType.WORD -> Value(DataType.WORD, (wordval!! + 1) and 65535)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, (byteval!! + 1) and 255)
|
||||
DataType.UWORD -> Value(DataType.UWORD, (wordval!! + 1) and 65535)
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, floatval!! + 1)
|
||||
else -> throw VmExecutionException("inc can only work on byte/word/float")
|
||||
}
|
||||
@ -333,8 +359,8 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun dec(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, (byteval!! - 1) and 255)
|
||||
DataType.WORD -> Value(DataType.WORD, (wordval!! - 1) and 65535)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, (byteval!! - 1) and 255)
|
||||
DataType.UWORD -> Value(DataType.UWORD, (wordval!! - 1) and 65535)
|
||||
DataType.FLOAT -> Value(DataType.FLOAT, floatval!! - 1)
|
||||
else -> throw VmExecutionException("dec can only work on byte/word/float")
|
||||
}
|
||||
@ -342,16 +368,16 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
|
||||
|
||||
fun lsb(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, byteval!!)
|
||||
DataType.WORD -> Value(DataType.BYTE, wordval!! and 255)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, byteval!!)
|
||||
DataType.UWORD -> Value(DataType.UBYTE, wordval!! and 255)
|
||||
else -> throw VmExecutionException("not can only work on byte/word")
|
||||
}
|
||||
}
|
||||
|
||||
fun msb(): Value {
|
||||
return when(type) {
|
||||
DataType.BYTE -> Value(DataType.BYTE, 0)
|
||||
DataType.WORD -> Value(DataType.BYTE, wordval!! ushr 8 and 255)
|
||||
DataType.UBYTE -> Value(DataType.UBYTE, 0)
|
||||
DataType.UWORD -> Value(DataType.UBYTE, wordval!! ushr 8 and 255)
|
||||
else -> throw VmExecutionException("not can only work on byte/word")
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -116,16 +116,16 @@ class TestZeropage {
|
||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false))
|
||||
|
||||
assertFailsWith<AssertionError> {
|
||||
zp.allocate(VarDecl(VarDeclType.MEMORY, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.MEMORY, DataType.UBYTE, null, "", null, dummypos))
|
||||
}
|
||||
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "varname", null, dummypos))
|
||||
assertFailsWith<AssertionError> {
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "varname", null, dummypos))
|
||||
}
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname2", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "varname2", null, dummypos))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -183,15 +183,15 @@ class TestZeropage {
|
||||
}
|
||||
|
||||
for (i in 0 until zp.available()) {
|
||||
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
assertTrue(loc > 0)
|
||||
}
|
||||
assertEquals(0, zp.available())
|
||||
assertFailsWith<CompilerException> {
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
}
|
||||
assertFailsWith<CompilerException> {
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,16 +216,16 @@ class TestZeropage {
|
||||
}
|
||||
|
||||
for(i in 0..13) {
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
}
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos))
|
||||
|
||||
assertEquals(1, zp.available())
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
assertFailsWith<CompilerException> {
|
||||
// no more space
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos))
|
||||
zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos))
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,17 +237,17 @@ class TestZeropage {
|
||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true))
|
||||
assertEquals(23, zp.available())
|
||||
assertEquals(0x04, zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null, dummypos)))
|
||||
assertEquals(0x09, zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos)))
|
||||
assertEquals(0x12, zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos)))
|
||||
assertEquals(0x0d, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0x94, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0x2a, zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos)))
|
||||
assertEquals(0xa7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0xa9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0xb5, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0xf7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0xf9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null, dummypos)))
|
||||
assertEquals(0x52, zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null, dummypos)))
|
||||
assertEquals(0x09, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
|
||||
assertEquals(0x12, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
|
||||
assertEquals(0x0d, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0x94, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0x2a, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
|
||||
assertEquals(0xa7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0xa9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0xb5, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0xf7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0xf9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, null, "", null, dummypos)))
|
||||
assertEquals(0x52, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, null, "", null, dummypos)))
|
||||
assertEquals(0, zp.available())
|
||||
}
|
||||
}
|
||||
@ -314,8 +314,8 @@ class TestPetscii {
|
||||
|
||||
@Test
|
||||
fun testLiteralValueComparisons() {
|
||||
val ten = LiteralValue(DataType.WORD, wordvalue=10, position=Position("", 0 ,0 ,0))
|
||||
val nine = LiteralValue(DataType.BYTE, bytevalue=9, position=Position("", 0 ,0 ,0))
|
||||
val ten = LiteralValue(DataType.UWORD, wordvalue=10, position=Position("", 0 ,0 ,0))
|
||||
val nine = LiteralValue(DataType.UBYTE, bytevalue=9, position=Position("", 0 ,0 ,0))
|
||||
assertTrue(ten == ten)
|
||||
assertFalse(ten == nine)
|
||||
assertFalse(ten != ten)
|
||||
@ -347,7 +347,7 @@ class TestPetscii {
|
||||
@Test
|
||||
fun testStackvmValueComparisons() {
|
||||
val ten = Value(DataType.FLOAT, 10)
|
||||
val nine = Value(DataType.WORD, 9)
|
||||
val nine = Value(DataType.UWORD, 9)
|
||||
assertTrue(ten == ten)
|
||||
assertFalse(ten == nine)
|
||||
assertFalse(ten != ten)
|
||||
|
@ -25,7 +25,7 @@ class TestStackVmValue {
|
||||
|
||||
@Test
|
||||
fun testIdentity() {
|
||||
val v = Value(DataType.WORD, 12345)
|
||||
val v = Value(DataType.UWORD, 12345)
|
||||
assertEquals(v, v)
|
||||
assertFalse(v != v)
|
||||
assertTrue(v<=v)
|
||||
@ -33,49 +33,49 @@ class TestStackVmValue {
|
||||
assertFalse(v<v)
|
||||
assertFalse(v>v)
|
||||
|
||||
assertTrue(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.BYTE, 100)))
|
||||
assertTrue(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.UBYTE, 100)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEqualsAndNotEquals() {
|
||||
assertEquals(Value(DataType.BYTE, 100), Value(DataType.BYTE, 100))
|
||||
assertEquals(Value(DataType.BYTE, 100), Value(DataType.WORD, 100))
|
||||
assertEquals(Value(DataType.BYTE, 100), Value(DataType.FLOAT, 100))
|
||||
assertEquals(Value(DataType.WORD, 254), Value(DataType.BYTE, 254))
|
||||
assertEquals(Value(DataType.WORD, 12345), Value(DataType.WORD, 12345))
|
||||
assertEquals(Value(DataType.WORD, 12345), Value(DataType.FLOAT, 12345))
|
||||
assertEquals(Value(DataType.FLOAT, 100.0), Value(DataType.BYTE, 100))
|
||||
assertEquals(Value(DataType.FLOAT, 22239.0), Value(DataType.WORD, 22239))
|
||||
assertEquals(Value(DataType.UBYTE, 100), Value(DataType.UBYTE, 100))
|
||||
assertEquals(Value(DataType.UBYTE, 100), Value(DataType.UWORD, 100))
|
||||
assertEquals(Value(DataType.UBYTE, 100), Value(DataType.FLOAT, 100))
|
||||
assertEquals(Value(DataType.UWORD, 254), Value(DataType.UBYTE, 254))
|
||||
assertEquals(Value(DataType.UWORD, 12345), Value(DataType.UWORD, 12345))
|
||||
assertEquals(Value(DataType.UWORD, 12345), Value(DataType.FLOAT, 12345))
|
||||
assertEquals(Value(DataType.FLOAT, 100.0), Value(DataType.UBYTE, 100))
|
||||
assertEquals(Value(DataType.FLOAT, 22239.0), Value(DataType.UWORD, 22239))
|
||||
assertEquals(Value(DataType.FLOAT, 9.99), Value(DataType.FLOAT, 9.99))
|
||||
|
||||
assertTrue(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.BYTE, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.WORD, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.FLOAT, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.WORD, 254), Value(DataType.BYTE, 254)))
|
||||
assertTrue(sameValueAndType(Value(DataType.WORD, 12345), Value(DataType.WORD, 12345)))
|
||||
assertFalse(sameValueAndType(Value(DataType.WORD, 12345), Value(DataType.FLOAT, 12345)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 100.0), Value(DataType.BYTE, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 22239.0), Value(DataType.WORD, 22239)))
|
||||
assertTrue(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.UBYTE, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.UWORD, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.FLOAT, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UWORD, 254), Value(DataType.UBYTE, 254)))
|
||||
assertTrue(sameValueAndType(Value(DataType.UWORD, 12345), Value(DataType.UWORD, 12345)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UWORD, 12345), Value(DataType.FLOAT, 12345)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 100.0), Value(DataType.UBYTE, 100)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 22239.0), Value(DataType.UWORD, 22239)))
|
||||
assertTrue(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.FLOAT, 9.99)))
|
||||
|
||||
assertNotEquals(Value(DataType.BYTE, 100), Value(DataType.BYTE, 101))
|
||||
assertNotEquals(Value(DataType.BYTE, 100), Value(DataType.WORD, 101))
|
||||
assertNotEquals(Value(DataType.BYTE, 100), Value(DataType.FLOAT, 101))
|
||||
assertNotEquals(Value(DataType.WORD, 245), Value(DataType.BYTE, 246))
|
||||
assertNotEquals(Value(DataType.WORD, 12345), Value(DataType.WORD, 12346))
|
||||
assertNotEquals(Value(DataType.WORD, 12345), Value(DataType.FLOAT, 12346))
|
||||
assertNotEquals(Value(DataType.FLOAT, 9.99), Value(DataType.BYTE, 9))
|
||||
assertNotEquals(Value(DataType.FLOAT, 9.99), Value(DataType.WORD, 9))
|
||||
assertNotEquals(Value(DataType.UBYTE, 100), Value(DataType.UBYTE, 101))
|
||||
assertNotEquals(Value(DataType.UBYTE, 100), Value(DataType.UWORD, 101))
|
||||
assertNotEquals(Value(DataType.UBYTE, 100), Value(DataType.FLOAT, 101))
|
||||
assertNotEquals(Value(DataType.UWORD, 245), Value(DataType.UBYTE, 246))
|
||||
assertNotEquals(Value(DataType.UWORD, 12345), Value(DataType.UWORD, 12346))
|
||||
assertNotEquals(Value(DataType.UWORD, 12345), Value(DataType.FLOAT, 12346))
|
||||
assertNotEquals(Value(DataType.FLOAT, 9.99), Value(DataType.UBYTE, 9))
|
||||
assertNotEquals(Value(DataType.FLOAT, 9.99), Value(DataType.UWORD, 9))
|
||||
assertNotEquals(Value(DataType.FLOAT, 9.99), Value(DataType.FLOAT, 9.0))
|
||||
|
||||
assertFalse(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.BYTE, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.WORD, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.BYTE, 100), Value(DataType.FLOAT, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.WORD, 245), Value(DataType.BYTE, 246)))
|
||||
assertFalse(sameValueAndType(Value(DataType.WORD, 12345), Value(DataType.WORD, 12346)))
|
||||
assertFalse(sameValueAndType(Value(DataType.WORD, 12345), Value(DataType.FLOAT, 12346)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.BYTE, 9)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.WORD, 9)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.UBYTE, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.UWORD, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UBYTE, 100), Value(DataType.FLOAT, 101)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UWORD, 245), Value(DataType.UBYTE, 246)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UWORD, 12345), Value(DataType.UWORD, 12346)))
|
||||
assertFalse(sameValueAndType(Value(DataType.UWORD, 12345), Value(DataType.FLOAT, 12346)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.UBYTE, 9)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.UWORD, 9)))
|
||||
assertFalse(sameValueAndType(Value(DataType.FLOAT, 9.99), Value(DataType.FLOAT, 9.0)))
|
||||
}
|
||||
|
||||
@ -86,98 +86,98 @@ class TestStackVmValue {
|
||||
assertFalse(sameValueAndType(Value(DataType.STR, 999), Value(DataType.STR_P, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.STR, 999), Value(DataType.STR, 222)))
|
||||
|
||||
assertTrue(sameValueAndType(Value(DataType.ARRAY, 99), Value(DataType.ARRAY, 99)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY, 99), Value(DataType.MATRIX, 99)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY, 99), Value(DataType.ARRAY, 22)))
|
||||
assertTrue(sameValueAndType(Value(DataType.ARRAY_UB, 99), Value(DataType.ARRAY_UB, 99)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_UB, 99), Value(DataType.MATRIX_UB, 99)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_UB, 99), Value(DataType.ARRAY_UB, 22)))
|
||||
|
||||
assertTrue(sameValueAndType(Value(DataType.ARRAY_W, 999), Value(DataType.ARRAY_W, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_W, 999), Value(DataType.MATRIX, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_W, 999), Value(DataType.ARRAY_W, 222)))
|
||||
assertTrue(sameValueAndType(Value(DataType.ARRAY_UW, 999), Value(DataType.ARRAY_UW, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_UW, 999), Value(DataType.MATRIX_UB, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_UW, 999), Value(DataType.ARRAY_UW, 222)))
|
||||
|
||||
assertTrue(sameValueAndType(Value(DataType.ARRAY_F, 999), Value(DataType.ARRAY_F, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_F, 999), Value(DataType.ARRAY_W, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_F, 999), Value(DataType.ARRAY_UW, 999)))
|
||||
assertFalse(sameValueAndType(Value(DataType.ARRAY_F, 999), Value(DataType.ARRAY_F, 222)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGreaterThan(){
|
||||
assertTrue(Value(DataType.BYTE, 100) > Value(DataType.BYTE, 99))
|
||||
assertTrue(Value(DataType.WORD, 254) > Value(DataType.WORD, 253))
|
||||
assertTrue(Value(DataType.UBYTE, 100) > Value(DataType.UBYTE, 99))
|
||||
assertTrue(Value(DataType.UWORD, 254) > Value(DataType.UWORD, 253))
|
||||
assertTrue(Value(DataType.FLOAT, 100.0) > Value(DataType.FLOAT, 99.9))
|
||||
|
||||
assertTrue(Value(DataType.BYTE, 100) >= Value(DataType.BYTE, 100))
|
||||
assertTrue(Value(DataType.WORD, 254) >= Value(DataType.WORD, 254))
|
||||
assertTrue(Value(DataType.UBYTE, 100) >= Value(DataType.UBYTE, 100))
|
||||
assertTrue(Value(DataType.UWORD, 254) >= Value(DataType.UWORD, 254))
|
||||
assertTrue(Value(DataType.FLOAT, 100.0) >= Value(DataType.FLOAT, 100.0))
|
||||
|
||||
assertFalse(Value(DataType.BYTE, 100) > Value(DataType.BYTE, 100))
|
||||
assertFalse(Value(DataType.WORD, 254) > Value(DataType.WORD, 254))
|
||||
assertFalse(Value(DataType.UBYTE, 100) > Value(DataType.UBYTE, 100))
|
||||
assertFalse(Value(DataType.UWORD, 254) > Value(DataType.UWORD, 254))
|
||||
assertFalse(Value(DataType.FLOAT, 100.0) > Value(DataType.FLOAT, 100.0))
|
||||
|
||||
assertFalse(Value(DataType.BYTE, 100) >= Value(DataType.BYTE, 101))
|
||||
assertFalse(Value(DataType.WORD, 254) >= Value(DataType.WORD, 255))
|
||||
assertFalse(Value(DataType.UBYTE, 100) >= Value(DataType.UBYTE, 101))
|
||||
assertFalse(Value(DataType.UWORD, 254) >= Value(DataType.UWORD, 255))
|
||||
assertFalse(Value(DataType.FLOAT, 100.0) >= Value(DataType.FLOAT, 100.1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLessThan() {
|
||||
assertTrue(Value(DataType.BYTE, 100) < Value(DataType.BYTE, 101))
|
||||
assertTrue(Value(DataType.WORD, 254) < Value(DataType.WORD, 255))
|
||||
assertTrue(Value(DataType.UBYTE, 100) < Value(DataType.UBYTE, 101))
|
||||
assertTrue(Value(DataType.UWORD, 254) < Value(DataType.UWORD, 255))
|
||||
assertTrue(Value(DataType.FLOAT, 100.0) < Value(DataType.FLOAT, 100.1))
|
||||
|
||||
assertTrue(Value(DataType.BYTE, 100) <= Value(DataType.BYTE, 100))
|
||||
assertTrue(Value(DataType.WORD, 254) <= Value(DataType.WORD, 254))
|
||||
assertTrue(Value(DataType.UBYTE, 100) <= Value(DataType.UBYTE, 100))
|
||||
assertTrue(Value(DataType.UWORD, 254) <= Value(DataType.UWORD, 254))
|
||||
assertTrue(Value(DataType.FLOAT, 100.0) <= Value(DataType.FLOAT, 100.0))
|
||||
|
||||
assertFalse(Value(DataType.BYTE, 100) < Value(DataType.BYTE, 100))
|
||||
assertFalse(Value(DataType.WORD, 254) < Value(DataType.WORD, 254))
|
||||
assertFalse(Value(DataType.UBYTE, 100) < Value(DataType.UBYTE, 100))
|
||||
assertFalse(Value(DataType.UWORD, 254) < Value(DataType.UWORD, 254))
|
||||
assertFalse(Value(DataType.FLOAT, 100.0) < Value(DataType.FLOAT, 100.0))
|
||||
|
||||
assertFalse(Value(DataType.BYTE, 100) <= Value(DataType.BYTE, 99))
|
||||
assertFalse(Value(DataType.WORD, 254) <= Value(DataType.WORD, 253))
|
||||
assertFalse(Value(DataType.UBYTE, 100) <= Value(DataType.UBYTE, 99))
|
||||
assertFalse(Value(DataType.UWORD, 254) <= Value(DataType.UWORD, 253))
|
||||
assertFalse(Value(DataType.FLOAT, 100.0) <= Value(DataType.FLOAT, 99.9))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNoDtConversion() {
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.WORD, 100).add(Value(DataType.BYTE, 120))
|
||||
Value(DataType.UWORD, 100).add(Value(DataType.UBYTE, 120))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.BYTE, 100).add(Value(DataType.WORD, 120))
|
||||
Value(DataType.UBYTE, 100).add(Value(DataType.UWORD, 120))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.FLOAT, 100.22).add(Value(DataType.WORD, 120))
|
||||
Value(DataType.FLOAT, 100.22).add(Value(DataType.UWORD, 120))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.WORD, 1002).add(Value(DataType.FLOAT, 120.22))
|
||||
Value(DataType.UWORD, 1002).add(Value(DataType.FLOAT, 120.22))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.FLOAT, 100.22).add(Value(DataType.BYTE, 120))
|
||||
Value(DataType.FLOAT, 100.22).add(Value(DataType.UBYTE, 120))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.BYTE, 12).add(Value(DataType.FLOAT, 120.22))
|
||||
Value(DataType.UBYTE, 12).add(Value(DataType.FLOAT, 120.22))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNoAutoFloatConversion() {
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.BYTE, 233).add(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UBYTE, 233).add(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.WORD, 233).add(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UWORD, 233).add(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.BYTE, 233).mul(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UBYTE, 233).mul(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.WORD, 233).mul(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UWORD, 233).mul(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.BYTE, 233).div(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UBYTE, 233).div(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
assertFailsWith<VmExecutionException> {
|
||||
Value(DataType.WORD, 233).div(Value(DataType.FLOAT, 1.234))
|
||||
Value(DataType.UWORD, 233).div(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
val result = Value(DataType.FLOAT, 233.333).add(Value(DataType.FLOAT, 1.234))
|
||||
}
|
||||
@ -191,7 +191,7 @@ class TestParserLiteralValue {
|
||||
|
||||
@Test
|
||||
fun testIdentity() {
|
||||
val v = LiteralValue(DataType.WORD, wordvalue = 12345, position = dummyPos)
|
||||
val v = LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos)
|
||||
assertEquals(v, v)
|
||||
assertFalse(v != v)
|
||||
assertTrue(v <= v)
|
||||
@ -199,62 +199,62 @@ class TestParserLiteralValue {
|
||||
assertFalse(v < v)
|
||||
assertFalse(v > v)
|
||||
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.WORD, wordvalue = 12345, position = dummyPos), LiteralValue(DataType.WORD, wordvalue = 12345, position = dummyPos)))
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos), LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEqualsAndNotEquals() {
|
||||
assertEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.BYTE, 254, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.WORD,wordvalue=22239, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos))
|
||||
assertEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos))
|
||||
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.BYTE, 100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.BYTE, 254, position=dummyPos)))
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.BYTE, 100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.WORD,wordvalue=22239, position=dummyPos)))
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos)))
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos)))
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos)))
|
||||
|
||||
assertNotEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.BYTE, 101, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=101, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.WORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.BYTE, 246, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=12346, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.BYTE, 9, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=9, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos))
|
||||
assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos))
|
||||
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.BYTE, 101, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=101, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.BYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.BYTE, 246, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=12346, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.WORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.BYTE, 9, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.WORD, wordvalue=9, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos)))
|
||||
|
||||
assertTrue(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="hello", position=dummyPos)))
|
||||
assertFalse(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="bye", position=dummyPos)))
|
||||
|
||||
val lvOne = LiteralValue(DataType.BYTE, 1, position=dummyPos)
|
||||
val lvTwo = LiteralValue(DataType.BYTE, 2, position=dummyPos)
|
||||
val lvThree = LiteralValue(DataType.BYTE, 3, position=dummyPos)
|
||||
val lvOneR = LiteralValue(DataType.BYTE, 1, position=dummyPos)
|
||||
val lvTwoR = LiteralValue(DataType.BYTE, 2, position=dummyPos)
|
||||
val lvThreeR = LiteralValue(DataType.BYTE, 3, position=dummyPos)
|
||||
val lv1 = LiteralValue(DataType.ARRAY, arrayvalue = arrayOf(lvOne, lvTwo, lvThree), position=dummyPos)
|
||||
val lv2 = LiteralValue(DataType.ARRAY, arrayvalue = arrayOf(lvOneR, lvTwoR, lvThreeR), position=dummyPos)
|
||||
val lvOne = LiteralValue(DataType.UBYTE, 1, position=dummyPos)
|
||||
val lvTwo = LiteralValue(DataType.UBYTE, 2, position=dummyPos)
|
||||
val lvThree = LiteralValue(DataType.UBYTE, 3, position=dummyPos)
|
||||
val lvOneR = LiteralValue(DataType.UBYTE, 1, position=dummyPos)
|
||||
val lvTwoR = LiteralValue(DataType.UBYTE, 2, position=dummyPos)
|
||||
val lvThreeR = LiteralValue(DataType.UBYTE, 3, position=dummyPos)
|
||||
val lv1 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOne, lvTwo, lvThree), position=dummyPos)
|
||||
val lv2 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOneR, lvTwoR, lvThreeR), position=dummyPos)
|
||||
assertFailsWith<ExpressionError> {
|
||||
assertEquals(lv1, lv2)
|
||||
}
|
||||
@ -262,39 +262,39 @@ class TestParserLiteralValue {
|
||||
|
||||
@Test
|
||||
fun testGreaterThan(){
|
||||
assertTrue(LiteralValue(DataType.BYTE, 100, position=dummyPos) > LiteralValue(DataType.BYTE, 99, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.WORD, wordvalue=253, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 99, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=253, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos))
|
||||
|
||||
assertTrue(LiteralValue(DataType.BYTE, 100, position=dummyPos) >= LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.WORD,wordvalue= 254, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
|
||||
assertFalse(LiteralValue(DataType.BYTE, 100, position=dummyPos) > LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
|
||||
assertFalse(LiteralValue(DataType.BYTE, 100, position=dummyPos) >= LiteralValue(DataType.BYTE, 101, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.WORD,wordvalue= 255, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 101, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 255, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLessThan() {
|
||||
assertTrue(LiteralValue(DataType.BYTE, 100, position=dummyPos) < LiteralValue(DataType.BYTE, 101, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.WORD, wordvalue=255, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 101, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=255, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos))
|
||||
|
||||
assertTrue(LiteralValue(DataType.BYTE, 100, position=dummyPos) <= LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) <= LiteralValue(DataType.WORD,wordvalue= 254, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos))
|
||||
assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
|
||||
assertFalse(LiteralValue(DataType.BYTE, 100, position=dummyPos) < LiteralValue(DataType.BYTE, 100, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.WORD, wordvalue=254, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 100, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))
|
||||
|
||||
assertFalse(LiteralValue(DataType.BYTE, 100, position=dummyPos) <= LiteralValue(DataType.BYTE, 99, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.WORD,wordvalue= 254, position=dummyPos) <= LiteralValue(DataType.WORD,wordvalue= 253, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 99, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 253, position=dummyPos))
|
||||
assertFalse(LiteralValue(DataType.FLOAT,floatvalue= 100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user