From 62aa738be03845f96c40edde087ea39693b27e4e Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Sun, 15 Dec 2024 17:54:45 +0000 Subject: Implement new number system --- subex/filter.go | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) (limited to 'subex/filter.go') 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} +} -- cgit v1.2.3