diff options
author | Charlie Stanton <charlie@shtanton.xyz> | 2024-12-15 17:54:45 +0000 |
---|---|---|
committer | Charlie Stanton <charlie@shtanton.xyz> | 2024-12-15 17:54:45 +0000 |
commit | 62aa738be03845f96c40edde087ea39693b27e4e (patch) | |
tree | 81a86faa96db42d9da5e7014f53974468229d3e6 /subex/filter.go | |
parent | b434fe4e14f6dcc8d1d7433a29351b8e8ea77d37 (diff) | |
download | stred-go-numbers.tar |
Implement new number systemnumbers
Diffstat (limited to 'subex/filter.go')
-rw-r--r-- | subex/filter.go | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/subex/filter.go b/subex/filter.go index 309d6c7..87c83a4 100644 --- a/subex/filter.go +++ b/subex/filter.go @@ -2,6 +2,8 @@ package subex import ( "main/walk" + "math" + "fmt" ) type valueFilter interface { @@ -86,3 +88,172 @@ type selectRuneFilter struct { func (f selectRuneFilter) runeFilter(r rune) bool { return f.r == r } + +type numberFilter interface { + add(m float64) numberFilter + multiply(m float64) numberFilter + numberFilter(n float64) bool +} + +func (_ anyNumberFilter) numberFilter(n float64) bool { + return true +} +func (_ anyNumberFilter) add(m float64) numberFilter { + return anyNumberFilter{} +} +func (_ anyNumberFilter) multiply(m float64) numberFilter { + if m == 0.0 { + return equalNumberFilter {0.0} + } else { + return anyNumberFilter{} + } +} +func (_ anyNumberFilter) String() string { + return "r" +} + +type divisibleNumberFilter struct { + divisor float64 + target float64 +} +func (d divisibleNumberFilter) numberFilter(n float64) bool { + mod := math.Mod(n, d.divisor) + if mod < 0 { + mod += d.divisor + } + return mod == d.target +} +func (d divisibleNumberFilter) add(m float64) numberFilter { + mod := math.Mod(m + d.target, d.divisor) + if mod < 0 { + mod += d.divisor + } + return divisibleNumberFilter { + divisor: d.divisor, + target: mod, + } +} +func (d divisibleNumberFilter) multiply(m float64) numberFilter { + if m == 0.0 { + return equalNumberFilter {0.0} + } + + target := d.target + if m < 0 { + target = d.divisor - target + m = -m + } + + return divisibleNumberFilter { + divisor: d.divisor * m, + target: target * m, + } +} +func (d divisibleNumberFilter) String() string { + return fmt.Sprintf("(x %% %v == %v)", d.divisor, d.target) +} + +type andNumberFilter struct { + lhs, rhs numberFilter +} +func (a andNumberFilter) numberFilter(n float64) bool { + return a.lhs.numberFilter(n) && a.rhs.numberFilter(n) +} +func (a andNumberFilter) add(m float64) numberFilter { + return andNumberFilter { + lhs: a.lhs.add(m), + rhs: a.rhs.add(m), + } +} +func (a andNumberFilter) multiply(m float64) numberFilter { + return andNumberFilter { + lhs: a.lhs.multiply(m), + rhs: a.rhs.multiply(m), + } +} +func (a andNumberFilter) String() string { + return fmt.Sprintf("(%v && %v)", a.lhs, a.rhs) +} + +type orNumberFilter struct { + lhs, rhs numberFilter +} +func (o orNumberFilter) numberFilter(n float64) bool { + return o.lhs.numberFilter(n) || o.rhs.numberFilter(n) +} +func (o orNumberFilter) String() string { + return fmt.Sprintf("(%v || %v)", o.lhs, o.rhs) +} + +type notNumberFilter struct { + operand numberFilter +} +func (no notNumberFilter) numberFilter(n float64) bool { + return !no.operand.numberFilter(n) +} +func (no notNumberFilter) add(m float64) numberFilter { + return notNumberFilter {no.operand.add(m)} +} +func (no notNumberFilter) multiply(m float64) numberFilter { + return notNumberFilter {no.operand.multiply(m)} +} +func (no notNumberFilter) String() string { + return fmt.Sprintf("(!%v)", no.operand) +} + +type lessThanNumberFilter struct { + rhs float64 +} +func (l lessThanNumberFilter) numberFilter(n float64) bool { + return n < l.rhs +} +func (l lessThanNumberFilter) add(m float64) numberFilter { + return lessThanNumberFilter {l.rhs + m} +} +func (l lessThanNumberFilter) multiply(m float64) numberFilter { + if m > 0 { + return lessThanNumberFilter {l.rhs * m} + } else if m < 0 { + return greaterThanNumberFilter {l.rhs * m} + } else { + return equalNumberFilter {0} + } +} +func (l lessThanNumberFilter) String() string { + return fmt.Sprintf("(x < %v)", l.rhs) +} + +type greaterThanNumberFilter struct { + rhs float64 +} +func (g greaterThanNumberFilter) numberFilter(n float64) bool { + return n > g.rhs +} +func (g greaterThanNumberFilter) add(m float64) numberFilter { + return greaterThanNumberFilter {g.rhs + m} +} +func (g greaterThanNumberFilter) multiply(m float64) numberFilter { + if m > 0 { + return greaterThanNumberFilter {g.rhs * m} + } else if m < 0 { + return lessThanNumberFilter {g.rhs * m} + } else { + return equalNumberFilter {0} + } +} +func (g greaterThanNumberFilter) String() string { + return fmt.Sprintf("(x > %v)", g.rhs) +} + +type equalNumberFilter struct { + rhs float64 +} +func (e equalNumberFilter) numberFilter(n float64) bool { + return n == e.rhs +} +func (e equalNumberFilter) add(m float64) numberFilter { + return equalNumberFilter {e.rhs + m} +} +func (e equalNumberFilter) multiply(m float64) numberFilter { + return equalNumberFilter {e.rhs * m} +} |