diff options
| author | s-ol <s+removethis@s-ol.nu> | 2022-10-20 11:20:46 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-02 14:24:49 +0000 |
| commit | 56bcabd974c0c0e34fb76d653e927668aaccbdb0 (patch) | |
| tree | e8458a58b4edf72e6a7e59edccdaaaf9ed7198ab | |
| parent | builtins: test def, use, export, export* (diff) | |
| download | alive-56bcabd974c0c0e34fb76d653e927668aaccbdb0.tar.gz alive-56bcabd974c0c0e34fb76d653e927668aaccbdb0.zip | |
lib: add <,<=,>,>= to logic, add tests
| -rw-r--r-- | alv-lib/logic.moon | 48 | ||||
| -rw-r--r-- | spec/lib/logic_spec.moon | 90 |
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 |
