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 (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.
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" -> "^"
else -> "invalid"
}
return listOf(
IAstModification.ReplaceNodeSafe(expr.left, wrapWithBooleanCastIfNeeded(expr.left), expr),
IAstModification.ReplaceNodeSafe(expr.right, wrapWithBooleanCastIfNeeded(expr.right), expr),)
val mods = mutableListOf<IAstModification>()
val newLeft = wrapWithBooleanCastIfNeeded(expr.left, program)
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
}
}
private fun wrapWithBooleanCastIfNeeded(expr: Expression): Expression {
internal fun wrapWithBooleanCastIfNeeded(expr: Expression, program: Program): Expression? {
fun isBoolean(expr: Expression): Boolean {
return if(expr.inferType(program) istype DataType.BOOL)
true
@ -109,8 +115,7 @@ internal class BoolRemover(val program: Program) : AstWalker() {
}
return if(isBoolean(expr))
expr
null
else
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 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
if(leftDt istype DataType.BOOL && rightDt.isBytes && !rightDt.istype(DataType.BOOL)) {
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 noModifications
}

View File

@ -3,9 +3,6 @@ TODO
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 {
sub start() {
bool bb2=true
bool @shared bb = bb2 and true
txt.print_ub(bb)
ubyte value1 = %1110
ubyte value2 = %1111
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!")
}
}