Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/numberexpr.go
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2025-10-18 09:41:50 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2025-10-18 09:41:50 +0100
commitb2ce005d227a10a9b8a6f5362c87a0e34ee07acc (patch)
tree454c7dcafc02759b90d083ab1d72c0bbfb65f578 /subex/numberexpr.go
parent62aa738be03845f96c40edde087ea39693b27e4e (diff)
downloadstred-go-main.tar
Implement numbers properlyHEADnumbersmain
Diffstat (limited to 'subex/numberexpr.go')
-rw-r--r--subex/numberexpr.go217
1 files changed, 217 insertions, 0 deletions
diff --git a/subex/numberexpr.go b/subex/numberexpr.go
new file mode 100644
index 0000000..3649305
--- /dev/null
+++ b/subex/numberexpr.go
@@ -0,0 +1,217 @@
+package subex
+
+import (
+ "fmt"
+ "math"
+)
+
+type NumberExpr interface {
+ String() string
+ Eval(float64) float64
+}
+
+type NumberExprVariable struct {}
+func (ev NumberExprVariable) String() string {
+ return "n"
+}
+func (ev NumberExprVariable) Eval(v float64) float64 {
+ return v
+}
+
+type NumberExprLiteral struct {
+ Value float64
+}
+func (el NumberExprLiteral) String() string {
+ return fmt.Sprintf("%v", el.Value)
+}
+func (el NumberExprLiteral) Eval(v float64) float64 {
+ return el.Value
+}
+
+type NumberExprAnd struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ea NumberExprAnd) String() string {
+ return fmt.Sprintf("(%v & %v)", ea.Left, ea.Right)
+}
+func (ea NumberExprAnd) Eval(v float64) float64 {
+ left := ea.Left.Eval(v)
+ if left != 0.0 {
+ return ea.Right.Eval(v)
+ } else {
+ return left
+ }
+}
+
+type NumberExprOr struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (eo NumberExprOr) String() string {
+ return fmt.Sprintf("(%v | %v)", eo.Left, eo.Right)
+}
+func (eo NumberExprOr) Eval(v float64) float64 {
+ left := eo.Left.Eval(v)
+ if left != 0.0 {
+ return left
+ } else {
+ return eo.Right.Eval(v)
+ }
+}
+
+type NumberExprNot struct {
+ Right NumberExpr
+}
+func (en NumberExprNot) String() string {
+ return fmt.Sprintf("(!%v)", en.Right)
+}
+func (en NumberExprNot) Eval(v float64) float64 {
+ inner := en.Right.Eval(v)
+ if inner == 0.0 {
+ return 1.0
+ }
+
+ return 0.0
+}
+
+type NumberExprEqual struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ee NumberExprEqual) String() string {
+ return fmt.Sprintf("(%v = %v)", ee.Left, ee.Right)
+}
+func (ee NumberExprEqual) Eval(v float64) float64 {
+ if ee.Left.Eval(v) == ee.Right.Eval(v) {
+ return 1.0
+ } else {
+ return 0.0
+ }
+}
+
+type NumberExprAtMost struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ea NumberExprAtMost) String() string {
+ return fmt.Sprintf("(%v <= %v)", ea.Left, ea.Right)
+}
+func (ea NumberExprAtMost) Eval(v float64) float64 {
+ if ea.Left.Eval(v) <= ea.Right.Eval(v) {
+ return 1.0
+ } else {
+ return 0.0
+ }
+}
+
+type NumberExprLessThan struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (el NumberExprLessThan) String() string {
+ return fmt.Sprintf("(%v < %v)", el.Left, el.Right)
+}
+func (el NumberExprLessThan) Eval(v float64) float64 {
+ if el.Left.Eval(v) < el.Right.Eval(v) {
+ return 1.0
+ } else {
+ return 0.0
+ }
+}
+
+type NumberExprGreaterThan struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (eg NumberExprGreaterThan) String() string {
+ return fmt.Sprintf("(%v > %v)", eg.Left, eg.Right)
+}
+func (eg NumberExprGreaterThan) Eval(v float64) float64 {
+ if eg.Left.Eval(v) > eg.Right.Eval(v) {
+ return 1.0
+ } else {
+ return 0.0
+ }
+}
+
+type NumberExprAtLeast struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ea NumberExprAtLeast) String() string {
+ return fmt.Sprintf("(%v >= %v)", ea.Left, ea.Right)
+}
+func (ea NumberExprAtLeast) Eval(v float64) float64 {
+ if ea.Left.Eval(v) >= ea.Right.Eval(v) {
+ return 1.0
+ } else {
+ return 0.0
+ }
+}
+
+type NumberExprAdd struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ea NumberExprAdd) String() string {
+ return fmt.Sprintf("(%v + %v)", ea.Left, ea.Right)
+}
+func (ea NumberExprAdd) Eval(v float64) float64 {
+ return ea.Left.Eval(v) + ea.Right.Eval(v)
+}
+
+type NumberExprSubtract struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (es NumberExprSubtract) String() string {
+ return fmt.Sprintf("(%v - %v)", es.Left, es.Right)
+}
+func (es NumberExprSubtract) Eval(v float64) float64 {
+ return es.Left.Eval(v) - es.Right.Eval(v)
+}
+
+type NumberExprMultiply struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (em NumberExprMultiply) String() string {
+ return fmt.Sprintf("(%v * %v)", em.Left, em.Right)
+}
+func (em NumberExprMultiply) Eval(v float64) float64 {
+ return em.Left.Eval(v) * em.Right.Eval(v)
+}
+
+type NumberExprDivide struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ed NumberExprDivide) String() string {
+ return fmt.Sprintf("(%v / %v)", ed.Left, ed.Right)
+}
+func (ed NumberExprDivide) Eval(v float64) float64 {
+ return ed.Left.Eval(v) / ed.Right.Eval(v)
+}
+
+type NumberExprMod struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (em NumberExprMod) String() string {
+ return fmt.Sprintf("(%v %% %v)", em.Left, em.Right)
+}
+func (em NumberExprMod) Eval(v float64) float64 {
+ return math.Mod(em.Left.Eval(v), em.Right.Eval(v))
+}
+
+type NumberExprExponent struct {
+ Left NumberExpr
+ Right NumberExpr
+}
+func (ee NumberExprExponent) String() string {
+ return fmt.Sprintf("(%v * %v)", ee.Left, ee.Right)
+}
+func (ee NumberExprExponent) Eval(v float64) float64 {
+ return ee.Left.Eval(v) * ee.Right.Eval(v)
+}