mirror of
https://github.com/janet-lang/janet
synced 2025-01-11 08:00:27 +00:00
Add defer and assert to the core.
This commit is contained in:
parent
bc2bac8cd3
commit
65be9ae095
@ -15,6 +15,9 @@ All notable changes to this project will be documented in this file.
|
||||
- Allow signaling from C functions (yielding) via janet\_signalv. This
|
||||
makes it easy to write C functions that work with event loops, such as
|
||||
in libuv or embedded in a game.
|
||||
- Add `defer`
|
||||
- Add `assert`
|
||||
- Fix thread module issue where sometimes decoding a message failed.
|
||||
- Fix segfault regression when macros are called with bad arity.
|
||||
|
||||
### 1.6.0 - 2019-12-22
|
||||
|
@ -131,6 +131,11 @@
|
||||
(defmacro /= "Shorthand for (set x (/ x n))." [x n] ~(set ,x (,/ ,x ,n)))
|
||||
(defmacro %= "Shorthand for (set x (% x n))." [x n] ~(set ,x (,% ,x ,n)))
|
||||
|
||||
(defn assert
|
||||
"Throw an error if x is not truthy."
|
||||
[x &opt err]
|
||||
(if x x (error (if err err "assert failure"))))
|
||||
|
||||
(defmacro default
|
||||
"Define a default value for an optional argument.
|
||||
Expands to (def sym (if (= nil sym) val sym))"
|
||||
@ -276,20 +281,28 @@
|
||||
(++ i))
|
||||
~(let (,;accum) ,;body))
|
||||
|
||||
(defmacro defer
|
||||
"Run form unconditionally after form, even if the body throws an error."
|
||||
[form & body]
|
||||
(with-syms [f r]
|
||||
~(do
|
||||
(def ,f (,fiber/new (fn [] ,;body) :ie))
|
||||
(def ,r (,resume ,f))
|
||||
,form
|
||||
(if (= (,fiber/status ,f) :dead)
|
||||
,r
|
||||
(propagate ,r ,f)))))
|
||||
|
||||
(defmacro with
|
||||
"Evaluate body with some resource, which will be automatically cleaned up
|
||||
if there is an error in body. binding is bound to the expression ctor, and
|
||||
dtor is a function or callable that is passed the binding. If no destructor
|
||||
(dtor) is given, will call :close on the resource."
|
||||
[[binding ctor dtor] & body]
|
||||
(with-syms [res f]
|
||||
~(let [,binding ,ctor
|
||||
,f (,fiber/new (fn [] ,;body) :ie)
|
||||
,res (,resume ,f)]
|
||||
(,(or dtor :close) ,binding)
|
||||
(if (,= (,fiber/status ,f) :error)
|
||||
(,propagate ,res ,f)
|
||||
,res))))
|
||||
~(do
|
||||
(def ,binding ,ctor)
|
||||
(defer (,(or dtor :close) ,binding)
|
||||
,;body)))
|
||||
|
||||
(defn- for-template
|
||||
[binding start stop step comparison delta body]
|
||||
|
@ -367,6 +367,9 @@ static int line() {
|
||||
case 2: /* ctrl-b */
|
||||
kleft();
|
||||
break;
|
||||
case 5: /* ctrl-e */
|
||||
gbl_pos = gbl_len;
|
||||
break;
|
||||
case 6: /* ctrl-f */
|
||||
kright();
|
||||
break;
|
||||
|
@ -6,7 +6,9 @@
|
||||
(var numchecks 0)
|
||||
(var start-time 0)
|
||||
|
||||
(defn assert [x e]
|
||||
(defn assert
|
||||
"Override's the default assert with some nice error handling."
|
||||
[x e]
|
||||
(++ num-tests-run)
|
||||
(when x (++ num-tests-passed))
|
||||
(if x
|
||||
|
Loading…
Reference in New Issue
Block a user