slightly improved warning about implicit float casts

This commit is contained in:
Irmen de Jong 2019-07-01 18:43:39 +02:00
parent 49eb7e7803
commit 3242495b0b
5 changed files with 29 additions and 32 deletions

View File

@ -119,6 +119,7 @@ val ArrayElementTypes = mapOf(
DataType.ARRAY_UW to DataType.UWORD,
DataType.ARRAY_F to DataType.FLOAT)
class FatalAstException (override var message: String) : Exception(message)
open class AstException (override var message: String) : Exception(message)
@ -1105,8 +1106,6 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
// word + word -> word
// a combination with a float will be float (but give a warning about this!)
val floatWarning = "byte or word value implicitly converted to float. Suggestion: use explicit cast as float, a float number, or revert to integer arithmetic"
if(this.operator=="/") {
// division is a bit weird, don't cast the operands
val commondt = divisionOpDt(leftDt, rightDt)
@ -1120,10 +1119,7 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
DataType.BYTE -> Pair(DataType.BYTE, left)
DataType.UWORD -> Pair(DataType.UWORD, left)
DataType.WORD -> Pair(DataType.WORD, left)
DataType.FLOAT -> {
printWarning(floatWarning, left.position)
Pair(DataType.FLOAT, left)
}
DataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> throw FatalAstException("non-numeric datatype $rightDt")
}
}
@ -1133,10 +1129,7 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
DataType.BYTE -> Pair(DataType.BYTE, null)
DataType.UWORD -> Pair(DataType.WORD, left)
DataType.WORD -> Pair(DataType.WORD, left)
DataType.FLOAT -> {
printWarning(floatWarning, left.position)
Pair(DataType.FLOAT, left)
}
DataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> throw FatalAstException("non-numeric datatype $rightDt")
}
}
@ -1146,10 +1139,7 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
DataType.BYTE -> Pair(DataType.UWORD, right)
DataType.UWORD -> Pair(DataType.UWORD, null)
DataType.WORD -> Pair(DataType.WORD, left)
DataType.FLOAT -> {
printWarning(floatWarning, left.position)
Pair(DataType.FLOAT, left)
}
DataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> throw FatalAstException("non-numeric datatype $rightDt")
}
}
@ -1159,16 +1149,11 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
DataType.BYTE -> Pair(DataType.WORD, right)
DataType.UWORD -> Pair(DataType.WORD, right)
DataType.WORD -> Pair(DataType.WORD, null)
DataType.FLOAT -> {
printWarning(floatWarning, left.position)
Pair(DataType.FLOAT, left)
}
DataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> throw FatalAstException("non-numeric datatype $rightDt")
}
}
DataType.FLOAT -> {
if (rightDt != DataType.FLOAT)
printWarning(floatWarning, left.position)
Pair(DataType.FLOAT, right)
}
else -> throw FatalAstException("non-numeric datatype $leftDt")
@ -1213,7 +1198,7 @@ class ArrayIndexedExpression(val identifier: IdentifierReference,
}
class TypecastExpression(var expression: IExpression, var type: DataType, override val position: Position) : IExpression {
class TypecastExpression(var expression: IExpression, var type: DataType, val implicit: Boolean, override val position: Position) : IExpression {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -2483,7 +2468,7 @@ private fun prog8Parser.ExpressionContext.toAst() : IExpression {
return arrayindexed().toAst()
if(typecast()!=null)
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), toPosition())
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), false, toPosition())
if(directmemory()!=null)
return DirectMemoryRead(directmemory().expression().toAst(), toPosition())

View File

@ -499,7 +499,7 @@ private class AstChecker(private val program: Program,
}
// FLOATS
if(!compilerOptions.floats && decl.datatype==DataType.FLOAT && decl.type!=VarDeclType.MEMORY) {
if(!compilerOptions.floats && decl.datatype in setOf(DataType.FLOAT, DataType.ARRAY_F) && decl.type!=VarDeclType.MEMORY) {
checkResult.add(SyntaxError("floating point used, but that is not enabled via options", decl.position))
}
@ -681,7 +681,7 @@ private class AstChecker(private val program: Program,
}
override fun process(literalValue: LiteralValue): LiteralValue {
if(!compilerOptions.floats && literalValue.type==DataType.FLOAT) {
if(!compilerOptions.floats && literalValue.type in setOf(DataType.FLOAT, DataType.ARRAY_F)) {
checkResult.add(SyntaxError("floating point used, but that is not enabled via options", literalValue.position))
}
val arrayspec =

View File

@ -79,7 +79,7 @@ private class AstIdentifiersChecker(private val namespace: INameScope) : IAstPro
override fun process(functionCall: FunctionCall): IExpression {
if(functionCall.target.nameInSource.size==1 && functionCall.target.nameInSource[0]=="lsb") {
// lsb(...) is just an alias for type cast to ubyte, so replace with "... as ubyte"
val typecast = TypecastExpression(functionCall.arglist.single(), DataType.UBYTE, functionCall.position)
val typecast = TypecastExpression(functionCall.arglist.single(), DataType.UBYTE, false, functionCall.position)
typecast.linkParents(functionCall.parent)
return super.process(typecast)
}

View File

@ -170,11 +170,11 @@ private class StatementReorderer(private val program: Program): IAstProcessor {
if(toFix!=null) {
when {
toFix===expr.left -> {
expr.left = TypecastExpression(expr.left, commonDt, expr.left.position)
expr.left = TypecastExpression(expr.left, commonDt, true, expr.left.position)
expr.left.linkParents(expr)
}
toFix===expr.right -> {
expr.right = TypecastExpression(expr.right, commonDt, expr.right.position)
expr.right = TypecastExpression(expr.right, commonDt, true, expr.right.position)
expr.right.linkParents(expr)
}
else -> throw FatalAstException("confused binary expression side")
@ -215,7 +215,7 @@ private class StatementReorderer(private val program: Program): IAstProcessor {
val targettype = target.inferType(program, assignment)
if(targettype!=null && valuetype!=null && valuetype!=targettype) {
if(valuetype isAssignableTo targettype) {
assignment.value = TypecastExpression(assignment.value, targettype, assignment.value.position)
assignment.value = TypecastExpression(assignment.value, targettype, true, assignment.value.position)
assignment.value.linkParents(assignment)
}
// if they're not assignable, we'll get a proper error later from the AstChecker
@ -246,7 +246,7 @@ private class StatementReorderer(private val program: Program): IAstProcessor {
val requiredType = arg.first.type
if (requiredType != argtype) {
if (argtype isAssignableTo requiredType) {
val typecasted = TypecastExpression(arg.second.value, requiredType, arg.second.value.position)
val typecasted = TypecastExpression(arg.second.value, requiredType, true, arg.second.value.position)
typecasted.linkParents(arg.second.value.parent)
call.arglist[arg.second.index] = typecasted
}
@ -267,7 +267,7 @@ private class StatementReorderer(private val program: Program): IAstProcessor {
continue
for (possibleType in arg.first.possibleDatatypes) {
if (argtype isAssignableTo possibleType) {
val typecasted = TypecastExpression(arg.second.value, possibleType, arg.second.value.position)
val typecasted = TypecastExpression(arg.second.value, possibleType, true, arg.second.value.position)
typecasted.linkParents(arg.second.value.parent)
call.arglist[arg.second.index] = typecasted
break
@ -304,6 +304,13 @@ private class StatementReorderer(private val program: Program): IAstProcessor {
return Pair(sorted, trailing)
}
override fun process(typecast: TypecastExpression): IExpression {
// warn about any implicit type casts to Float, because that may not be intended
if(typecast.implicit && typecast.type in setOf(DataType.FLOAT, DataType.ARRAY_F)) {
printWarning("byte or word value implicitly converted to float. Suggestion: use explicit cast as float, a float number, or revert to integer arithmetic", typecast.position)
}
return super.process(typecast)
}
}

View File

@ -1,13 +1,18 @@
;%import c64utils
;%zeropage basicsafe
;%import c64flt
%import c64flt
~ main {
sub start() {
float[] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
;float[] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
float x
float z = sin(x) * 3
;ubyte bb = len(xcoor)
; storage for rotated coordinates
; ubyte[len(xcoor)] xx = 2