aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-03-02 13:16:21 +0000
committers-ol <s-ol@users.noreply.github.com>2020-03-02 13:16:21 +0000
commitdf91fee4a7bb17f8822a0a5637533257d30e0743 (patch)
tree54f1a3a7bc7b850cc4b0a87296670612274ca518 /lib
parentconvert lib.time to IO (diff)
downloadalive-df91fee4a7bb17f8822a0a5637533257d30e0743.tar.gz
alive-df91fee4a7bb17f8822a0a5637533257d30e0743.zip
update lib.math and lib.logic to new op interface
Diffstat (limited to 'lib')
-rw-r--r--lib/logic.moon148
-rw-r--r--lib/math.moon86
2 files changed, 142 insertions, 92 deletions
diff --git a/lib/logic.moon b/lib/logic.moon
index c476033..d2144f6 100644
--- a/lib/logic.moon
+++ b/lib/logic.moon
@@ -1,75 +1,129 @@
-import Stream, Op from require 'core'
-unpack or= table.unpack
+import Op, ValueInput, match from require 'core'
-class BinOp extends Op
- new: (...) =>
- super ...
- @out = Stream 'bool'
+all_same = (first, list) ->
+ for v in *list
+ if v != first
+ return false
- setup: (...) =>
- @children = { ... }
- assert #@children >= 2, "#{@} needs at least two parameters"
- @out
+ true
-class eq extends BinOp
+tobool = (val) ->
+ switch val
+ when false, nil, 0
+ false
+ else
+ true
+
+class ReduceOp extends Op
+ new: => super 'bool'
+
+ setup: (inputs) =>
+ { first, rest } = match "any *any", inputs
+ super
+ first: ValueInput first
+ rest: [ValueInput v for v in *rest]
+
+ tick: =>
+ { :first, :rest } = @unwrap_all!
+ accum = tobool first
+ for val in *rest
+ accum = @.fn accum, tobool val
+
+ @out\set accum
+
+class eq extends Op
@doc: "(eq a b [c]...)
-(== a b [c]...) - check for equality"
+(== a b [c]...) - check for equality
+
+If the value types dont match, the result is an eval-time constant 'false'."
+
+ new: => super 'bool', false
+
+ setup: (inputs) =>
+ { first, rest } = match "any *any", inputs
+ same = all_same first\type!, [i\type! for i in *rest]
+
+ super if same
+ {
+ first: ValueInput first
+ rest: [ValueInput v for v in *rest]
+ }
+ else
+ {}
+
+ tick: =>
+ if not @inputs.first
+ @out\set false
+ return
+
+ { :first, :rest } = @unwrap_all!
- update: (dt) =>
equal = true
- val = @children[1]\unwrap!
- for child in *@children[2,]
- equal and= val == child\unwrap!
+ for other in *rest
+ if first != other
+ equal = false
+ break
+
@out\set equal
+class not_eq extends Op
+ @doc: "(not-eq a b [c]...)
+(!= a b [c]...) - check for inequality"
+ new: => super 'bool'
-class and_ extends BinOp
- @doc: "(and a b [c]...) - AND values"
+ setup: (inputs) =>
+ assert #inputs > 1, "neq need at least two values"
+ super [ValueInput v for v in *inputs]
+
+ tick: =>
+ if not @inputs[1]
+ @out\set true
+ return
- update: (dt) =>
- value = true
- for child in *@children
- value and= child\unwrap!
- @out\set value
+ diff = true
+ for a=1, #@inputs-1
+ for b=a+1, #@inputs
+ print @inputs[a], @inputs[b]
+ if @inputs[a].stream == @inputs[b].stream
+ print "found a match #{a} == #{b}"
+ diff = false
+ break
-class or_ extends BinOp
- @doc: "(or a b [c]...) - OR values
+ break unless diff
-subtracts all other arguments from a"
+ @out\set diff
+
+class and_ extends ReduceOp
+ @doc: "(and a b [c]...) - AND values"
+ fn: (a, b) -> a and b
- update: (dt) =>
- value = false
- for child in *@children
- value or= child\unwrap!
- @out\set value
+class or_ extends ReduceOp
+ @doc: "(or a b [c]...) - OR values"
+ fn: (a, b) -> a or b
class not_ extends Op
@doc: "(not a) - boolean opposite"
+ new: => super 'bool'
- setup: (@a) =>
- @out = Stream 'bool'
- @out
+ setup: (inputs) =>
+ { value } = match 'any', inputs
+ super value: ValueInput value
- update: (dt) =>
- @out\set not @a\unwrap!
+ tick: => @out\set not tobool @inputs.value!
class bool extends Op
@doc: "(bool a) - convert to bool"
+ new: => super 'bool'
- setup: (@a) =>
- @out = Stream 'bool'
- @out
+ setup: (inputs) =>
+ { value } = match 'any', inputs
+ super value: ValueInput value
- update: (dt) =>
- @out\set switch @a\unwrap!
- when false, nil, 0
- false
- else
- true
+ tick: => @out\set tobool @inputs\value!
{
- '==': eq
- :eq
+ :eq, '==': eq
+ 'not-eq': not_eq, '!=': not_eq
and: and_
or: or_
not: not_
diff --git a/lib/math.moon b/lib/math.moon
index ca965be..4d01741 100644
--- a/lib/math.moon
+++ b/lib/math.moon
@@ -1,67 +1,63 @@
-import Op, Value from require 'core'
+import Op, Value, ValueInput, match from require 'core'
unpack or= table.unpack
-class BinOp extends Op
- new: =>
- super 'num', 0
+class ReduceOp extends Op
+ new: => super 'num'
- setup: (params) =>
- super params
- assert #@inputs >= 2, "#{@} needs at least two parameters"
+ setup: (inputs) =>
+ { first, rest } = match 'num *num', inputs
+ super
+ first: ValueInput first
+ rest: [ValueInput v for v in *rest]
-class add extends BinOp
+ tick: =>
+ { :first, :rest } = @unwrap_all!
+ accum = first
+ for val in *rest
+ accum = @.fn accum, val
+ @out\set accum
+
+class add extends ReduceOp
@doc: "(+ a b [c]...)
(add a b [c]...) - add values"
- tick: =>
- value = 0
- for child in *@inputs
- value += child\unwrap 'num'
- @out\set value
+ fn: (a, b) -> a + b
-class sub extends BinOp
+class sub extends ReduceOp
@doc: "(- a b [c]...)
(sub a b [c]...) - subtract values
subtracts all other arguments from a"
- tick: =>
- value = @inputs[1]\unwrap 'num'
- for child in *@inputs[2,]
- value -= child\unwrap 'num'
- @out\set value
+ fn: (a, b) -> a - b
-class mul extends BinOp
+class mul extends ReduceOp
@doc: "(* a b [c]...)
(mul a b [c]...) - multiply values"
- tick: =>
- value = 1
- for child in *@inputs
- value *= child\unwrap 'num'
- @out\set value
+ fn: (a, b) -> a * b
-class div extends BinOp
+class div extends ReduceOp
@doc: "(/ a b [c]...)
(div a b [c]...) - divide values
divides a by all other arguments"
- tick: =>
- value = @inputs[1]\unwrap 'num'
- for child in *@inputs[2,]
- value /= child\unwrap 'num'
- @out\set value
+ fn: (a, b) -> a / b
evenodd_op = (name, remainder) ->
class k extends Op
- setup: (@a, @div=Const.num 2) =>
- @out = Stream 'bool'
- @out
+ new: => super 'bool'
+
+ setup: (inputs) =>
+ { val, div } = match 'num num?', inputs
+ super
+ val: ValueInput val
+ div: ValueInput div or Value.num 2
tick: =>
- a, divi = (@a\unwrap 'num'), @div\unwrap 'num'
- @out\set (a % divi) == remainder
+ { :val, :div } = @unwrap_all!
+ @out\set (val % div) == remainder
k.__name = name
k.doc = "(#{name} a [div]) - check for #{name} divison
@@ -71,16 +67,14 @@ div defaults to 2"
func_op = (name, arity, func) ->
k = class extends Op
- new: =>
- super 'num'
+ new: => super 'num'
- setup: (...) =>
- @params = { ... }
- if arity != '*'
- assert #@params == arity, "#{@} needs exactly #{arity} parameters"
+ setup: (inputs) =>
+ { params } = match '*num', inputs
+ assert #params == arity, "#{@} needs exactly #{arity} parameters" if arity != '*'
+ super [ValueInput p for p in *params]
- tick: =>
- @out\set func unpack [p\unwrap 'num' for p in *@params]
+ tick: => @out\set func unpack @unwrap_all!
k.__name = name
k
@@ -98,7 +92,9 @@ module = {
even: evenodd_op 'even', 0
odd: evenodd_op 'odd', 1
- pi: math.pi, huge: math.huge
+ pi: math.pi
+ tau: math.pi*2
+ huge: math.huge
}
for name, arity in pairs {