aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2022-10-20 11:20:46 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit56bcabd974c0c0e34fb76d653e927668aaccbdb0 (patch)
treee8458a58b4edf72e6a7e59edccdaaaf9ed7198ab
parentbuiltins: test def, use, export, export* (diff)
downloadalive-56bcabd974c0c0e34fb76d653e927668aaccbdb0.tar.gz
alive-56bcabd974c0c0e34fb76d653e927668aaccbdb0.zip
lib: add <,<=,>,>= to logic, add tests
-rw-r--r--alv-lib/logic.moon48
-rw-r--r--spec/lib/logic_spec.moon90
2 files changed, 137 insertions, 1 deletions
diff --git a/alv-lib/logic.moon b/alv-lib/logic.moon
index d66f53a..b29c4ba 100644
--- a/alv-lib/logic.moon
+++ b/alv-lib/logic.moon
@@ -26,6 +26,18 @@ class ReduceOp extends PureOp
@out\set accum
+class CompareOp extends PureOp
+ pattern: any.num\rep 2, nil
+ type: T.bool
+
+ tick: =>
+ args = @unwrap_all!
+ accum = true
+ for i = 1, #args - 1
+ accum = accum and @.fn args[i], args[i+1]
+
+ @out\set accum
+
eq = Constant.meta
meta:
name: 'eq'
@@ -121,6 +133,38 @@ bool = Constant.meta
type: T.bool
tick: => @out\set tobool @inputs[1]!
+asc = Constant.meta
+ meta:
+ name: 'asc?'
+ summary: "Check if values are in ascending order."
+ examples: { '(asc? a b [c…])', '(< a b [c…])' }
+ value: class extends CompareOp
+ fn: (a, b) -> a < b
+
+lte = Constant.meta
+ meta:
+ name: '<='
+ summary: "Check if values are in ascending order."
+ examples: { '(<= a b [c…])' }
+ value: class extends CompareOp
+ fn: (a, b) -> a <= b
+
+desc = Constant.meta
+ meta:
+ name: 'desc?'
+ summary: "Check if values are in descending order."
+ examples: { '(desc? a b [c…])', '(> a b [c…])' }
+ value: class extends CompareOp
+ fn: (a, b) -> a > b
+
+gte = Constant.meta
+ meta:
+ name: '>='
+ summary: "Check if values are in descending order."
+ examples: { '(>= a b [c…])' }
+ value: class extends CompareOp
+ fn: (a, b) -> a >= b
+
Constant.meta
meta:
name: 'logic'
@@ -132,4 +176,8 @@ Constant.meta
and: and_
or: or_
not: not_
+
+ 'asc?': asc, '<': asc, '<=': lte
+ 'desc?': desc, '>': desc, '>=': gte
+
:bool
diff --git a/spec/lib/logic_spec.moon b/spec/lib/logic_spec.moon
index f3d0610..8e79cbd 100644
--- a/spec/lib/logic_spec.moon
+++ b/spec/lib/logic_spec.moon
@@ -2,7 +2,7 @@ import TestPilot from require 'spec.test_setup'
import T, Array, Constant from require 'alv'
describe "logic", ->
- test = TestPilot '', '(import* logic)\n'
+ test = TestPilot '', '(import* testing logic)\n'
TRUE = T.bool\mk_const true
FALSE = T.bool\mk_const false
@@ -262,3 +262,91 @@ describe "logic", ->
with COPILOT\eval_once '(and 1 1 1)'
assert.is.true \is_const!
assert.is.equal TRUE, .result
+
+ describe "<", ->
+ it "is aliased as asc?", -> COPILOT\eval_once '
+ (expect= < asc?)
+ '
+
+ it "compares numbers as expected", -> COPILOT\eval_once '
+ (assert (< -2 5))
+ (assert (not (< 3 1)))
+ (assert (not (< 1 1)))
+ '
+
+ it "can handle multiple arguments", -> COPILOT\eval_once '
+ (assert (< 1 2 3))
+ (assert (not (< 2 3.5 3 4)))
+ (assert (not (< 3 2 1)))
+ '
+
+ describe "<=", ->
+ it "compares numbers as expected", -> COPILOT\eval_once '
+ (assert (<= 1 1))
+ (assert (<= -2 2))
+ (assert (not (<= 3 2)))
+ '
+
+ it "can handle multiple arguments", -> COPILOT\eval_once '
+ (assert (<= 1 2 3))
+ (assert (<= 1 2 2 3))
+ (assert (not (<= 2 3 2.5 4)))
+ (assert (not (<= 3 2 2 1)))
+ '
+
+ describe ">", ->
+ it "is aliased as desc?", -> COPILOT\eval_once '
+ (expect= > desc?)
+ '
+
+ it "compares numbers as expected", -> COPILOT\eval_once '
+ (assert (> 3 1))
+ (assert (not (> -2 5)))
+ (assert (not (> 1 1)))
+ '
+
+ it "can handle multiple arguments", -> COPILOT\eval_once '
+ (assert (> 3 2 1))
+ (assert (not (> 5 4 3 3.5 2)))
+ (assert (not (> 1 2 3)))
+ '
+
+ describe ">=", ->
+ it "compares numbers as expected", -> COPILOT\eval_once '
+ (assert (>= 1 1))
+ (assert (>= 5 1))
+ (assert (not (>= 2 3)))
+ '
+
+ it "can handle multiple arguments", -> COPILOT\eval_once '
+ (assert (>= 3 2 1))
+ (assert (>= 3 2 2 1))
+ (assert (not (>= 5 4 3 3 3.5 2)))
+ (assert (not (>= 1 2 2 3)))
+ '
+
+ describe "<, <=, >, >=", ->
+ each = (fn) ->
+ fn '<'
+ fn '<='
+ fn '>'
+ fn '>='
+
+ it "need at least two arguments", ->
+ each =>
+ err = assert.has.error -> COPILOT\eval_once "(#{@})"
+ assert.matches "couldn't match arguments", err
+
+ err = assert.has.error -> COPILOT\eval_once "(#{@} 1)"
+ assert.matches "couldn't match arguments", err
+
+ it "only work on numbers", ->
+ each =>
+ err = assert.has.error -> COPILOT\eval_once "(#{@} 1 'b')"
+ assert.matches "couldn't match arguments", err
+
+ err = assert.has.error -> COPILOT\eval_once "(#{@} 'c' 'd')"
+ assert.matches "couldn't match arguments", err
+
+ err = assert.has.error -> COPILOT\eval_once "(#{@} true 3)"
+ assert.matches "couldn't match arguments", err