1
0
mirror of https://github.com/janet-lang/janet synced 2025-04-27 05:03:14 +00:00

Harden semantics for and and or macros.

There was perviously a bit of fuzziness on returning false/nil
from these macros that has been removed.
This commit is contained in:
Calvin Rose 2020-03-06 08:36:21 -06:00
parent fbe8998ca8
commit 6123c41f13
2 changed files with 17 additions and 8 deletions

View File

@ -244,26 +244,30 @@
[(,not= :error (,fiber/status ,f)) ,r]))) [(,not= :error (,fiber/status ,f)) ,r])))
(defmacro and (defmacro and
"Evaluates to the last argument if all preceding elements are true, otherwise "Evaluates to the last argument if all preceding elements are truthy, otherwise
evaluates to false." evaluates to the first falsey argument."
[& forms] [& forms]
(var ret true) (var ret true)
(def len (length forms)) (def len (length forms))
(var i len) (var i len)
(while (> i 0) (while (> i 0)
(-- i) (-- i)
(def v (in forms i))
(set ret (if (= ret true) (set ret (if (= ret true)
(in forms i) v
(tuple 'if (in forms i) ret)))) (if (idempotent? v)
['if v ret v]
(do (def s (gensym))
['if ['def s v] ret s])))))
ret) ret)
(defmacro or (defmacro or
"Evaluates to the last argument if all preceding elements are false, otherwise "Evaluates to the last argument if all preceding elements are falsey, otherwise
evaluates to true." evaluates to the first truthy element."
[& forms] [& forms]
(var ret nil)
(def len (length forms)) (def len (length forms))
(var i len) (var i (- len 1))
(var ret (in forms i))
(while (> i 0) (while (> i 0)
(-- i) (-- i)
(def fi (in forms i)) (def fi (in forms i))

View File

@ -107,4 +107,9 @@
(assert (= nil (match [1 2] [a b c] a)) "match 4") (assert (= nil (match [1 2] [a b c] a)) "match 4")
(assert (= 2 (match [1 2] [a b] b)) "match 5") (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) (end-suite)