From b7279a3d9e5f218e4b426eaa3b13a7182b9667d4 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 19 Dec 2023 19:49:25 +0100 Subject: [PATCH] fix 'not in' parsing error fixes #115 --- compiler/test/ast/TestVariousCompilerAst.kt | 15 +++++++++++++++ compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt | 2 +- .../src/prog8/ast/expressions/AstExpressions.kt | 2 +- docs/source/todo.rst | 4 ++++ parser/antlr/Prog8ANTLR.g4 | 2 +- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index 77b73ddd4..f788a454d 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -440,5 +440,20 @@ main { forloop.body.statements[1] shouldBe instanceOf() forloop.body.statements[2] shouldBe instanceOf() } + + test("'not in' operator parsing") { + val src=""" +main { + sub start() { + str test = "test" + ubyte insync + if not insync + insync++ + if insync not in test + insync++ + } +}""" + compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null + } }) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index 83740418a..7e51cda2d 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -468,7 +468,7 @@ private fun ExpressionContext.toAst() : Expression { return scoped_identifier().toAst() if(bop!=null) - return BinaryExpression(left.toAst(), bop.text, right.toAst(), toPosition()) + return BinaryExpression(left.toAst(), bop.text.trim(), right.toAst(), toPosition()) if(prefix!=null) return PrefixExpression(prefix.text, expression(0).toAst(), toPosition()) diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 622995531..3f20683c1 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -219,7 +219,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex "and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.BOOL) "<", ">", "<=", ">=", - "==", "!=", "in" -> InferredTypes.knownFor(DataType.BOOL) + "==", "!=", "in", "not in" -> InferredTypes.knownFor(DataType.BOOL) "<<", ">>" -> leftDt else -> throw FatalAstException("resulting datatype check for invalid operator $operator") } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c69474009..58ffdf2ca 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,9 @@ TODO ==== +- fix the 'message' github compiler error (github) + + - verafx vram-vram copy routine? set the cache fill and cache write bits in fx ctrl, set one data port's increment to 1 and the other one to 4, Assuming your writes are aligned to 32-bit boundaries, do four reads from the increment-1 port @@ -87,5 +90,6 @@ Other language/syntax features to think about - add (rom/ram)bank support to romsub. A call will then automatically switch banks, use callfar and something else when in banked ram. challenges: how to not make this too X16 specific? How does the compiler know what bank to switch (ram/rom)? + How to make it performant when we want to (i.e. NOT have it use callfar/auto bank switching) ? - chained comparisons `10 x==true) - negative array index to refer to an element from the end of the array. Python `[-1]` or Raku syntax `[\*-1]` , `[\*/2]` .... \*=size of the array diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index 444adf0a7..c202dd092 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -178,7 +178,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 + | left = expression EOL? bop = ('not in ' | 'not in\t' | 'not in\n' | 'not in\r') EOL? right = expression | prefix = 'not' expression | left = expression EOL? bop = 'and' EOL? right = expression | left = expression EOL? bop = 'or' EOL? right = expression