mirror of
https://github.com/wader/fq.git
synced 2024-12-28 08:02:28 +03:00
518f6af4a8
Upstream changes: Many performance improvements Error message improvments Lots of refactoring Most of the JQValue interface changes in gojq fork had to be reworked but resultet in a much nicer and cleaner changeset. fq changes: Assignment to JQValue (like a decode value) now shallowly converts the value into a jq value before assigning. Was a bit hacky as it was and this makes JQValue behave more like real jq values. This also fixes some advanced indexing issues. Actual custom path updates will be something for the future.
110 lines
4.3 KiB
Go
110 lines
4.3 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) interface{} {
|
|
if v := l << r; v>>r == l {
|
|
return v
|
|
}
|
|
return new(big.Int).Lsh(big.NewInt(int64(l)), uint(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) 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) 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) 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) 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} },
|
|
)
|
|
}
|