mirror of
https://github.com/irmen/prog8.git
synced 2025-03-14 11:34:32 +00:00
slightly improved warning about implicit float casts
This commit is contained in:
parent
49eb7e7803
commit
3242495b0b
@ -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())
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user