diff options
author | Charlie Stanton <charlie@shtanton.xyz> | 2025-10-18 09:41:50 +0100 |
---|---|---|
committer | Charlie Stanton <charlie@shtanton.xyz> | 2025-10-18 09:41:50 +0100 |
commit | b2ce005d227a10a9b8a6f5362c87a0e34ee07acc (patch) | |
tree | 454c7dcafc02759b90d083ab1d72c0bbfb65f578 /subex/numberexpr.go | |
parent | 62aa738be03845f96c40edde087ea39693b27e4e (diff) | |
download | stred-go-b2ce005d227a10a9b8a6f5362c87a0e34ee07acc.tar |
Diffstat (limited to 'subex/numberexpr.go')
-rw-r--r-- | subex/numberexpr.go | 217 |
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) +} |