mirror of
https://github.com/janet-lang/janet
synced 2025-07-22 03:42:54 +00:00
Add prompt
and return
.
User friendly delimited continuations. While this was doable with signals before, this does not require C and will play nicely with existing error handling, defers, and with statements.
This commit is contained in:
parent
8c41c0b6a7
commit
59d288c429
@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Correct arity for `next`
|
- Correct arity for `next`
|
||||||
- Correct arity for `marshal`
|
- Correct arity for `marshal`
|
||||||
- Add `flush` and `eflush`
|
- Add `flush` and `eflush`
|
||||||
|
- Add `prompt` and `return` on top of signal for user friendly delimited continuations.
|
||||||
|
|
||||||
## 1.7.0 - 2020-02-01
|
## 1.7.0 - 2020-02-01
|
||||||
- Remove `file/fileno` and `file/fdopen`.
|
- Remove `file/fileno` and `file/fdopen`.
|
||||||
|
@ -299,6 +299,24 @@
|
|||||||
,r
|
,r
|
||||||
(propagate ,r ,f)))))
|
(propagate ,r ,f)))))
|
||||||
|
|
||||||
|
(defmacro prompt
|
||||||
|
"Set up a prompt point that can be aborted to. Tag should be a value
|
||||||
|
that is used in a return statement, like a keyword."
|
||||||
|
[tag & body]
|
||||||
|
(with-syms [res target payload fib]
|
||||||
|
~(do
|
||||||
|
(def ,fib (,fiber/new (fn [] [,tag (do ,;body)]) :i0))
|
||||||
|
(def ,res (,resume ,fib))
|
||||||
|
(def [,target ,payload] ,res)
|
||||||
|
(if (,= ,tag ,target)
|
||||||
|
,payload
|
||||||
|
(propagate ,res ,fib)))))
|
||||||
|
|
||||||
|
(defn return
|
||||||
|
"Return to a prompt point."
|
||||||
|
[to value]
|
||||||
|
(signal 0 [to value]))
|
||||||
|
|
||||||
(defmacro with
|
(defmacro with
|
||||||
"Evaluate body with some resource, which will be automatically cleaned up
|
"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
|
if there is an error in body. binding is bound to the expression ctor, and
|
||||||
|
@ -70,4 +70,24 @@
|
|||||||
(test-bf "+[+[<<<+>>>>]+<-<-<<<+<++]<<.<++.<++..+++.<<++.<---.>>.>.+++.------.>-.>>--."
|
(test-bf "+[+[<<<+>>>>]+<-<-<<<+<++]<<.<++.<++..+++.<<++.<---.>>.>.+++.------.>-.>>--."
|
||||||
"Hello, World!")
|
"Hello, World!")
|
||||||
|
|
||||||
|
# Prompts
|
||||||
|
|
||||||
|
(assert (= 10 (prompt :a (for i 0 10 (if (= i 5) (return :a 10))))) "prompt 1")
|
||||||
|
|
||||||
|
(defn- inner-loop
|
||||||
|
[i]
|
||||||
|
(if (= i 5)
|
||||||
|
(return :a 10)))
|
||||||
|
|
||||||
|
(assert (= 10 (prompt :a (for i 0 10 (inner-loop i)))) "prompt 2")
|
||||||
|
|
||||||
|
(defn- inner-loop2
|
||||||
|
[i]
|
||||||
|
(try
|
||||||
|
(if (= i 5)
|
||||||
|
(error 10))
|
||||||
|
([err] (return :a err))))
|
||||||
|
|
||||||
|
(assert (= 10 (prompt :a (for i 0 10 (inner-loop2 i)))) "prompt 3")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user