2022-01-09 00:26:49 +03:00
|
|
|
package interp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
|
2024-04-01 19:39:45 +03:00
|
|
|
"github.com/wader/fq/internal/gojqx"
|
2022-01-09 00:26:49 +03:00
|
|
|
"github.com/wader/gojq"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2022-07-16 19:39:57 +03:00
|
|
|
RegisterFunc0("bnot", (*Interp).bnot)
|
|
|
|
RegisterFunc2("bsl", (*Interp).bsl)
|
|
|
|
RegisterFunc2("bsr", (*Interp).bsr)
|
|
|
|
RegisterFunc2("band", (*Interp).band)
|
|
|
|
RegisterFunc2("bor", (*Interp).bor)
|
|
|
|
RegisterFunc2("bxor", (*Interp).bxor)
|
2022-01-09 00:26:49 +03:00
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) bnot(c any) any {
|
2022-01-09 00:26:49 +03:00
|
|
|
switch c := c.(type) {
|
|
|
|
case int:
|
|
|
|
return ^c
|
|
|
|
case *big.Int:
|
|
|
|
return new(big.Int).Not(c)
|
|
|
|
case gojq.JQValue:
|
2022-07-16 19:39:57 +03:00
|
|
|
return i.bnot(c.JQValueToGoJQ())
|
2022-01-09 00:26:49 +03:00
|
|
|
default:
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.UnaryTypeError{Name: "bnot", V: c}
|
2022-01-09 00:26:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) bsl(c any, a any, b any) any {
|
|
|
|
return gojq.BinopTypeSwitch(a, b,
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r int) any {
|
2022-04-10 12:51:14 +03:00
|
|
|
if v := l << r; v>>r == l {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
return new(big.Int).Lsh(big.NewInt(int64(l)), uint(r))
|
|
|
|
},
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r float64) any { return int(l) << int(r) },
|
|
|
|
func(l, r *big.Int) any { return new(big.Int).Lsh(l, uint(r.Uint64())) },
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r string) any { return &gojqx.BinopTypeError{Name: "bsl", L: l, R: r} },
|
|
|
|
func(l, r []any) any { return &gojqx.BinopTypeError{Name: "bsl", L: l, R: r} },
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r map[string]any) any {
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.BinopTypeError{Name: "bsl", L: l, R: r}
|
2022-01-09 00:26:49 +03:00
|
|
|
},
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r any) any { return &gojqx.BinopTypeError{Name: "bsl", L: l, R: r} },
|
2022-01-09 00:26:49 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) bsr(c any, a any, b any) any {
|
|
|
|
return gojq.BinopTypeSwitch(a, b,
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r int) any { return l >> r },
|
|
|
|
func(l, r float64) any { return int(l) >> int(r) },
|
|
|
|
func(l, r *big.Int) any { return new(big.Int).Rsh(l, uint(r.Uint64())) },
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r string) any { return &gojqx.BinopTypeError{Name: "bsr", L: l, R: r} },
|
|
|
|
func(l, r []any) any { return &gojqx.BinopTypeError{Name: "bsr", L: l, R: r} },
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r map[string]any) any {
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.BinopTypeError{Name: "bsr", L: l, R: r}
|
2022-01-09 00:26:49 +03:00
|
|
|
},
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r any) any { return &gojqx.BinopTypeError{Name: "bsr", L: l, R: r} },
|
2022-01-09 00:26:49 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) band(c any, a any, b any) any {
|
|
|
|
return gojq.BinopTypeSwitch(a, b,
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r int) any { return l & r },
|
|
|
|
func(l, r float64) any { return int(l) & int(r) },
|
|
|
|
func(l, r *big.Int) any { return new(big.Int).And(l, r) },
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r string) any { return &gojqx.BinopTypeError{Name: "band", L: l, R: r} },
|
|
|
|
func(l, r []any) any { return &gojqx.BinopTypeError{Name: "band", L: l, R: r} },
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r map[string]any) any {
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.BinopTypeError{Name: "band", L: l, R: r}
|
2022-01-09 00:26:49 +03:00
|
|
|
},
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r any) any { return &gojqx.BinopTypeError{Name: "band", L: l, R: r} },
|
2022-01-09 00:26:49 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) bor(c any, a any, b any) any {
|
|
|
|
return gojq.BinopTypeSwitch(a, b,
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r int) any { return l | r },
|
|
|
|
func(l, r float64) any { return int(l) | int(r) },
|
|
|
|
func(l, r *big.Int) any { return new(big.Int).Or(l, r) },
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r string) any { return &gojqx.BinopTypeError{Name: "bor", L: l, R: r} },
|
|
|
|
func(l, r []any) any { return &gojqx.BinopTypeError{Name: "bor", L: l, R: r} },
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r map[string]any) any {
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.BinopTypeError{Name: "bor", L: l, R: r}
|
2022-01-09 00:26:49 +03:00
|
|
|
},
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r any) any { return &gojqx.BinopTypeError{Name: "bor", L: l, R: r} },
|
2022-01-09 00:26:49 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-16 19:39:57 +03:00
|
|
|
func (i *Interp) bxor(c any, a any, b any) any {
|
|
|
|
return gojq.BinopTypeSwitch(a, b,
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r int) any { return l ^ r },
|
|
|
|
func(l, r float64) any { return int(l) ^ int(r) },
|
|
|
|
func(l, r *big.Int) any { return new(big.Int).Xor(l, r) },
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r string) any { return &gojqx.BinopTypeError{Name: "bxor", L: l, R: r} },
|
|
|
|
func(l, r []any) any { return &gojqx.BinopTypeError{Name: "bxor", L: l, R: r} },
|
2022-05-20 16:10:41 +03:00
|
|
|
func(l, r map[string]any) any {
|
2024-04-01 19:39:45 +03:00
|
|
|
return &gojqx.BinopTypeError{Name: "bxor", L: l, R: r}
|
2022-01-09 00:26:49 +03:00
|
|
|
},
|
2024-04-01 19:39:45 +03:00
|
|
|
func(l, r any) any { return &gojqx.BinopTypeError{Name: "bxor", L: l, R: r} },
|
2022-01-09 00:26:49 +03:00
|
|
|
)
|
|
|
|
}
|