This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-govaluate.git


The following commit(s) were added to refs/heads/master by this push:
     new afacb06  feat: give bitwise AND, XOR and OR separate precedence levels
afacb06 is described below

commit afacb061ca363eceb3f0024d3d2e160c7eb8c9d8
Author: Yang Luo <[email protected]>
AuthorDate: Tue Oct 20 22:07:48 2026 +0800

    feat: give bitwise AND, XOR and OR separate precedence levels
---
 OperatorSymbol.go  | 22 +++++++++++++++-------
 evaluation_test.go | 20 ++++++++++++++++++++
 stagePlanner.go    | 22 ++++++++++++++++++----
 3 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/OperatorSymbol.go b/OperatorSymbol.go
index fcebe33..04d9874 100644
--- a/OperatorSymbol.go
+++ b/OperatorSymbol.go
@@ -56,7 +56,9 @@ const (
        prefixPrecedence
        exponentialPrecedence
        additivePrecedence
-       bitwisePrecedence
+       bitwiseAndPrecedence
+       bitwiseXorPrecedence
+       bitwiseOrPrecedence
        bitwiseShiftPrecedence
        multiplicativePrecedence
        comparatorPrecedence
@@ -96,11 +98,11 @@ func findOperatorPrecedenceForSymbol(symbol OperatorSymbol) 
operatorPrecedence {
        case OR:
                return logicalOrPrecedence
        case BITWISE_AND:
-               fallthrough
-       case BITWISE_OR:
-               fallthrough
+               return bitwiseAndPrecedence
        case BITWISE_XOR:
-               return bitwisePrecedence
+               return bitwiseXorPrecedence
+       case BITWISE_OR:
+               return bitwiseOrPrecedence
        case BITWISE_LSHIFT:
                fallthrough
        case BITWISE_RSHIFT:
@@ -162,9 +164,15 @@ var logicalSymbols = map[string]OperatorSymbol{
        "||": OR,
 }
 
-var bitwiseSymbols = map[string]OperatorSymbol{
-       "^": BITWISE_XOR,
+var bitwiseAndSymbols = map[string]OperatorSymbol{
        "&": BITWISE_AND,
+}
+
+var bitwiseXorSymbols = map[string]OperatorSymbol{
+       "^": BITWISE_XOR,
+}
+
+var bitwiseOrSymbols = map[string]OperatorSymbol{
        "|": BITWISE_OR,
 }
 
diff --git a/evaluation_test.go b/evaluation_test.go
index d2a5fad..39e2dc1 100644
--- a/evaluation_test.go
+++ b/evaluation_test.go
@@ -249,6 +249,26 @@ func TestNoParameterEvaluation(test *testing.T) {
                        Input:    "90 & 50 << 1",
                        Expected: 64.0,
                },
+               {
+                       Name:     "Bitwise AND precedence over OR",
+                       Input:    "1 | 2 & 4",
+                       Expected: 1.0,
+               },
+               {
+                       Name:     "Bitwise AND precedence over XOR",
+                       Input:    "6 ^ 3 & 1",
+                       Expected: 7.0,
+               },
+               {
+                       Name:     "Bitwise XOR precedence over OR",
+                       Input:    "1 | 1 ^ 1",
+                       Expected: 1.0,
+               },
+               {
+                       Name:     "Bitwise precedence mixed",
+                       Input:    "4 & 6 | 1 ^ 3 & 2",
+                       Expected: 7.0,
+               },
                {
                        Name:     "Bit shift precedence amongst non-bitwise",
                        Input:    "90 + 50 << 1 * 5",
diff --git a/stagePlanner.go b/stagePlanner.go
index 770af5a..71ed0da 100644
--- a/stagePlanner.go
+++ b/stagePlanner.go
@@ -64,7 +64,9 @@ var planPrefix precedent
 var planExponential precedent
 var planMultiplicative precedent
 var planAdditive precedent
-var planBitwise precedent
+var planBitwiseAnd precedent
+var planBitwiseXor precedent
+var planBitwiseOr precedent
 var planShift precedent
 var planComparator precedent
 var planLogicalAnd precedent
@@ -107,17 +109,29 @@ func init() {
                typeErrorFormat: modifierErrorFormat,
                next:            planAdditive,
        })
-       planBitwise = makePrecedentFromPlanner(&precedencePlanner{
-               validSymbols:    bitwiseSymbols,
+       planBitwiseAnd = makePrecedentFromPlanner(&precedencePlanner{
+               validSymbols:    bitwiseAndSymbols,
                validKinds:      []TokenKind{MODIFIER},
                typeErrorFormat: modifierErrorFormat,
                next:            planShift,
        })
+       planBitwiseXor = makePrecedentFromPlanner(&precedencePlanner{
+               validSymbols:    bitwiseXorSymbols,
+               validKinds:      []TokenKind{MODIFIER},
+               typeErrorFormat: modifierErrorFormat,
+               next:            planBitwiseAnd,
+       })
+       planBitwiseOr = makePrecedentFromPlanner(&precedencePlanner{
+               validSymbols:    bitwiseOrSymbols,
+               validKinds:      []TokenKind{MODIFIER},
+               typeErrorFormat: modifierErrorFormat,
+               next:            planBitwiseXor,
+       })
        planComparator = makePrecedentFromPlanner(&precedencePlanner{
                validSymbols:    comparatorSymbols,
                validKinds:      []TokenKind{COMPARATOR},
                typeErrorFormat: comparatorErrorFormat,
-               next:            planBitwise,
+               next:            planBitwiseOr,
        })
        planLogicalAnd = makePrecedentFromPlanner(&precedencePlanner{
                validSymbols:    map[string]OperatorSymbol{"&&": AND},


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to