diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 1b61e6df..5de7dc00 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -244,26 +244,30 @@ [(,not= :error (,fiber/status ,f)) ,r]))) (defmacro and - "Evaluates to the last argument if all preceding elements are true, otherwise - evaluates to false." + "Evaluates to the last argument if all preceding elements are truthy, otherwise + evaluates to the first falsey argument." [& forms] (var ret true) (def len (length forms)) (var i len) (while (> i 0) (-- i) + (def v (in forms i)) (set ret (if (= ret true) - (in forms i) - (tuple 'if (in forms i) ret)))) + v + (if (idempotent? v) + ['if v ret v] + (do (def s (gensym)) + ['if ['def s v] ret s]))))) ret) (defmacro or - "Evaluates to the last argument if all preceding elements are false, otherwise - evaluates to true." + "Evaluates to the last argument if all preceding elements are falsey, otherwise + evaluates to the first truthy element." [& forms] - (var ret nil) (def len (length forms)) - (var i len) + (var i (- len 1)) + (var ret (in forms i)) (while (> i 0) (-- i) (def fi (in forms i)) diff --git a/test/suite8.janet b/test/suite8.janet index 4c948511..f314a53e 100644 --- a/test/suite8.janet +++ b/test/suite8.janet @@ -107,4 +107,9 @@ (assert (= nil (match [1 2] [a b c] a)) "match 4") (assert (= 2 (match [1 2] [a b] b)) "match 5") +# And/or checks + +(assert (= false (and false false)) "and 1") +(assert (= false (or false false)) "or 1") + (end-suite)