From 962cd7e5f5e5047385c75557a6a7bdd3709116e1 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Wed, 15 Jan 2020 22:49:41 -0600 Subject: [PATCH] Add when-with and if-with This is useful for reading from files. --- CHANGELOG.md | 2 ++ src/boot/boot.janet | 16 ++++++++++++++++ test/suite7.janet | 13 +++++++++++++ 3 files changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a175acc..8b3e570a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. in libuv or embedded in a game. - Add `defer` - Add `assert` +- Add `when-with` +- Add `if-with` - Fix thread module issue where sometimes decoding a message failed. - Fix segfault regression when macros are called with bad arity. diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 10ff904b..6d8f5625 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -304,6 +304,22 @@ (defer (,(or dtor :close) ,binding) ,;body))) +(defmacro when-with + "Similar to with, but if binding is false or nil, returns + nil without evaluating the body. Otherwise, the same as with." + [[binding ctor dtor] & body] + ~(if-let [,binding ,ctor] + (defer (,(or dtor :close) ,binding) + ,;body))) + +(defmacro if-with + "Similar to with, but if binding is false or nil, returns + nil without evaluating the body. Otherwise, the same as with." + [[binding ctor dtor] truthy &opt falsey ] + ~(if-let [,binding ,ctor] + (defer (,(or dtor :close) ,binding) ,truthy) + ,falsey)) + (defn- for-template [binding start stop step comparison delta body] (with-syms [i s] diff --git a/test/suite7.janet b/test/suite7.janet index 520210aa..cdffc3c9 100644 --- a/test/suite7.janet +++ b/test/suite7.janet @@ -286,4 +286,17 @@ (file/seek f :set 0) (assert (= (string (file/read f :all)) "foo\n") "temp files work")) +(var counter 0) +(when-with [x nil |$] + (++ counter)) +(when-with [x 10 |$] + (+= counter 10)) + +(assert (= 10 counter) "when-with 1") + +(if-with [x nil |$] (++ counter) (+= counter 10)) +(if-with [x true |$] (+= counter 20) (+= counter 30)) + +(assert (= 40 counter) "if-with 1") + (end-suite)