-
Notifications
You must be signed in to change notification settings - Fork 1
/
control.rkt
78 lines (65 loc) · 2.1 KB
/
control.rkt
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#lang racket
(provide %%
raise-process-escape-error
reactive-tag
empty-calling-continuation
sched-tag
switch!
debug-continuation!
compose-continuations)
(require racket/control
reactor/data
(for-syntax syntax/parse syntax/srcloc))
(module+ test (require rackunit))
(define reactive-tag (make-continuation-prompt-tag 'reaction))
(struct delete-tag (start-prompt-tag end-prompt-tag) #:authentic)
(define (raise-process-escape-error)
(error "reactive code escaped reactor context"))
;; basic continuation grabbing
(define-syntax %%
(syntax-parser
[(_ k:id body ...)
#`(begin
(unless (continuation-prompt-available? reactive-tag)
(raise-process-escape-error))
#,(syntax/loc this-syntax ((call/comp
(lambda (k) (lambda () body ...))
reactive-tag))))]))
(define empty-calling-continuation
(call/prompt
(lambda () (%% k k))
reactive-tag))
(define (compose-continuations k1 k2)
(call/prompt
(lambda ()
(k1 (lambda () (k2 (lambda () (%% k (abort/cc reactive-tag k)))))))
reactive-tag
values))
(module+ test
(define k1 (call/prompt
(lambda ()
(with-continuation-mark 1 1
(%% k (abort/cc reactive-tag k))))
reactive-tag values))
(define k2 (call/prompt
(lambda ()
(with-continuation-mark 1 2
(%% k (abort/cc reactive-tag k))))
reactive-tag values))
(check-equal?
(continuation-mark-set->list (continuation-marks (compose-continuations k1 k2)) 1)
(list 2))
(check-equal?
(continuation-mark-set->list
(continuation-marks (compose-continuations (compose-continuations k1 k2) (compose-continuations k1 k2)))
1)
(list 2)))
;; OS tags
(define sched-tag (make-continuation-prompt-tag 'sched))
;; -> Any
;; switch back to the scheduler
(define (switch!)
(abort/cc sched-tag))
(define (debug-continuation! k)
(call/prompt
(lambda () (k (lambda () (error 'debug "~a" k))))))