mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Add with-vars
This helps for temporarily setting vars in a safe manner that is guaranteed not to leave vars in a bad state (assuming that a fiber does not emit debug or use signal and is never resumed).
This commit is contained in:
parent
25a9804d91
commit
6ceaf9d28d
@ -2,6 +2,7 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
- Add `with-vars` macro.
|
||||||
- Add the `quickbin` command to jpm.
|
- Add the `quickbin` command to jpm.
|
||||||
- Create shell.c when making the amlagamated source. This can be compiled with
|
- Create shell.c when making the amlagamated source. This can be compiled with
|
||||||
janet.c to make the janet interpreter.
|
janet.c to make the janet interpreter.
|
||||||
|
@ -909,6 +909,25 @@
|
|||||||
~(setdyn ,(bindings i) ,(bindings (+ i 1)))))
|
~(setdyn ,(bindings i) ,(bindings (+ i 1)))))
|
||||||
~(,resume (,fiber/new (fn [] ,;dyn-forms ,;body) :p)))
|
~(,resume (,fiber/new (fn [] ,;dyn-forms ,;body) :p)))
|
||||||
|
|
||||||
|
(defmacro with-vars
|
||||||
|
"Evaluates body with each var in vars temporarily bound. Similar signature to
|
||||||
|
let, but each binding must be a var."
|
||||||
|
[vars & body]
|
||||||
|
(def len (length vars))
|
||||||
|
(unless (even? len) (error "expected even number of argument to vars"))
|
||||||
|
(def temp (seq [i :range [0 len 2]] (gensym)))
|
||||||
|
(def saveold (seq [i :range [0 len 2]] ['def (temp (/ i 2)) (vars i)]))
|
||||||
|
(def setnew (seq [i :range [0 len 2]] ['set (vars i) (vars (+ i 1))]))
|
||||||
|
(def restoreold (seq [i :range [0 len 2]] ['set (vars i) (temp (/ i 2))]))
|
||||||
|
(with-syms [ret f s]
|
||||||
|
~(do
|
||||||
|
,;saveold
|
||||||
|
(def ,f (,fiber/new (fn [] ,;setnew ,;body) :ei))
|
||||||
|
(def ,ret (,resume ,f))
|
||||||
|
,;restoreold
|
||||||
|
(if (= (,fiber/status ,f) :error) (,propagate ,ret ,f))
|
||||||
|
,ret)))
|
||||||
|
|
||||||
(defn partial
|
(defn partial
|
||||||
"Partial function application."
|
"Partial function application."
|
||||||
[f & more]
|
[f & more]
|
||||||
@ -928,7 +947,7 @@
|
|||||||
"Reverses the order of the elements in a given array or tuple and returns a new array."
|
"Reverses the order of the elements in a given array or tuple and returns a new array."
|
||||||
[t]
|
[t]
|
||||||
(def len (length t))
|
(def len (length t))
|
||||||
(var n (dec len))
|
(var n (- len 1))
|
||||||
(def reversed (array/new len))
|
(def reversed (array/new len))
|
||||||
(while (>= n 0)
|
(while (>= n 0)
|
||||||
(array/push reversed (get t n))
|
(array/push reversed (get t n))
|
||||||
|
@ -184,4 +184,10 @@
|
|||||||
|
|
||||||
(assert (= (string '()) (string [])) "empty bracket tuple literal")
|
(assert (= (string '()) (string [])) "empty bracket tuple literal")
|
||||||
|
|
||||||
|
# with-vars
|
||||||
|
(var abc 123)
|
||||||
|
(assert (= 356 (with-vars [abc 456] (- abc 100))) "with-vars 1")
|
||||||
|
(assert-error "with-vars 2" (with-vars [abc 456] (error :oops)))
|
||||||
|
(assert (= abc 123) "with-vars 3")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user