File size: 1,577 Bytes
43203b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(cl:in-package :cl-flow)

;;;
;;; ASYNCHRONOUSLY
;;;
(defun dispatch-asynchronously (flow-context body-fu)
  (funcall body-fu (flow-context-value flow-context)))


(defun continue-flow (&optional value)
  "Invokes next flow block with provided value as an argument"
  (declare (ignore value))
  (error "Function can be called inside asynchonous block only"))


(defun interrupt-flow (&optional condition)
  "Interrupts flow with provided condition"
  (declare (ignore condition))
  (error "Function can be called inside asynchonous block only"))


(defmacro asynchronously (lambda-list &body body)
  "Splits current flow allowing manually managing its execution via #'continue-flow and
#'interrupt-flow functions. Consing: ~32 bytes per invocation"
  (with-gensyms (continue-arg condi)
    (flow-lambda-macro (flow-context)
      (let ((fu-body `((flet ((continue-flow (&optional ,continue-arg)
                                (capture-flow-value ,flow-context ,continue-arg)
                                (dispatch-rest ,flow-context))
                              (interrupt-flow (&optional ,condi)
                                (error ,condi)))
                         (declare (ignorable (function continue-flow)
                                             (function interrupt-flow)))
                         ,@body))))
        (with-flow-function-macro (body-fu lambda-list fu-body)
          `(dispatch-asynchronously ,flow-context #',body-fu))))))


(defmacro %> (lambda-list &body body)
  "See flow:asynchronously"
  `(asynchronously ,lambda-list
     ,@body))