diff options
Diffstat (limited to 'lib/logic.moon')
| -rw-r--r-- | lib/logic.moon | 148 |
1 files changed, 101 insertions, 47 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_ |
