mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
fix bug in evaluating logical expressions if one of the operands was not boolean 1 or 0
This commit is contained in:
parent
62dda4d891
commit
1e3930aae2
@ -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
|
||||
}
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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))
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user