mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
improved bool type checking
This commit is contained in:
parent
d2d08bf143
commit
211e2bb37a
@ -80,10 +80,11 @@ internal class AstChecker(private val program: Program,
|
||||
} else {
|
||||
if (expectedReturnValues[0] != valueDt.getOr(DataType.UNDEFINED)) {
|
||||
if(valueDt istype DataType.BOOL && expectedReturnValues[0] == DataType.UBYTE) {
|
||||
// if the return value is a bool and the return type is ubyte, allow this.
|
||||
// if the return value is a bool and the return type is ubyte, allow this. But give a warning.
|
||||
errors.warn("return type of the subroutine should probably be bool instead of ubyte", returnStmt.position)
|
||||
} else if(valueDt istype DataType.UBYTE && expectedReturnValues[0] == DataType.BOOL) {
|
||||
// if the return value is ubyte and the return type is bool, allow this only if value is 0 or 1
|
||||
val returnValue = returnStmt.value?.constValue(program)
|
||||
val returnValue = returnStmt.value as? NumericLiteral
|
||||
if (returnValue == null || returnValue.type != DataType.UBYTE || (returnValue.number!=0.0 && returnValue.number!=1.0)) {
|
||||
errors.err("type $valueDt of return value doesn't match subroutine's return type ${expectedReturnValues[0]}",returnStmt.value!!.position)
|
||||
}
|
||||
|
@ -185,16 +185,6 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
|
||||
val leftDt = left.inferType(program)
|
||||
val rightDt = right.inferType(program)
|
||||
|
||||
fun dynamicBooleanType(): InferredTypes.InferredType {
|
||||
// as a special case, an expression yielding a boolean result, adapts the result
|
||||
// type to what is required (byte or word), to avoid useless type casting
|
||||
return when (parent) {
|
||||
is TypecastExpression -> InferredTypes.InferredType.known((parent as TypecastExpression).type)
|
||||
is Assignment -> (parent as Assignment).target.inferType(program)
|
||||
else -> InferredTypes.InferredType.known(DataType.BOOL)
|
||||
}
|
||||
}
|
||||
|
||||
return when (operator) {
|
||||
"+", "-", "*", "%", "/" -> {
|
||||
if (!leftDt.isKnown || !rightDt.isKnown)
|
||||
@ -214,10 +204,10 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
|
||||
}
|
||||
}
|
||||
"&", "|", "^" -> if(leftDt istype DataType.BOOL) InferredTypes.knownFor(DataType.UBYTE) else leftDt
|
||||
"and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.UBYTE) // note: don't use BOOL type here to avoid type errors later! Will be replaced anyway.
|
||||
"and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.BOOL)
|
||||
"<", ">",
|
||||
"<=", ">=",
|
||||
"==", "!=", "in" -> dynamicBooleanType()
|
||||
"==", "!=", "in" -> InferredTypes.knownFor(DataType.BOOL)
|
||||
"<<", ">>" -> leftDt
|
||||
else -> throw FatalAstException("resulting datatype check for invalid operator $operator")
|
||||
}
|
||||
|
@ -10,8 +10,9 @@ main {
|
||||
return key=='a'
|
||||
}
|
||||
|
||||
|
||||
sub func2() -> bool {
|
||||
return key=='z'
|
||||
return key==2
|
||||
}
|
||||
|
||||
sub start() {
|
||||
|
Loading…
Reference in New Issue
Block a user