File: bitops.go

package info (click to toggle)
fq 0.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 106,624 kB
  • sloc: xml: 2,835; makefile: 250; sh: 241; exp: 57; ansic: 21
file content (105 lines) | stat: -rw-r--r-- 3,672 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package interp

import (
	"math/big"

	"github.com/wader/fq/internal/gojqex"
	"github.com/wader/gojq"
)

func init() {
	RegisterFunc0("bnot", (*Interp).bnot)
	RegisterFunc2("bsl", (*Interp).bsl)
	RegisterFunc2("bsr", (*Interp).bsr)
	RegisterFunc2("band", (*Interp).band)
	RegisterFunc2("bor", (*Interp).bor)
	RegisterFunc2("bxor", (*Interp).bxor)
}

func (i *Interp) bnot(c any) any {
	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())
	default:
		return &gojqex.UnaryTypeError{Name: "bnot", V: c}
	}
}

func (i *Interp) bsl(c any, a any, b any) any {
	return gojq.BinopTypeSwitch(a, b,
		func(l, r int) any {
			if v := l << r; v>>r == l {
				return v
			}
			return new(big.Int).Lsh(big.NewInt(int64(l)), uint(r))
		},
		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())) },
		func(l, r string) any { return &gojqex.BinopTypeError{Name: "bsl", L: l, R: r} },
		func(l, r []any) any { return &gojqex.BinopTypeError{Name: "bsl", L: l, R: r} },
		func(l, r map[string]any) any {
			return &gojqex.BinopTypeError{Name: "bsl", L: l, R: r}
		},
		func(l, r any) any { return &gojqex.BinopTypeError{Name: "bsl", L: l, R: r} },
	)
}

func (i *Interp) bsr(c any, a any, b any) any {
	return gojq.BinopTypeSwitch(a, b,
		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())) },
		func(l, r string) any { return &gojqex.BinopTypeError{Name: "bsr", L: l, R: r} },
		func(l, r []any) any { return &gojqex.BinopTypeError{Name: "bsr", L: l, R: r} },
		func(l, r map[string]any) any {
			return &gojqex.BinopTypeError{Name: "bsr", L: l, R: r}
		},
		func(l, r any) any { return &gojqex.BinopTypeError{Name: "bsr", L: l, R: r} },
	)
}

func (i *Interp) band(c any, a any, b any) any {
	return gojq.BinopTypeSwitch(a, b,
		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) },
		func(l, r string) any { return &gojqex.BinopTypeError{Name: "band", L: l, R: r} },
		func(l, r []any) any { return &gojqex.BinopTypeError{Name: "band", L: l, R: r} },
		func(l, r map[string]any) any {
			return &gojqex.BinopTypeError{Name: "band", L: l, R: r}
		},
		func(l, r any) any { return &gojqex.BinopTypeError{Name: "band", L: l, R: r} },
	)
}

func (i *Interp) bor(c any, a any, b any) any {
	return gojq.BinopTypeSwitch(a, b,
		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) },
		func(l, r string) any { return &gojqex.BinopTypeError{Name: "bor", L: l, R: r} },
		func(l, r []any) any { return &gojqex.BinopTypeError{Name: "bor", L: l, R: r} },
		func(l, r map[string]any) any {
			return &gojqex.BinopTypeError{Name: "bor", L: l, R: r}
		},
		func(l, r any) any { return &gojqex.BinopTypeError{Name: "bor", L: l, R: r} },
	)
}

func (i *Interp) bxor(c any, a any, b any) any {
	return gojq.BinopTypeSwitch(a, b,
		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) },
		func(l, r string) any { return &gojqex.BinopTypeError{Name: "bxor", L: l, R: r} },
		func(l, r []any) any { return &gojqex.BinopTypeError{Name: "bxor", L: l, R: r} },
		func(l, r map[string]any) any {
			return &gojqex.BinopTypeError{Name: "bxor", L: l, R: r}
		},
		func(l, r any) any { return &gojqex.BinopTypeError{Name: "bxor", L: l, R: r} },
	)
}