From 1860f66de5224a5d26e55205a0a838d9356275c2 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 23 Dec 2022 17:54:09 +0100 Subject: [PATCH] allow "x not in array" as equivalent to "not x in array" update antlr parsing lib --- .idea/libraries/antlr_antlr4.xml | 10 +++---- compiler/build.gradle | 2 +- compiler/res/version.txt | 2 +- .../compiler/astprocessing/AstPreprocessor.kt | 5 ++++ compiler/test/ast/TestVarious.kt | 28 +++++++++++++++++-- compilerAst/build.gradle | 2 +- docs/source/todo.rst | 1 - parser/antlr/Prog8ANTLR.g4 | 1 + parser/build.gradle | 4 +-- 9 files changed, 41 insertions(+), 14 deletions(-) diff --git a/.idea/libraries/antlr_antlr4.xml b/.idea/libraries/antlr_antlr4.xml index e626486a2..237fa4297 100644 --- a/.idea/libraries/antlr_antlr4.xml +++ b/.idea/libraries/antlr_antlr4.xml @@ -1,17 +1,17 @@ - + - - + + - + - + diff --git a/compiler/build.gradle b/compiler/build.gradle index cc9d5ff23..2e894c158 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -34,7 +34,7 @@ dependencies { implementation project(':codeGenIntermediate') implementation project(':codeGenExperimental') implementation project(':virtualmachine') - implementation 'org.antlr:antlr4-runtime:4.10.1' + implementation 'org.antlr:antlr4-runtime:4.11.1' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" // implementation "org.jetbrains.kotlin:kotlin-reflect" implementation 'org.jetbrains.kotlinx:kotlinx-cli:0.3.4' diff --git a/compiler/res/version.txt b/compiler/res/version.txt index 43b158476..eec6dacbd 100644 --- a/compiler/res/version.txt +++ b/compiler/res/version.txt @@ -1 +1 @@ -8.8 +8.8.1 diff --git a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt index f07778178..df907eb04 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt @@ -145,6 +145,11 @@ class AstPreprocessor(val program: Program, val containment = ContainmentCheck(expr.left, expr.right, expr.position) return listOf(IAstModification.ReplaceNode(expr, containment, parent)) } + if(expr.operator=="not in") { + val containment = ContainmentCheck(expr.left, expr.right, expr.position) + val notContainment = PrefixExpression("not", containment, expr.position) + return listOf(IAstModification.ReplaceNode(expr, notContainment, parent)) + } return noModifications } diff --git a/compiler/test/ast/TestVarious.kt b/compiler/test/ast/TestVarious.kt index d0a1595c2..4bf9e9c04 100644 --- a/compiler/test/ast/TestVarious.kt +++ b/compiler/test/ast/TestVarious.kt @@ -3,10 +3,9 @@ package prog8tests.ast import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe +import io.kotest.matchers.types.instanceOf import prog8.ast.IFunctionCall -import prog8.ast.expressions.BinaryExpression -import prog8.ast.expressions.IdentifierReference -import prog8.ast.expressions.StringLiteral +import prog8.ast.expressions.* import prog8.ast.statements.Assignment import prog8.ast.statements.InlineAssembly import prog8.ast.statements.VarDecl @@ -179,5 +178,28 @@ main { val stmts = result.program.entrypoint.statements stmts.size shouldBe 9 } + + test("alternative notation for negative containment check") { + val src=""" +main { + sub start() { + ubyte[] array=[1,2,3] + cx16.r0L = not (3 in array) + cx16.r1L = 3 not in array + } +} +""" + val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!! + val stmts = result.program.entrypoint.statements + stmts.size shouldBe 3 + val value1 = (stmts[1] as Assignment).value as BinaryExpression + val value2 = (stmts[2] as Assignment).value as BinaryExpression + value1.operator shouldBe "==" + value1.left shouldBe instanceOf() + (value1.right as NumericLiteral).number shouldBe 0.0 + value2.operator shouldBe "==" + value2.left shouldBe instanceOf() + (value2.right as NumericLiteral).number shouldBe 0.0 + } }) diff --git a/compilerAst/build.gradle b/compilerAst/build.gradle index a722f55b2..ed0fa1da1 100644 --- a/compilerAst/build.gradle +++ b/compilerAst/build.gradle @@ -24,7 +24,7 @@ compileTestKotlin { dependencies { implementation project(':codeCore') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - implementation 'org.antlr:antlr4-runtime:4.10.1' + implementation 'org.antlr:antlr4-runtime:4.11.1' implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:1.1.16" implementation project(':parser') } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c40079012..cb8df04b0 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- allow "xx not in array" and rewrite it into "not xx in array" - make sure bool value is always 0 or 1 (all casts should convert), then: - rewrite bool=bool^1 into bool=not bool - should solve: bool bb = not bb -> larger code than bool bb ^= 1 diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index 846487bd8..e9ae0ca5f 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -170,6 +170,7 @@ expression : | left = expression EOL? bop = ('==' | '!=') EOL? right = expression | rangefrom = expression rto = ('to'|'downto') rangeto = expression ('step' rangestep = expression)? // can't create separate rule due to mutual left-recursion | left = expression EOL? bop = 'in' EOL? right = expression + | left = expression EOL? bop = 'not in' EOL? right = expression | prefix = 'not' expression | left = expression EOL? bop = 'and' EOL? right = expression | left = expression EOL? bop = 'or' EOL? right = expression diff --git a/parser/build.gradle b/parser/build.gradle index b2965aca7..8223de7de 100644 --- a/parser/build.gradle +++ b/parser/build.gradle @@ -10,8 +10,8 @@ java { } dependencies { - antlr 'org.antlr:antlr4:4.10.1' - implementation 'org.antlr:antlr4-runtime:4.10.1' + antlr 'org.antlr:antlr4:4.11.1' + implementation 'org.antlr:antlr4-runtime:4.11.1' } configurations.all {