mirror of
https://github.com/wader/fq.git
synced 2024-12-24 13:52:02 +03:00
Merge pull request #61 from wader/bitops-funcs
interp,fq: Make bit operators normal functions
This commit is contained in:
commit
2743585219
2
go.mod
2
go.mod
@ -23,7 +23,7 @@ require (
|
||||
|
||||
require (
|
||||
// fork of github.com/itchyny/gojq, see github.com/wader/gojq fq branch
|
||||
github.com/wader/gojq v0.12.1-0.20211211101122-3894ded312be
|
||||
github.com/wader/gojq v0.12.1-0.20220108235115-6a05b6c59ace
|
||||
// fork of github.com/chzyer/readline, see github.com/wader/readline fq branch
|
||||
github.com/wader/readline v0.0.0-20210920124728-5a81f7707bac
|
||||
)
|
||||
|
4
go.sum
4
go.sum
@ -16,8 +16,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJ
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/wader/gojq v0.12.1-0.20211211101122-3894ded312be h1:Bc8ZRZxUqQPPwHqdY1c99mKInhJ0UeWEMjgsjHMRGUA=
|
||||
github.com/wader/gojq v0.12.1-0.20211211101122-3894ded312be/go.mod h1:tdC5h6dXdwAJs7eJUw4681AzsgfOSBrAV+cZzEbCZs4=
|
||||
github.com/wader/gojq v0.12.1-0.20220108235115-6a05b6c59ace h1:pt07NaC7OhePrQVRKRxZy9umeWkjr28AmbtQC9CrtVQ=
|
||||
github.com/wader/gojq v0.12.1-0.20220108235115-6a05b6c59ace/go.mod h1:tdC5h6dXdwAJs7eJUw4681AzsgfOSBrAV+cZzEbCZs4=
|
||||
github.com/wader/readline v0.0.0-20210920124728-5a81f7707bac h1:F5x54dwg6vGyf+8XhujiyXr651E3tKpcL1mqGmS7/MU=
|
||||
github.com/wader/readline v0.0.0-20210920124728-5a81f7707bac/go.mod h1:jYXyt9wQg3DifxQ8FM5M/ZoskO23GIwmo05QLHtO9CQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
@ -11,6 +11,24 @@ import (
|
||||
// TODO: refactor to use errors from gojq?
|
||||
// TODO: preview from gojq?
|
||||
|
||||
type UnaryTypeError struct {
|
||||
Name string
|
||||
V interface{}
|
||||
}
|
||||
|
||||
func (err *UnaryTypeError) Error() string {
|
||||
return fmt.Sprintf("cannot %s: %s", err.Name, typeof(err.V))
|
||||
}
|
||||
|
||||
type BinopTypeError struct {
|
||||
Name string
|
||||
L, R interface{}
|
||||
}
|
||||
|
||||
func (err *BinopTypeError) Error() string {
|
||||
return "cannot " + err.Name + ": " + typeof(err.L) + " and " + typeof(err.R)
|
||||
}
|
||||
|
||||
type NonUpdatableTypeError struct {
|
||||
Typ string
|
||||
Key string
|
||||
|
109
pkg/interp/bitops.go
Normal file
109
pkg/interp/bitops.go
Normal file
@ -0,0 +1,109 @@
|
||||
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} },
|
||||
)
|
||||
}
|
27
pkg/interp/testdata/bitops.fqtest
vendored
Normal file
27
pkg/interp/testdata/bitops.fqtest
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
$ fq -i
|
||||
null> 0, -1, 1208925819614629174706175, -1208925819614629174706176 | bnot
|
||||
-1
|
||||
0
|
||||
-1208925819614629174706176
|
||||
1208925819614629174706175
|
||||
null> [0,0], [8,1], [0xffff_ffff_ffff_ffff,1] | bsl(.[0]; .[1])
|
||||
0
|
||||
16
|
||||
36893488147419103230
|
||||
null> [0,0], [8,1], [0x1_ffff_ffff_ffff_fffe,1] | bsr(.[0]; .[1])
|
||||
0
|
||||
4
|
||||
18446744073709551615
|
||||
null> [0,0], [0xffff_ffff_ffff_ffff_ffff,0x1234], [0x1234,0xffff_ffff_ffff_ffff_ffff,0x1234] | band(.[0]; .[1])
|
||||
0
|
||||
4660
|
||||
4660
|
||||
null> [0,0], [0xffff_ffff_ffff_ffff_0000,0x1234], [0x1234,0xffff_ffff_ffff_ffff_0000,0x1234] | bor(.[0]; .[1])
|
||||
0
|
||||
1208925819614629174645300
|
||||
1208925819614629174645300
|
||||
null> [0,0], [0xffff_ffff_ffff_ffff_ffff,0x1234], [0x1234,0xffff_ffff_ffff_ffff_ffff,0x1234] | bxor(.[0]; .[1])
|
||||
0
|
||||
1208925819614629174701515
|
||||
1208925819614629174701515
|
||||
null> ^D
|
Loading…
Reference in New Issue
Block a user