fixed missing non-boolean operand cast in logical expressions

This commit is contained in:
Irmen de Jong 2022-07-12 21:58:33 +02:00
parent f46e131f18
commit 10ddd5b127
5 changed files with 124 additions and 96 deletions

View File

@ -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)
} }
} }

View File

@ -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)
} }
}

View File

@ -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
} }

View File

@ -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)
... ...

View File

@ -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!")
} }
} }