mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +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 {
|
} else {
|
||||||
if (expectedReturnValues[0] != valueDt.getOr(DataType.UNDEFINED)) {
|
if (expectedReturnValues[0] != valueDt.getOr(DataType.UNDEFINED)) {
|
||||||
if(valueDt istype DataType.BOOL && expectedReturnValues[0] == DataType.UBYTE) {
|
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) {
|
} 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
|
// 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)) {
|
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)
|
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 leftDt = left.inferType(program)
|
||||||
val rightDt = right.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) {
|
return when (operator) {
|
||||||
"+", "-", "*", "%", "/" -> {
|
"+", "-", "*", "%", "/" -> {
|
||||||
if (!leftDt.isKnown || !rightDt.isKnown)
|
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
|
"&", "|", "^" -> 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
|
"<<", ">>" -> leftDt
|
||||||
else -> throw FatalAstException("resulting datatype check for invalid operator $operator")
|
else -> throw FatalAstException("resulting datatype check for invalid operator $operator")
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ main {
|
|||||||
return key=='a'
|
return key=='a'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub func2() -> bool {
|
sub func2() -> bool {
|
||||||
return key=='z'
|
return key==2
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
Loading…
Reference in New Issue
Block a user