// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operator-shift.go package expr import ( "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/scan" ) //-------- bit right shift term func newRightShiftTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 2), Position: scan.PosInfix, Priority: scan.PriBinShift, EvalFunc: evalRightShift, } } func bitRightShift(opTerm *scan.Term, leftValue, rightValue any) (v any, err error) { if kern.IsInteger(leftValue) && kern.IsInteger(rightValue) { leftInt := leftValue.(int64) rightInt := rightValue.(int64) v = leftInt >> rightInt } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } return } func evalRightShift(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 = bitRightShift(opTerm, leftValue, rightValue) return } func newLeftShiftTerm(tk *scan.Token) (inst *scan.Term) { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 2), Position: scan.PosInfix, Priority: scan.PriBinShift, EvalFunc: evalLeftShift, } } func bitLeftShift(opTerm *scan.Term, leftValue, rightValue any) (v any, err error) { if kern.IsInteger(leftValue) && kern.IsInteger(rightValue) { leftInt := leftValue.(int64) rightInt := rightValue.(int64) v = leftInt << rightInt } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } return } func evalLeftShift(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 = bitLeftShift(opTerm, leftValue, rightValue) return } // init func init() { scan.RegisterTermConstructor(scan.SymDoubleGreater, newRightShiftTerm) scan.RegisterTermConstructor(scan.SymDoubleLess, newLeftShiftTerm) }