aboutsummaryrefslogtreecommitdiffstats
path: root/lib/math.moon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/math.moon')
-rw-r--r--lib/math.moon218
1 files changed, 150 insertions, 68 deletions
diff --git a/lib/math.moon b/lib/math.moon
index 84e6682..69d83bb 100644
--- a/lib/math.moon
+++ b/lib/math.moon
@@ -17,36 +17,31 @@ class ReduceOp extends Op
accum = @.fn accum, val
@out\set accum
-class add extends ReduceOp
- @doc: "(+ a b [c]...)
-(add a b [c]...) - add values"
-
- fn: (a, b) -> a + b
-
-class sub extends ReduceOp
- @doc: "(- a b [c]...)
-(sub a b [c]...) - subtract values
-
-subtracts all other arguments from a"
-
- fn: (a, b) -> a - b
-
-class mul extends ReduceOp
- @doc: "(* a b [c]...)
-(mul a b [c]...) - multiply values"
+func_op = (arity, func) ->
+ class extends Op
+ new: => super 'num'
- fn: (a, b) -> a * b
+ setup: (inputs) =>
+ { params } = match '*num', inputs
+ if arity != '*'
+ err = Error 'argument', "need exactly #{arity} arguments"
+ assert #params == arity, err
+ super [Input.value p for p in *params]
-class div extends ReduceOp
- @doc: "(/ a b [c]...)
-(div a b [c]...) - divide values
+ tick: => @out\set func unpack @unwrap_all!
-divides a by all other arguments"
+func_def = (name, args, func, summary) ->
+ _, arity = args\gsub ' ', ' '
- fn: (a, b) -> a / b
+ Value.meta
+ meta:
+ :name
+ :summary
+ examples: { "(#{name} #{args})" }
+ value: func_op arity+1, func
-evenodd_op = (name, remainder) ->
- class k extends Op
+evenodd_op = (remainder) ->
+ class extends Op
new: => super 'bool'
setup: (inputs) =>
@@ -59,57 +54,144 @@ evenodd_op = (name, remainder) ->
{ :val, :div } = @unwrap_all!
@out\set (val % div) == remainder
- k.__name = name
- k.doc = "(#{name} a [div]) - check for #{name} divison
-
-div defaults to 2"
- k
-
-func_op = (name, arity, func) ->
- k = class extends Op
- new: => super 'num'
-
- setup: (inputs) =>
- { params } = match '*num', inputs
- if arity != '*'
- err = Error 'argument', "need exactly #{arity} arguments"
- assert #params == arity, err
- super [Input.value p for p in *params]
-
- tick: => @out\set func unpack @unwrap_all!
-
- k.__name = name
- k
-
-mod = func_op 'mod', 2, (a, b) -> a % b
-
-module = {
+add = Value.meta
+ meta:
+ name: 'add'
+ summary: "Add values."
+ examples: { '(+ a b [c…])', '(add a b [c…])' }
+ description: "Sum all arguments."
+ value: class extends ReduceOp
+ fn: (a, b) -> a + b
+
+sub = Value.meta
+ meta:
+ name: 'sub'
+ summary: "Subtract values."
+ examples: { '(- a b [c…])', '(sub a b [c…])' }
+ description: "Subtract all other arguments from `a`."
+ value: class extends ReduceOp
+ fn: (a, b) -> a - b
+
+mul = Value.meta
+ meta:
+ name: 'mul'
+ summary: "Multiply values."
+ examples: { '(* a b [c…])', '(mul a b [c…])' }
+ value: class extends ReduceOp
+ fn: (a, b) -> a * b
+
+div = Value.meta
+ meta:
+ name: 'div'
+ summary: "Divide values."
+ examples: { '(/ a b [c…])', '(div a b [c…])' }
+ description: "Divide `a` by all other arguments."
+ value: class extends ReduceOp
+ fn: (a, b) -> a / b
+
+pow = Value.meta
+ meta:
+ name: 'pow'
+ summary: "Raise to a power."
+ examples: { '(^ base exp)', '(pow base exp' }
+ description: "Raise `base` to the power `exp`."
+ value: class extends ReduceOp
+ fn: (a, b) -> a ^ b
+
+mod = Value.meta
+ meta:
+ name: 'mod'
+ summary: 'Modulo operator.'
+ examples: { '(% num div)', '(mod num div)' }
+ description: "Calculate remainder of division by `div`."
+ value: func_op 2, (a, b) -> a % b
+
+even = Value.meta
+ meta:
+ name: 'even'
+ summary: 'Check whether val is even.'
+ examples: { '(even val [div])' }
+ description: "`true` if dividing `val` by `div` has remainder zero.
+`div` defaults to 2."
+ value: evenodd_op 0
+
+odd = Value.meta
+ meta:
+ name: 'odd'
+ summary: 'Check whether val is odd.'
+ examples: { '(odd val [div])' }
+ description: "`true` if dividing `val` by `div` has remainder one.
+`div` defaults to 2."
+ value: evenodd_op 1
+
+mix = Value.meta
+ meta:
+ name: 'mix'
+ summary: 'Linearly interpolate.'
+ examples: { '(mix a b i)' }
+ description: "Interpolate between `a` and `b` using `i` in range 0-1."
+ value: func_op 3, (a, b, i) -> i*b + (1-i)*a
+
+min = Value.meta
+ meta:
+ name: 'min'
+ summary: "Find the minimum."
+ examples: { '(min a b [c…])' }
+ description: "Return the lowest of arguments."
+ value: func_op '*', math.min
+
+max = Value.meta
+ meta:
+ name: 'max'
+ summary: "Find the maximum."
+ examples: { '(max a b [c…])' }
+ description: "Return the highest of arguments."
+ value: func_op '*', math.min
+
+cos = func_def 'cos', 'alpha', math.cos, "Cosine function (radians)."
+sin = func_def 'sin', 'alpha', math.sin, "Sine function (radians)."
+tan = func_def 'tan', 'alpha', math.tan, "Tangent function (radians)."
+acos = func_def 'acos', 'cos', math.acos, "Inverse cosine function (radians)."
+asin = func_def 'asin', 'sin', math.asin, "Inverse sine function (radians)."
+atan = func_def 'atan', 'tan', math.atan, "Inverse tangent function (radians)."
+atan2 = func_def 'atan2', 'y x', math.atan2, "Inverse tangent function (two argument version)."
+cosh = func_def 'cosh', 'alpha', math.cosh, "Hyperbolic cosine function (radians)."
+sinh = func_def 'sinh', 'alpha', math.sinh, "Hyperbolic sine function (radians)."
+tanh = func_def 'tanh', 'alpha', math.tanh, "Hyperbolic tangent function (radians)."
+
+floor = func_def 'floor', 'val', math.floor, "Round towards negative infinity."
+ceil = func_def 'ceil', 'val', math.ceil, "Round towards positive infinity."
+abs = func_def 'abs', 'val', math.abs, "Get the absolute value."
+
+exp = func_def 'exp', 'exp', math.floor, "*e* number raised to a power."
+log = func_def 'log', 'val base', math.log, "Logarithm with given base."
+log10 = func_def 'log10', 'val', math.log10, "Logarithm with base 10."
+sqrt = func_def 'sqrt', 'val', math.sqrt, "Square root function."
+
+{
:add, '+': add
:sub, '-': sub
:mul, '*': mul
:div, '/': div
+ :pow, '^': pow
:mod, '%': mod
- mix: func_op 'mix', 3, (a, b, i) -> i*b + (1-i)*a
- even: evenodd_op 'even', 0
- odd: evenodd_op 'odd', 1
+ :even, :odd
- pi: math.pi
- tau: math.pi*2
- huge: math.huge
-}
-
-for name, arity in pairs {
- exp: 1, log: 2, log10: 1, sqrt: 1
+ :mix
+ :min, :max
- cos: 1, sin: 1, tan: 1
- asin: 1, acos: 1, atan: 1, atan2: 2
- sinh: 1, cosh: 1, tanh: 1
+ pi: with Value.wrap math.pi
+ .meta = summary: 'The pi constant.'
+ tau: with Value.wrap math.pi*2
+ .meta = summary: 'The tau constant.'
+ huge: with Value.wrap math.huge
+ .meta = summary: 'Positive infinity constant.'
- min: '*', max: '*'
+ :sin, :cos, :tan
+ :asin, :acos, :atan, :atan2
+ :sinh, :cosh, :tanh
- floor: 1, ceil: 1, abs: 1
+ :floor, :ceil, :abs
+ :exp, :log, :log10, :sqrt
}
- module[name] = func_op name, arity, math[name]
-
-module