~adnano/kiln-devel

funcs.go: Add mathematical functions v4 APPLIED

Edd Salkield: 2
 funcs.go: Add mathematical functions
 docs: Document mathematical functions

 2 files changed, 321 insertions(+), 0 deletions(-)
Pushed with minor edits. Thanks!

If you have some time, it might be nice to add some tests for these new
math functions in a new file funcs_test.go.

To git@git.sr.ht:~adnano/kiln
   4f73b34..4e6a81e  master -> master
Thanks for your help getting this implemented.  I'll take a look at
writing some tests next time I have a bit of time.
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~adnano/kiln-devel/patches/33457/mbox | git am -3
Learn more about email & git

[PATCH v4 1/2] funcs.go: Add mathematical functions Export this patch

---
 funcs.go | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 279 insertions(+)

diff --git a/funcs.go b/funcs.go
index 2704ebe..54082ba 100644
--- a/funcs.go
+++ b/funcs.go
@@ -2,6 +2,7 @@ package main

import (
	"html/template"
	"math"
	"path"
	"reflect"
	"strings"
@@ -13,6 +14,7 @@ import (
func (s *Site) funcs() map[string]interface{} {
	return map[string]interface{}{
		"exec":         executeString,
		"math":         func() _math { return _math{} },
		"path":         func() _path { return _path{} },
		"partial":      s.templates.ExecutePartial,
		"reverse":      reverse,
@@ -26,6 +28,283 @@ func (s *Site) funcs() map[string]interface{} {
	}
}

type _math struct{}

func (_math) Add(a, b interface{}) interface{} {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return a + b
		case float64:
			return float64(a) + b
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return a + float64(b)
		case float64:
			return a + b

		}
	}
	panic("invalid input")
}

func (_math) Sub(a, b interface{}) interface{} {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return a - b
		case float64:
			return float64(a) - b
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return a - float64(b)
		case float64:
			return a - b

		}
	}
	panic("invalid input")
}

func (_math) Mul(a, b interface{}) interface{} {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return a * b
		case float64:
			return float64(a) * b
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return a * float64(b)
		case float64:
			return a * b

		}
	}
	panic("invalid input")
}

func (_math) Div(a, b interface{}) float64 {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return float64(a) / float64(b)
		case float64:
			return float64(a) / b
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return a / float64(b)
		case float64:
			return a / b

		}
	}
	panic("invalid input")
}

func (_math) Mod(a, b interface{}) int64 {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return a % b
		case float64:
			return int64(math.Mod(float64(a), b))
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return int64(math.Mod(a, float64(b)))
		case float64:
			return int64(math.Mod(a, b))

		}
	}
	panic("invalid input")
}

func (_math) Ceil(a interface{}) int64 {
	switch a := get64(a).(type) {
	case int64:
		return a
	case float64:
		return int64(math.Ceil(a))
	}
	panic("invalid input")
}

func (_math) Floor(a interface{}) int64 {
	switch a := get64(a).(type) {
	case int64:
		return a
	case float64:
		return int64(math.Floor(a))
	}
	panic("invalid input")
}

func (_math) Log(a interface{}) float64 {
	switch a := get64(a).(type) {
	case int64:
		return math.Log(float64(a))
	case float64:
		return math.Log(a)
	}
	panic("invalid input")
}

func (_math) Max(a, b interface{}) interface{} {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			if a >= b {
				return a
			} else {
				return b
			}
		case float64:
			if float64(a) >= b {
				return float64(a)
			} else {
				return b
			}
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			if a >= float64(b) {
				return a
			} else {
				return float64(b)
			}
		case float64:
			if a >= b {
				return a
			} else {
				return b
			}
		}
	}
	panic("invalid input")
}

func (_math) Min(a, b interface{}) interface{} {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			if a <= b {
				return a
			} else {
				return b
			}
		case float64:
			if float64(a) <= b {
				return float64(a)
			} else {
				return b
			}
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			if a <= float64(b) {
				return a
			} else {
				return float64(b)
			}
		case float64:
			if a <= b {
				return a
			} else {
				return b
			}
		}
	}
	panic("invalid input")
}

func (_math) Pow(a, b interface{}) float64 {
	switch a := get64(a).(type) {
	case int64:
		switch b := get64(b).(type) {
		case int64:
			return math.Pow(float64(a), float64(b))
		case float64:
			return math.Pow(float64(a), b)
		}
	case float64:
		switch b := get64(b).(type) {
		case int64:
			return math.Pow(a, float64(b))
		case float64:
			return math.Pow(a, b)
		}
	}
	panic("invalid input")
}

func (_math) Round(a interface{}) int64 {
	switch a := get64(a).(type) {
	case int64:
		return a
	case float64:
		return int64(math.Round(a))
	}
	panic("invalid input")
}

func (_math) Sqrt(a interface{}) float64 {
	switch a := get64(a).(type) {
	case int64:
		return math.Sqrt(float64(a))
	case float64:
		return math.Sqrt(a)
	}
	panic("invalid input")
}

func get64(x interface{}) interface{} {
	switch x := x.(type) {
	case uint8:
		return int64(x)
	case int8:
		return int64(x)
	case uint16:
		return int64(x)
	case int16:
		return int64(x)
	case uint32:
		return int64(x)
	case int32:
		return int64(x)
	case uint64:
		return int64(x)
	case int64:
		return int64(x)
	case int:
		return int64(x)
	case float32:
		return float64(x)
	case float64:
		return float64(x)
	}
	panic("invalid input")
}

type _path struct{}

func (_path) Base(s string) string            { return path.Base(s) }
-- 
2.36.1

[PATCH v4 2/2] docs: Document mathematical functions Export this patch

---
 docs/kiln.1.scd | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/docs/kiln.1.scd b/docs/kiln.1.scd
index e995581..0908456 100644
--- a/docs/kiln.1.scd
+++ b/docs/kiln.1.scd
@@ -621,6 +621,48 @@ All templates have the following functions available to them:
*lt* _arg1_, _arg2_
	Returns the boolean truth of _arg1_ < _arg2_.

*math.Add* _arg1_, _arg2_
	Returns _arg1_ + _arg2_ as an integer if both arguments are
	integers, otherwise as a float.

*math.Sub* _arg1_, _arg2_
	Returns _arg1_ - _arg2_ as an integer if both arguments are
	integers, otherwise as a float.

*math.Mul* _arg1_, _arg2_
	Returns _arg1_ \* _arg2_ as an integer if both arguments are
	integers, otherwise as a float.

*math.Div* _arg1_, _arg2_
	Returns _arg1_ / _arg2_ as a float.

*math.Mod* _arg1_, _arg2_
	Returns _arg1_ % _arg2_ as an integer.

*math.Ceil* _arg_
	Returns the greatest integer value greater than or equal to _arg_.

*math.Floor* _arg_
	Returns the greatest integer value less than or equal to _arg_.

*math.Log* _arg_
	Returns the natural logarithm of _arg_ as a float.

*math.Max* _arg1_, _arg2_
	Returns the greater of _arg1_ and _arg2_ as an integer if both arguments are integers, otherwise as a float.

*math.Min* _arg1_, _arg2_
	Returns the lesser of _arg1_ and _arg2_ as an integer if both arguments are integers, otherwise as a float.

*math.Pow* _arg1_, _arg2_
	Returns _arg1_ ^ _arg2_ as a float.

*math.Round* _arg_
	Returns the nearest integer to _arg_, rounding half away from zero.

*math.Sqrt* _arg_
	Returns square root of _arg_ as a float.

*ne* _arg1_, _arg2_
	Returns the boolean truth of _arg1_ != _arg2_.

-- 
2.36.1
Pushed with minor edits. Thanks!

If you have some time, it might be nice to add some tests for these new
math functions in a new file funcs_test.go.

To git@git.sr.ht:~adnano/kiln
   4f73b34..4e6a81e  master -> master