give an error when initializing an integer var with a float value instead of silently rounding

This commit is contained in:
Irmen de Jong 2021-11-18 01:56:11 +01:00
parent fa11a6e18b
commit 8f379e2262
4 changed files with 22 additions and 12 deletions

View File

@ -24,11 +24,16 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err
try {
val declConstValue = decl.value?.constValue(program)
if(declConstValue!=null && (decl.type==VarDeclType.VAR || decl.type==VarDeclType.CONST)
&& declConstValue.inferType(program) isnot decl.datatype) {
// cast the numeric literal to the appropriate datatype of the variable
val cast = declConstValue.cast(decl.datatype)
if(cast.isValid)
return listOf(IAstModification.ReplaceNode(decl.value!!, cast.valueOrZero(), decl))
&& declConstValue.type != decl.datatype) {
// avoid silent float roundings
if(decl.datatype in IntegerDatatypes && declConstValue.type==DataType.FLOAT) {
errors.err("refused silent rounding of float to avoid loss of precision", decl.value!!.position)
} else {
// cast the numeric literal to the appropriate datatype of the variable
val cast = declConstValue.cast(decl.datatype)
if (cast.isValid)
return listOf(IAstModification.ReplaceNode(decl.value!!, cast.valueOrZero(), decl))
}
}
} catch (x: UndefinedSymbolError) {
errors.err(x.message, x.position)

View File

@ -388,7 +388,16 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed
numbervalue: Double, // can be byte, word or float depending on the type
override val position: Position) : Expression() {
override lateinit var parent: Node
val number: Double = if(type==DataType.FLOAT) numbervalue else round(numbervalue)
val number: Double by lazy {
if(type==DataType.FLOAT)
numbervalue
else {
val rounded = round(numbervalue)
if(rounded != numbervalue)
throw ExpressionError("refused silent rounding of float to avoid loss of precision", position)
rounded
}
}
override val isSimple = true
override fun copy() = NumericLiteralValue(type, number, position)

View File

@ -9,9 +9,6 @@ optimize TODO in "Add assignment to initialize with zero" in StatementReorderer
optimize TODO in after(assignment) in VariousCleanups
optimize: bitwise operations with a negative constant number -> replace the number by its positive 2 complement
optimize: add some more constant folders mentioned in test.p8
fix: give error when initializing an integer var with a float value
optimize: there is an optimizations in AsmOptimizer that can only be done correctly
if it knows about regular ram vs io space ram distinction.

View File

@ -5,13 +5,12 @@ main {
sub start() {
ubyte xx = 1.234
ubyte yy = 2.234
ubyte xx = 1
ubyte yy = 2
uword aw
byte bb
float fl
; TODO add these constant folders:
; (X + C1) + (Y + C2) => (X + Y) + (C1 + C2)