fixed 'not' operator priority: it now has higher priority as or/and/xor.

This commit is contained in:
Irmen de Jong 2021-11-08 18:38:04 +01:00
parent 2d1e5bbc7e
commit a9b0400d13
2 changed files with 34 additions and 5 deletions

View File

@ -14,10 +14,7 @@ import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.CharLiteral
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.expressions.RangeExpr
import prog8.ast.expressions.StringLiteralValue
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.parser.ParseError
import prog8.parser.Prog8Parser.parseModule
@ -625,4 +622,36 @@ class TestProg8Parser: FunSpec( {
val labels = start.statements.filterIsInstance<Label>()
labels.size shouldBe 1
}
test("logical operator 'not' priority") {
val src = SourceCode.Text("""
main {
sub start() {
ubyte xx
xx = not 4 and not 5
xx = not 4 or not 5
xx = not 4 xor not 5
}
}
""")
val module = parseModule(src)
val start = (module.statements.single() as Block).statements.single() as Subroutine
val andAssignmentExpr = (start.statements[1] as Assignment).value
val orAssignmentExpr = (start.statements[2] as Assignment).value
val xorAssignmentExpr = (start.statements[3] as Assignment).value
fun correctPrios(expr: Expression, operator: String) {
withClue("not should have higher prio as the other logical operators") {
expr shouldBe instanceOf<BinaryExpression>()
val binExpr = expr as BinaryExpression
binExpr.operator shouldBe operator
(binExpr.left as PrefixExpression).operator shouldBe "not"
(binExpr.right as PrefixExpression).operator shouldBe "not"
}
}
correctPrios(andAssignmentExpr, "and")
correctPrios(orAssignmentExpr, "or")
correctPrios(xorAssignmentExpr, "xor")
}
})

View File

@ -182,10 +182,10 @@ expression :
| left = expression EOL? bop = '|' EOL? right = 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
| prefix = 'not' expression
| left = expression EOL? bop = 'and' EOL? right = expression
| left = expression EOL? bop = 'or' EOL? right = expression
| left = expression EOL? bop = 'xor' EOL? right = expression
| prefix = 'not' expression
| literalvalue
| scoped_identifier
| arrayindexed