mirror of
https://github.com/irmen/prog8.git
synced 2025-02-24 13:29:10 +00:00
no operand swap on logical expressions with shortcircuit evaluation (and,or are no longer associative!)
This commit is contained in:
parent
592becc126
commit
ad4880997a
5
.github/workflows/all-ci.yml
vendored
5
.github/workflows/all-ci.yml
vendored
@ -35,9 +35,11 @@ jobs:
|
||||
name: prog8-compiler-jar-zipped
|
||||
path: compiler/build/libs/*-all.jar
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Calculate hash
|
||||
uses: MCJack123/ghaction-generate-release-hashes@v4
|
||||
if: "github.event_name == 'release'"
|
||||
with:
|
||||
get-assets: true
|
||||
hash-type: sha256
|
||||
@ -45,7 +47,6 @@ jobs:
|
||||
|
||||
- name: Upload hashes
|
||||
uses: actions/upload-artifact@v4
|
||||
if: "github.event_name == 'release'"
|
||||
with:
|
||||
name: Artifact Hashes
|
||||
path: hashes.txt
|
||||
|
@ -1,6 +1,6 @@
|
||||
package prog8.code.core
|
||||
|
||||
val AssociativeOperators = setOf("+", "*", "&", "|", "^", "==", "!=", "and", "or", "xor")
|
||||
val AssociativeOperators = setOf("+", "*", "&", "|", "^", "==", "!=", "xor") // note: and,or are no longer associative because of Shortcircuit/McCarthy evaluation
|
||||
val ComparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
||||
val LogicalOperators = setOf("and", "or", "xor", "not", "in")
|
||||
val BitwiseOperators = setOf("&", "|", "^", "~")
|
||||
|
@ -4,7 +4,6 @@ import prog8.ast.*
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.AnonymousScope
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.IfElse
|
||||
import prog8.ast.statements.Jump
|
||||
import prog8.ast.walk.AstWalker
|
||||
@ -109,12 +108,6 @@ class ExpressionSimplifier(private val program: Program, private val options: Co
|
||||
if (!leftIDt.isKnown || !rightIDt.isKnown)
|
||||
throw FatalAstException("can't determine datatype of both expression operands $expr")
|
||||
|
||||
// NonBinaryExpression <associativeoperator> BinaryExpression --> BinaryExpression <associativeoperator> NonBinaryExpression
|
||||
if (expr.operator in AssociativeOperators && expr.left !is BinaryExpression && expr.right is BinaryExpression) {
|
||||
if(parent !is Assignment || !(expr.left isSameAs parent.target) && maySwapOperandOrder(expr))
|
||||
return listOf(IAstModification.SwapOperands(expr))
|
||||
}
|
||||
|
||||
// X + (-A) --> X - A
|
||||
if (expr.operator == "+" && (expr.right as? PrefixExpression)?.operator == "-") {
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
|
@ -935,4 +935,41 @@ main {
|
||||
funcarg3.target.nameInSource shouldBe listOf("msb")
|
||||
funcarg3.args.single() shouldBe instanceOf<BinaryExpression>()
|
||||
}
|
||||
|
||||
test("no operand swap on logical expressions with shortcircuit evaluation") {
|
||||
val src="""
|
||||
%import diskio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
str scanline_buf = "?"* 20
|
||||
|
||||
sub start() {
|
||||
if diskio.f_open("test.prg") and diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
|
||||
if diskio.f_open("test.prg") or diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
|
||||
if diskio.f_open("test.prg") xor diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
}
|
||||
}"""
|
||||
val result = compileText(Cx16Target(), true, src, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 3
|
||||
val ifCond1 = (st[0] as IfElse).condition as BinaryExpression
|
||||
val ifCond2 = (st[1] as IfElse).condition as BinaryExpression
|
||||
val ifCond3 = (st[2] as IfElse).condition as BinaryExpression
|
||||
(ifCond1.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_open")
|
||||
(ifCond2.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_open")
|
||||
(ifCond3.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_open")
|
||||
val right1 = ifCond1.right as BinaryExpression
|
||||
val right2 = ifCond2.right as BinaryExpression
|
||||
val right3 = ifCond3.right as BinaryExpression
|
||||
(right1.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_read")
|
||||
(right2.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_read")
|
||||
(right3.left as FunctionCallExpression).target.nameInSource shouldBe listOf("diskio", "f_read")
|
||||
}
|
||||
})
|
||||
|
@ -1,78 +1,18 @@
|
||||
%import textio
|
||||
%import string
|
||||
%import diskio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
str name = "irmen@de@jong"
|
||||
cx16.r0L = findstr(name, "de-")
|
||||
if_cs {
|
||||
txt.print("found1. error. ")
|
||||
} else {
|
||||
txt.print("not found1. ok ")
|
||||
}
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
cx16.r0L = findstr(name, "de@")
|
||||
if_cs {
|
||||
txt.print("found2 (6?). ")
|
||||
} else {
|
||||
txt.print("not found2. error ")
|
||||
}
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
cx16.r0L = findstr(name, "irmen@de@jong")
|
||||
if_cs {
|
||||
txt.print("found3 (0?). ")
|
||||
} else {
|
||||
txt.print("not found3. error ")
|
||||
}
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
cx16.r0L = findstr(name, "irmen@de@jong1")
|
||||
if_cs {
|
||||
txt.print("found4. error. ")
|
||||
} else {
|
||||
txt.print("not found4. ok ")
|
||||
}
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
cx16.r0L = findstr(name, "jong")
|
||||
if_cs {
|
||||
txt.print("found5 (9?). ")
|
||||
} else {
|
||||
txt.print("not found5. error ")
|
||||
}
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
}
|
||||
str scanline_buf = "?"* 20
|
||||
|
||||
sub findstr(str haystack, str needle) -> ubyte {
|
||||
; searches for needle in haystack.
|
||||
; returns index in haystack where it first occurs, and Carry set,
|
||||
; or if needle doesn't occur in haystack it returns Carry clear and 255 (an invalid index.)
|
||||
txt.print_uwhex(haystack, true)
|
||||
txt.spc()
|
||||
txt.print(haystack)
|
||||
txt.nl()
|
||||
cx16.r2L = string.length(haystack)
|
||||
cx16.r3L = string.length(needle)
|
||||
if cx16.r3L <= cx16.r2L {
|
||||
cx16.r2L = cx16.r2L-cx16.r3L+1
|
||||
repeat cx16.r2L {
|
||||
if string.startswith(haystack, needle) {
|
||||
sys.set_carry()
|
||||
return 13 as ubyte
|
||||
}
|
||||
haystack++
|
||||
}
|
||||
}
|
||||
sys.clear_carry()
|
||||
return 255
|
||||
sub start() {
|
||||
if diskio.f_open("test.prg") and diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
|
||||
if diskio.f_open("test.prg") or diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
|
||||
if diskio.f_open("test.prg") xor diskio.f_read(scanline_buf, 2)==2
|
||||
cx16.r0++
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user