mirror of
https://github.com/irmen/prog8.git
synced 2024-09-06 12:54:36 +00:00
fixed missing non-boolean operand cast in logical expressions
This commit is contained in:
parent
f46e131f18
commit
10ddd5b127
@ -913,7 +913,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(expr.operator !in ComparisonOperators) {
|
if(expr.operator !in ComparisonOperators) {
|
||||||
if (leftDt == DataType.STR && rightDt == DataType.STR || leftDt in ArrayDatatypes && rightDt in ArrayDatatypes) {
|
if (leftDt == DataType.STR && rightDt == DataType.STR || leftDt in ArrayDatatypes && rightDt in ArrayDatatypes) {
|
||||||
// str+str and str*number have already been const evaluated before we get here.
|
// str+str and str*number have already been const evaluated before we get here.
|
||||||
errors.err("no computational expressions with strings or arrays are possible", expr.position)
|
errors.err("no computational or logical expressions with strings or arrays are possible", expr.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,14 +82,20 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
|||||||
"xor" -> "^"
|
"xor" -> "^"
|
||||||
else -> "invalid"
|
else -> "invalid"
|
||||||
}
|
}
|
||||||
return listOf(
|
val mods = mutableListOf<IAstModification>()
|
||||||
IAstModification.ReplaceNodeSafe(expr.left, wrapWithBooleanCastIfNeeded(expr.left), expr),
|
val newLeft = wrapWithBooleanCastIfNeeded(expr.left, program)
|
||||||
IAstModification.ReplaceNodeSafe(expr.right, wrapWithBooleanCastIfNeeded(expr.right), expr),)
|
val newRight = wrapWithBooleanCastIfNeeded(expr.right, program)
|
||||||
|
if(newLeft!=null)
|
||||||
|
mods += IAstModification.ReplaceNodeSafe(expr.left, newLeft, expr)
|
||||||
|
if(newRight!=null)
|
||||||
|
mods += IAstModification.ReplaceNodeSafe(expr.right, newRight, expr)
|
||||||
|
return mods
|
||||||
}
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun wrapWithBooleanCastIfNeeded(expr: Expression): Expression {
|
internal fun wrapWithBooleanCastIfNeeded(expr: Expression, program: Program): Expression? {
|
||||||
fun isBoolean(expr: Expression): Boolean {
|
fun isBoolean(expr: Expression): Boolean {
|
||||||
return if(expr.inferType(program) istype DataType.BOOL)
|
return if(expr.inferType(program) istype DataType.BOOL)
|
||||||
true
|
true
|
||||||
@ -109,8 +115,7 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return if(isBoolean(expr))
|
return if(isBoolean(expr))
|
||||||
expr
|
null
|
||||||
else
|
else
|
||||||
TypecastExpression(expr, DataType.BOOL, true, expr.position)
|
TypecastExpression(expr, DataType.BOOL, true, expr.position)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,20 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
val leftCv = expr.left.constValue(program)
|
val leftCv = expr.left.constValue(program)
|
||||||
val rightCv = expr.right.constValue(program)
|
val rightCv = expr.right.constValue(program)
|
||||||
|
|
||||||
if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) {
|
if(leftDt.isKnown && rightDt.isKnown) {
|
||||||
|
if(expr.operator in LogicalOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||||
|
// see if any of the operands needs conversion to bool
|
||||||
|
val modifications = mutableListOf<IAstModification>()
|
||||||
|
val newLeft = wrapWithBooleanCastIfNeeded(expr.left, program)
|
||||||
|
val newRight = wrapWithBooleanCastIfNeeded(expr.right, program)
|
||||||
|
if(newLeft!=null)
|
||||||
|
modifications += IAstModification.ReplaceNode(expr.left, newLeft, expr)
|
||||||
|
if(newRight!=null)
|
||||||
|
modifications += IAstModification.ReplaceNode(expr.right, newRight, expr)
|
||||||
|
if(modifications.isNotEmpty())
|
||||||
|
return modifications
|
||||||
|
}
|
||||||
|
if(leftDt!=rightDt) {
|
||||||
// convert bool type to byte if needed
|
// convert bool type to byte if needed
|
||||||
if(leftDt istype DataType.BOOL && rightDt.isBytes && !rightDt.istype(DataType.BOOL)) {
|
if(leftDt istype DataType.BOOL && rightDt.isBytes && !rightDt.istype(DataType.BOOL)) {
|
||||||
if(rightCv==null || (rightCv.number!=1.0 && rightCv.number!=0.0))
|
if(rightCv==null || (rightCv.number!=1.0 && rightCv.number!=0.0))
|
||||||
@ -111,6 +123,8 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
return modifications
|
return modifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- fix compiler bug: tehtriz: blocks fall through the bottom
|
|
||||||
- fix compiler bug: maze: maze runner goes all wacky (both c64 and cx6)
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,8 +3,20 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
bool bb2=true
|
ubyte value1 = %1110
|
||||||
bool @shared bb = bb2 and true
|
ubyte value2 = %1111
|
||||||
txt.print_ub(bb)
|
|
||||||
|
bool[2] @shared barr = [true, false]
|
||||||
|
|
||||||
|
; if value1 and value2 ; TODO value1 isn't converted to bool in 6502 preprocess
|
||||||
|
; txt.print("ok")
|
||||||
|
; else
|
||||||
|
; txt.print("fail!")
|
||||||
|
; txt.nl()
|
||||||
|
|
||||||
|
if value1 and value2!=255 ; TODO value1 isn't converted to bool in 6502 preprocess
|
||||||
|
txt.print("ok")
|
||||||
|
else
|
||||||
|
txt.print("fail!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user