added ast check for invalid type cast

This commit is contained in:
Irmen de Jong 2019-01-16 23:24:47 +01:00
parent aa8f8978f0
commit 9424387803
4 changed files with 45 additions and 85 deletions

View File

@ -697,6 +697,8 @@ class AstChecker(private val namespace: INameScope,
} }
override fun process(typecast: TypecastExpression): IExpression { override fun process(typecast: TypecastExpression): IExpression {
if(typecast.type in IterableDatatypes)
checkResult.add(ExpressionError("cannot type cast to string or array type", typecast.position))
val funcTarget = (typecast.expression as? IFunctionCall)?.target?.targetStatement(namespace) val funcTarget = (typecast.expression as? IFunctionCall)?.target?.targetStatement(namespace)
if(funcTarget is Subroutine && if(funcTarget is Subroutine &&
funcTarget.asmReturnvaluesRegisters.isNotEmpty() && funcTarget.asmReturnvaluesRegisters.isNotEmpty() &&

View File

@ -2190,7 +2190,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.UWORD-> prog.instr(Opcode.CAST_UW_TO_UB) DataType.UWORD-> prog.instr(Opcode.CAST_UW_TO_UB)
DataType.WORD-> prog.instr(Opcode.CAST_W_TO_UB) DataType.WORD-> prog.instr(Opcode.CAST_W_TO_UB)
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UB) DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UB)
else -> throw CompilerException("invalid cast type $sourceDt") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
DataType.BYTE -> when(sourceDt) { DataType.BYTE -> when(sourceDt) {
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_B) DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_B)
@ -2198,7 +2198,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_B) DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_B)
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_B) DataType.WORD -> prog.instr(Opcode.CAST_W_TO_B)
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_B) DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_B)
else -> throw CompilerException("invalid cast type $sourceDt") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
DataType.UWORD -> when(sourceDt) { DataType.UWORD -> when(sourceDt) {
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_UW) DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_UW)
@ -2206,7 +2206,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.UWORD -> {} DataType.UWORD -> {}
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_UW) DataType.WORD -> prog.instr(Opcode.CAST_W_TO_UW)
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UW) DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_UW)
else -> throw CompilerException("invalid cast type $sourceDt") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
DataType.WORD -> when(sourceDt) { DataType.WORD -> when(sourceDt) {
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_W) DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_W)
@ -2214,7 +2214,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_W) DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_W)
DataType.WORD -> {} DataType.WORD -> {}
DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_W) DataType.FLOAT -> prog.instr(Opcode.CAST_F_TO_W)
else -> throw CompilerException("invalid cast type $sourceDt") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
DataType.FLOAT -> when(sourceDt) { DataType.FLOAT -> when(sourceDt) {
DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_F) DataType.UBYTE -> prog.instr(Opcode.CAST_UB_TO_F)
@ -2222,9 +2222,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_F) DataType.UWORD -> prog.instr(Opcode.CAST_UW_TO_F)
DataType.WORD -> prog.instr(Opcode.CAST_W_TO_F) DataType.WORD -> prog.instr(Opcode.CAST_W_TO_F)
DataType.FLOAT -> {} DataType.FLOAT -> {}
else -> throw CompilerException("invalid cast type $sourceDt") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
else -> throw CompilerException("can't typecast to ${expr.type}") else -> throw CompilerException("invalid cast $sourceDt to ${expr.type} -- should be an Ast check")
} }
} }

View File

@ -3,7 +3,6 @@ package prog8.compiler.intermediate
import prog8.ast.* import prog8.ast.*
import java.lang.Exception import java.lang.Exception
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.floor
import kotlin.math.pow import kotlin.math.pow
@ -414,7 +413,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, numericValue()) DataType.UWORD -> Value(DataType.UWORD, numericValue())
DataType.WORD -> Value(DataType.WORD, numericValue()) DataType.WORD -> Value(DataType.WORD, numericValue())
DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }
DataType.BYTE -> { DataType.BYTE -> {
@ -424,7 +423,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535) DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535)
DataType.WORD -> Value(DataType.WORD, integerValue()) DataType.WORD -> Value(DataType.WORD, integerValue())
DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }
DataType.UWORD -> { DataType.UWORD -> {
@ -438,7 +437,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
Value(DataType.WORD, -(65536-integerValue())) Value(DataType.WORD, -(65536-integerValue()))
} }
DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }
DataType.WORD -> { DataType.WORD -> {
@ -447,7 +446,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535) DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535)
DataType.WORD -> this DataType.WORD -> this
DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue())
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }
DataType.FLOAT -> { DataType.FLOAT -> {
@ -457,7 +456,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
if(integer in -128..127) if(integer in -128..127)
Value(DataType.BYTE, integer) Value(DataType.BYTE, integer)
else else
TODO("overflow when casting float to byte: $this - should be an ast-check") throw ValueException("overflow when casting float to byte: $this")
} }
DataType.UBYTE -> Value(DataType.UBYTE, numericValue().toInt() and 255) DataType.UBYTE -> Value(DataType.UBYTE, numericValue().toInt() and 255)
DataType.UWORD -> Value(DataType.UWORD, numericValue().toInt() and 65535) DataType.UWORD -> Value(DataType.UWORD, numericValue().toInt() and 65535)
@ -466,13 +465,13 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) {
if(integer in -32768..32767) if(integer in -32768..32767)
Value(DataType.WORD, integer) Value(DataType.WORD, integer)
else else
TODO("overflow when casting float to word: $this - should be an ast-check") throw ValueException("overflow when casting float to word: $this")
} }
DataType.FLOAT -> this DataType.FLOAT -> this
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }
else -> TODO("invalid type cast from $type to $targetType - should be an ast-check") else -> throw ValueException("invalid type cast from $type to $targetType")
} }
} }

View File

@ -5,80 +5,39 @@
sub start() { sub start() {
while(true) ubyte ub
A++ byte b
word w
uword uw
repeat A++ until(false) ubyte[2] uba
byte[2] ba
word[2] wa
uword[2] uwa
str s
str_p sp
str_s ss
str_ps sps
s = ub as str
sp = ub as str_p
ss = ub as str_s
sps = ub as str_ps
s = b as str
sp = b as str_p
ss = b as str_s
sps = b as str_ps
s = w as str
sp = w as str_p
ss = w as str_s
sps = w as str_ps
s = uw as str
sp = uw as str_p
ss = uw as str_s
sps = uw as str_ps
for ubyte i in 0 to 10
A++
; c64scr.print_ub(c64utils.str2ubyte("1"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("12"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("123"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("1234"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("12xyz"))
; c64.CHROUT('\n')
; c64.CHROUT('\n')
;
; c64scr.print_ub(c64utils.str2ubyte("19"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("199"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("29"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("99xyz"))
; c64.CHROUT('\n')
; c64scr.print_ub(c64utils.str2ubyte("199xyz"))
; c64.CHROUT('\n')
; c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("1"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("12"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("123"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("1234"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2ubyte("12xyz"))
c64.CHROUT('\n')
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("19"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("29"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("199"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("299"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2ubyte("99zzxyz"))
c64.CHROUT('\n')
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("-9"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("-99"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("-199"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("-1111"))
c64.CHROUT('\n')
c64scr.print_b(c64utils.str2byte("-12xyz"))
c64.CHROUT('\n')
}
sub foo(ubyte param1, ubyte param2) {
ubyte local1
} }
} }