improved De Morgan rewrite rules

This commit is contained in:
Irmen de Jong 2024-02-20 23:34:28 +01:00
parent 006713fe13
commit a5110b1f96
4 changed files with 32 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import prog8.ast.base.FatalAstException
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.NumericLiteral
import prog8.ast.expressions.PrefixExpression
import prog8.ast.expressions.invertCondition
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.core.*
@ -74,6 +75,22 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
}
}
}
// mixed cases
if(leftC!=null && rightP!=null && leftC.operator=="==" && rightP.operator=="not") {
// mixed case 1: x==V or not y -> not(x!=V and y)
val invertedLeftExpression = invertCondition(leftC, program)
val inner = BinaryExpression(invertedLeftExpression, newOper, rightP.expression, expr.position)
val notExpr = PrefixExpression("not", inner, expr.position)
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
}
else if(rightC!=null && leftP!=null && rightC.operator=="==" && leftP.operator=="not") {
// mixed case 1: not x or y==V -> not(x and y!=V)
val invertedRightExpression = invertCondition(rightC, program)
val inner = BinaryExpression(leftP.expression, newOper, invertedRightExpression, expr.position)
val notExpr = PrefixExpression("not", inner, expr.position)
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
}
}
return noModifications

View File

@ -782,17 +782,29 @@ main {
cx16.r0++
if not a1 and not a2
cx16.r0++
if cx16.r0L==42 or not a2
cx16.r0L++
if not a2 or cx16.r0L==42
cx16.r0L++
}
}"""
val result = compileText(Cx16Target(), true, src, writeAssembly = false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 6
st.size shouldBe 8
val if1c = (st[4] as IfElse).condition as PrefixExpression
val if2c = (st[5] as IfElse).condition as PrefixExpression
val if3c = (st[6] as IfElse).condition as PrefixExpression
val if4c = (st[7] as IfElse).condition as PrefixExpression
if1c.operator shouldBe "not"
if2c.operator shouldBe "not"
if3c.operator shouldBe "not"
if4c.operator shouldBe "not"
(if1c.expression as BinaryExpression).operator shouldBe "and"
(if2c.expression as BinaryExpression).operator shouldBe "or"
(if3c.expression as BinaryExpression).operator shouldBe "and"
(if4c.expression as BinaryExpression).operator shouldBe "and"
}
test("absorption laws") {

View File

@ -1,7 +1,6 @@
TODO
====
examples/maze is larger than on 10.1
rockrunner is a lot bigger still than on 10.1
paint is bigger than on 10.1

View File

@ -9,17 +9,11 @@ main {
word[4] words
byte @shared sbb
float @shared fl=3.3
float @shared fl2=4.3
sub start() {
; cx16.r0L = fl==fl2 as ubyte
; cx16.r1L = fl!=fl2 as ubyte
cx16.r0L = cx16.r0 == cx16.r1 as ubyte
cx16.r1L = cx16.r0 != cx16.r1 as ubyte
cx16.r0L = cx16.r0L == cx16.r1L as ubyte
cx16.r1L = cx16.r0L != cx16.r1L as ubyte
if cx16.r0 > cx16.r1
cx16.r0L++
; TODO all this for uwords