fix bug in evaluating logical expressions if one of the operands was not boolean 1 or 0

This commit is contained in:
Irmen de Jong 2021-02-14 18:24:31 +01:00
parent 62dda4d891
commit 1e3930aae2
4 changed files with 51 additions and 5 deletions

View File

@ -167,6 +167,38 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
else -> return noModifications
}
}
else if(expr.operator in logicalOperators) {
// make sure that logical expressions like "var and other-logical-expression
// is rewritten as "var!=0 and other-logical-expression", to avoid bitwise boolean and
// generating the wrong results later
fun wrapped(expr: Expression): Expression =
BinaryExpression(expr, "!=", NumericLiteralValue(DataType.UBYTE, 0, expr.position), expr.position)
fun isLogicalExpr(expr: Expression?): Boolean {
if(expr is BinaryExpression && expr.operator in (logicalOperators + comparisonOperators))
return true
if(expr is PrefixExpression && expr.operator in logicalOperators)
return true
return false
}
return if(isLogicalExpr(expr.left)) {
if(isLogicalExpr(expr.right))
noModifications
else
listOf(IAstModification.ReplaceNode(expr.right, wrapped(expr.right), expr))
} else {
if(isLogicalExpr(expr.right))
listOf(IAstModification.ReplaceNode(expr.left, wrapped(expr.left), expr))
else {
listOf(
IAstModification.ReplaceNode(expr.left, wrapped(expr.left), expr),
IAstModification.ReplaceNode(expr.right, wrapped(expr.right), expr)
)
}
}
}
return noModifications
}

View File

@ -13,6 +13,8 @@ import kotlin.math.abs
val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=")
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
val logicalOperators = setOf("and", "or", "xor", "not")
sealed class Expression: Node {
abstract fun constValue(program: Program): NumericLiteralValue?

View File

@ -2,6 +2,7 @@
TODO
====
- auto_heap_value for strings: avoid creating multiple values for identical strings (or fix it at the end)
- refactor the asmgen into their own submodule?
- refactor the compiler optimizers into their own submodule?
- optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))

View File

@ -9,14 +9,25 @@ main {
uword textptr = &text
ubyte nlen = conv.any2uword(textptr)
ubyte valid_operand = (nlen>0) and (@(textptr+nlen)==0)
ubyte lastchr = text[nlen]
ubyte valid_operand
valid_operand = nlen>0 and lastchr==0
txt.print("\nvalidoper? ")
txt.print_ub(valid_operand)
txt.nl()
valid_operand = nlen>0
valid_operand = valid_operand and lastchr==0
txt.print("\nvalidoper? ")
txt.print_ub(valid_operand)
txt.print("\nnlen=")
txt.print_ub(nlen)
txt.print("\nr15=")
txt.print_uwhex(cx16.r15, true)
txt.nl()
valid_operand = nlen and lastchr==0
txt.print("\nvalidoper? ")
txt.print_ub(valid_operand)
txt.nl()
}
}