mirror of
https://github.com/irmen/prog8.git
synced 2024-09-30 00:55:52 +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 -> 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
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ import kotlin.math.abs
|
|||||||
val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=")
|
val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=")
|
||||||
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
||||||
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
||||||
|
val logicalOperators = setOf("and", "or", "xor", "not")
|
||||||
|
|
||||||
|
|
||||||
sealed class Expression: Node {
|
sealed class Expression: Node {
|
||||||
abstract fun constValue(program: Program): NumericLiteralValue?
|
abstract fun constValue(program: Program): NumericLiteralValue?
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
TODO
|
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 asmgen into their own submodule?
|
||||||
- refactor the compiler optimizers 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))
|
- 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
|
uword textptr = &text
|
||||||
|
|
||||||
ubyte nlen = conv.any2uword(textptr)
|
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("\nvalidoper? ")
|
||||||
txt.print_ub(valid_operand)
|
txt.print_ub(valid_operand)
|
||||||
txt.print("\nnlen=")
|
txt.nl()
|
||||||
txt.print_ub(nlen)
|
|
||||||
txt.print("\nr15=")
|
|
||||||
txt.print_uwhex(cx16.r15, true)
|
valid_operand = nlen and lastchr==0
|
||||||
|
txt.print("\nvalidoper? ")
|
||||||
|
txt.print_ub(valid_operand)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user