aboutsummaryrefslogtreecommitdiffstats
path: root/lib/logic.moon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/logic.moon')
-rw-r--r--lib/logic.moon159
1 files changed, 93 insertions, 66 deletions
diff --git a/lib/logic.moon b/lib/logic.moon
index 7264be0..157d190 100644
--- a/lib/logic.moon
+++ b/lib/logic.moon
@@ -1,4 +1,4 @@
-import Op, Input, Error, match from require 'core.base'
+import Op, Value, Input, Error, match from require 'core.base'
all_same = (first, list) ->
for v in *list
@@ -31,77 +31,98 @@ class ReduceOp extends Op
@out\set accum
-class eq extends Op
- @doc: "(eq a b [c]...)
-(== a b [c]...) - check for equality
+eq = Value.meta
+ meta:
+ name: 'eq'
+ summary: "Check for equality."
+ examples: { '(== a b [c]...)', '(eq a b [c]...)' }
+ description: "`true` if the types and values of all arguments are equal."
+
+ value: class extends Op
+ 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: Input.value first
+ rest: [Input.value v for v in *rest]
+ }
+ else
+ {}
+
+ tick: =>
+ if not @inputs.first
+ @out\set false
+ return
+
+ { :first, :rest } = @unwrap_all!
+
+ equal = true
+ for other in *rest
+ if first != other
+ equal = false
+ break
-If the value types dont match, the result is an eval-time constant 'false'."
+ @out\set equal
- new: => super 'bool', false
- setup: (inputs) =>
- { first, rest } = match "any *any", inputs
- same = all_same first\type!, [i\type! for i in *rest]
+not_eq = Value.meta
+ meta:
+ name: 'not-eq'
+ summary: "Check for inequality."
+ examples: { '(!= a b [c]...)', '(not-eq a b [c]...)' }
+ description: "`true` if types or values of any two arguments are different."
- super if same
- {
- first: Input.value first
- rest: [Input.value v for v in *rest]
- }
- else
- {}
+ value: class extends Op
+ new: => super 'bool'
- tick: =>
- if not @inputs.first
- @out\set false
- return
+ setup: (inputs) =>
+ assert #inputs > 1, Error 'argument', "need at least two values"
+ super [Input.value v for v in *inputs]
- { :first, :rest } = @unwrap_all!
+ tick: =>
+ if not @inputs[1]
+ @out\set true
+ return
- equal = true
- for other in *rest
- if first != other
- equal = false
- break
+ diff = true
+ for a=1, #@inputs-1
+ for b=a+1, #@inputs
+ if @inputs[a].stream == @inputs[b].stream
+ diff = false
+ break
- @out\set equal
+ break unless diff
-class not_eq extends Op
- @doc: "(not-eq a b [c]...)
-(!= a b [c]...) - check for inequality"
- new: => super 'bool'
+ @out\set diff
- setup: (inputs) =>
- assert #inputs > 1, Error 'argument', "need at least two values"
- super [Input.value v for v in *inputs]
+and_ = Value.meta
+ meta:
+ name: 'and'
+ summary: "Logical AND."
+ examples: { '(and a b [c…])' }
+ value: class extends ReduceOp
+ fn: (a, b) -> a and b
- tick: =>
- if not @inputs[1]
- @out\set true
- return
-
- diff = true
- for a=1, #@inputs-1
- for b=a+1, #@inputs
- if @inputs[a].stream == @inputs[b].stream
- diff = false
- break
+or_ = Value.meta
+ meta:
+ name: 'or'
+ summary: "Logical OR."
+ examples: { '(or a b [c…])' }
+ value: class extends ReduceOp
+ fn: (a, b) -> a or b
- break unless diff
+not_ = Value.meta
+ meta:
+ name: 'not'
+ summary: "Logical NOT."
+ examples: { '(not a)' }
- @out\set diff
-
-class and_ extends ReduceOp
- @doc: "(and a b [c]...) - AND values"
- fn: (a, b) -> a and b
-
-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'
+ value: class extends Op
+ new: => super 'bool'
setup: (inputs) =>
{ value } = match 'any', inputs
@@ -109,15 +130,21 @@ class not_ extends Op
tick: => @out\set not tobool @inputs.value!
-class bool extends Op
- @doc: "(bool a) - convert to bool"
- new: => super 'bool'
+bool = Value.meta
+ meta:
+ name: 'bool'
+ summary: "Cast value to bool."
+ examples: { '(bool a)' }
+ description: "`false` if a is `false`, `nil` or `0`, `true` otherwise."
- setup: (inputs) =>
- { value } = match 'any', inputs
- super value: Input.value value
+ value: class extends Op
+ new: => super 'bool'
+
+ setup: (inputs) =>
+ { value } = match 'any', inputs
+ super value: Input.value value
- tick: => @out\set tobool @inputs\value!
+ tick: => @out\set tobool @inputs\value!
{
:eq, '==': eq