mirror of
https://github.com/wader/fq.git
synced 2024-12-23 13:22:58 +03:00
be0ef80c8d
Uses same rule as jq math functions, 1 arg uses input, more than one all passed as args. So "bnot 1" -> "1 | bnot", "1 bsl 1" -> "bsl(1; 1)" Don't think it's worth changing the jq syntax for this and also it could make fq scripts no compatiblr with other jq tools. Non-10 base number literals are still allowed but should probably not be used in scripts, only in repl and with cli.
110 lines
4.4 KiB
Go
110 lines
4.4 KiB
Go
package interp
|
|
|
|
import (
|
|
"math/big"
|
|
|
|
"github.com/wader/fq/internal/gojqextra"
|
|
"github.com/wader/gojq"
|
|
)
|
|
|
|
func init() {
|
|
functionRegisterFns = append(functionRegisterFns, func(i *Interp) []Function {
|
|
return []Function{
|
|
{"bnot", 0, 0, i.bnot, nil},
|
|
{"bsl", 2, 2, i.bsl, nil},
|
|
{"bsr", 2, 2, i.bsr, nil},
|
|
{"band", 2, 2, i.band, nil},
|
|
{"bor", 2, 2, i.bor, nil},
|
|
{"bxor", 2, 2, i.bxor, nil},
|
|
}
|
|
})
|
|
}
|
|
|
|
func (i *Interp) bnot(c interface{}, a []interface{}) interface{} {
|
|
switch c := c.(type) {
|
|
case int:
|
|
return ^c
|
|
case *big.Int:
|
|
return new(big.Int).Not(c)
|
|
case gojq.JQValue:
|
|
return i.bnot(c.JQValueToGoJQ(), a)
|
|
default:
|
|
return &gojqextra.UnaryTypeError{Name: "bnot", V: c}
|
|
}
|
|
}
|
|
|
|
func (i *Interp) bsl(c interface{}, a []interface{}) interface{} {
|
|
return gojq.BinopTypeSwitch(a[0], a[1],
|
|
func(l, r int) bool { return false }, // TODO: can be int safe i think
|
|
func(l, r int) interface{} { return l << r },
|
|
func(l, r float64) interface{} { return int(l) << int(r) },
|
|
func(l, r *big.Int) interface{} { return new(big.Int).Lsh(l, uint(r.Uint64())) },
|
|
func(l, r string) interface{} { return &gojqextra.BinopTypeError{Name: "bsl", L: l, R: r} },
|
|
func(l, r []interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bsl", L: l, R: r} },
|
|
func(l, r map[string]interface{}) interface{} {
|
|
return &gojqextra.BinopTypeError{Name: "bsl", L: l, R: r}
|
|
},
|
|
func(l, r interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bsl", L: l, R: r} },
|
|
)
|
|
}
|
|
|
|
func (i *Interp) bsr(c interface{}, a []interface{}) interface{} {
|
|
return gojq.BinopTypeSwitch(a[0], a[1],
|
|
func(l, r int) bool { return true },
|
|
func(l, r int) interface{} { return l >> r },
|
|
func(l, r float64) interface{} { return int(l) >> int(r) },
|
|
func(l, r *big.Int) interface{} { return new(big.Int).Rsh(l, uint(r.Uint64())) },
|
|
func(l, r string) interface{} { return &gojqextra.BinopTypeError{Name: "bsr", L: l, R: r} },
|
|
func(l, r []interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bsr", L: l, R: r} },
|
|
func(l, r map[string]interface{}) interface{} {
|
|
return &gojqextra.BinopTypeError{Name: "bsr", L: l, R: r}
|
|
},
|
|
func(l, r interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bsr", L: l, R: r} },
|
|
)
|
|
}
|
|
|
|
func (i *Interp) band(c interface{}, a []interface{}) interface{} {
|
|
return gojq.BinopTypeSwitch(a[0], a[1],
|
|
func(l, r int) bool { return true },
|
|
func(l, r int) interface{} { return l & r },
|
|
func(l, r float64) interface{} { return int(l) & int(r) },
|
|
func(l, r *big.Int) interface{} { return new(big.Int).And(l, r) },
|
|
func(l, r string) interface{} { return &gojqextra.BinopTypeError{Name: "band", L: l, R: r} },
|
|
func(l, r []interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "band", L: l, R: r} },
|
|
func(l, r map[string]interface{}) interface{} {
|
|
return &gojqextra.BinopTypeError{Name: "band", L: l, R: r}
|
|
},
|
|
func(l, r interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "band", L: l, R: r} },
|
|
)
|
|
}
|
|
|
|
func (i *Interp) bor(c interface{}, a []interface{}) interface{} {
|
|
return gojq.BinopTypeSwitch(a[0], a[1],
|
|
func(l, r int) bool { return true },
|
|
func(l, r int) interface{} { return l | r },
|
|
func(l, r float64) interface{} { return int(l) | int(r) },
|
|
func(l, r *big.Int) interface{} { return new(big.Int).Or(l, r) },
|
|
func(l, r string) interface{} { return &gojqextra.BinopTypeError{Name: "bor", L: l, R: r} },
|
|
func(l, r []interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bor", L: l, R: r} },
|
|
func(l, r map[string]interface{}) interface{} {
|
|
return &gojqextra.BinopTypeError{Name: "bor", L: l, R: r}
|
|
},
|
|
func(l, r interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bor", L: l, R: r} },
|
|
)
|
|
}
|
|
|
|
func (i *Interp) bxor(c interface{}, a []interface{}) interface{} {
|
|
return gojq.BinopTypeSwitch(a[0], a[1],
|
|
func(l, r int) bool { return true },
|
|
func(l, r int) interface{} { return l ^ r },
|
|
func(l, r float64) interface{} { return int(l) ^ int(r) },
|
|
func(l, r *big.Int) interface{} { return new(big.Int).Xor(l, r) },
|
|
func(l, r string) interface{} { return &gojqextra.BinopTypeError{Name: "bxor", L: l, R: r} },
|
|
func(l, r []interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bxor", L: l, R: r} },
|
|
func(l, r map[string]interface{}) interface{} {
|
|
return &gojqextra.BinopTypeError{Name: "bxor", L: l, R: r}
|
|
},
|
|
func(l, r interface{}) interface{} { return &gojqextra.BinopTypeError{Name: "bxor", L: l, R: r} },
|
|
)
|
|
}
|