// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operator-bitwise.go package expr import ( "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/scan" ) //-------- Bitwise NOT term func newBitwiseNotTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 1), Position: scan.PosPrefix, Priority: scan.PriBitwiseNot, EvalFunc: evalBitwiseNot, } } func evalBitwiseNot(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var value any if value, err = opTerm.EvalPrefix(ctx); err != nil { return } if kern.IsInteger(value) { i, _ := value.(int64) v = ^i } else { err = opTerm.ErrIncompatiblePrefixPostfixType(value) } return } //-------- Bitwise AND term func newBitwiseAndTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 2), Position: scan.PosInfix, Priority: scan.PriBitwiseAnd, EvalFunc: evalBitwiseAnd, } } func bitwiseAnd(opTerm *scan.Term, leftValue, rightValue any) (v any, err error) { var leftInt, rightInt int64 var lok, rok bool leftInt, lok = leftValue.(int64) rightInt, rok = rightValue.(int64) if lok && rok { v = leftInt & rightInt } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } return } func evalBitwiseAnd(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var leftValue, rightValue any if leftValue, rightValue, err = opTerm.EvalInfix(ctx); err != nil { return } v, err = bitwiseAnd(opTerm, leftValue, rightValue) return } //-------- Bitwise OR term func newBitwiseOrTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 2), Position: scan.PosInfix, Priority: scan.PriBitwiseOr, EvalFunc: evalBitwiseOr, } } func bitwiseOr(opTerm *scan.Term, leftValue, rightValue any) (v any, err error) { var leftInt, rightInt int64 var lok, rok bool leftInt, lok = leftValue.(int64) rightInt, rok = rightValue.(int64) if lok && rok { v = leftInt | rightInt } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } return } func evalBitwiseOr(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var leftValue, rightValue any if leftValue, rightValue, err = opTerm.EvalInfix(ctx); err != nil { return } v, err = bitwiseOr(opTerm, leftValue, rightValue) return } //-------- Bitwise XOR term func newBitwiseXorTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 2), Position: scan.PosInfix, Priority: scan.PriBitwiseXor, EvalFunc: evalBitwiseXor, } } func bitwiseXor(opTerm *scan.Term, leftValue, rightValue any) (v any, err error) { var leftInt, rightInt int64 var lok, rok bool leftInt, lok = leftValue.(int64) rightInt, rok = rightValue.(int64) if lok && rok { v = leftInt ^ rightInt } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } return } func evalBitwiseXor(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var leftValue, rightValue any if leftValue, rightValue, err = opTerm.EvalInfix(ctx); err != nil { return } v, err = bitwiseXor(opTerm, leftValue, rightValue) return } // init func init() { scan.RegisterTermConstructor(scan.SymTilde, newBitwiseNotTerm) scan.RegisterTermConstructor(scan.SymAmpersand, newBitwiseAndTerm) scan.RegisterTermConstructor(scan.SymVertBar, newBitwiseOrTerm) scan.RegisterTermConstructor(scan.SymCaret, newBitwiseXorTerm) }