|
45 | 45 | continuation? composable-continuation? |
46 | 46 | continuation-prompt-available? |
47 | 47 |
|
| 48 | + with-continuation-mark with-continuation-marks |
| 49 | + continuation-mark-set? |
| 50 | + continuation-mark-set->list continuation-mark-set->list* |
| 51 | + current-continuation-marks |
| 52 | + continuation-mark-set-first |
| 53 | + call-with-immediate-continuation-mark |
| 54 | + |
| 55 | + make-continuation-mark-key continuation-mark-key? |
| 56 | + |
48 | 57 | default-continuation-prompt-tag |
49 | 58 | make-continuation-prompt-tag continuation-prompt-tag? |
50 | 59 | shift reset |
51 | 60 | prompt control) |
52 | 61 | (import (except (core) call/cc call-with-current-continuation) |
53 | 62 | (core macro) |
| 63 | + (core record) |
54 | 64 | (core conditions) |
55 | 65 | (sagittarius)) |
56 | 66 |
|
| 67 | +(define-syntax with-continuation-mark |
| 68 | + (lambda (x) |
| 69 | + (syntax-case x () |
| 70 | + ((_ k v expr ...) |
| 71 | + #'(call/cm (vector (cons k v)) (lambda () expr ...)))))) |
| 72 | +(define-syntax with-continuation-marks |
| 73 | + (lambda (x) |
| 74 | + (syntax-case x () |
| 75 | + ((_ ((k v) ...) expr ...) |
| 76 | + #'(call/cm (vector (cons k v) ...) (lambda () expr ...)))))) |
| 77 | + |
| 78 | +(define (continuation-mark-set->list mark-set key |
| 79 | + :optional (prompt-tag (default-continuation-prompt-tag))) |
| 80 | + ;; If mark-set is #f, use current-continuation-marks |
| 81 | + (let* ((ms (or mark-set (current-continuation-marks prompt-tag))) |
| 82 | + (frames (vector-ref ms 1))) |
| 83 | + (let loop ((frames frames) (result '())) |
| 84 | + (if (null? frames) |
| 85 | + (reverse! result) |
| 86 | + (let* ((frame (car frames)) |
| 87 | + (entry (assq key frame))) |
| 88 | + (if entry |
| 89 | + (loop (cdr frames) (cons (cdr entry) result)) |
| 90 | + (loop (cdr frames) result))))))) |
| 91 | + |
| 92 | +(define (continuation-mark-set->list* mark-set keys |
| 93 | + :optional (default #f) (prompt-tag (default-continuation-prompt-tag))) |
| 94 | + ;; Helper function to check if any key in keys has an entry in frame |
| 95 | + (define (has-any-key? frame keys) |
| 96 | + (let loop ((ks keys)) |
| 97 | + (cond ((null? ks) #f) |
| 98 | + ((assq (car ks) frame) #t) |
| 99 | + (else (loop (cdr ks)))))) |
| 100 | + ;; If mark-set is #f, use current-continuation-marks |
| 101 | + (let* ((ms (or mark-set (current-continuation-marks prompt-tag))) |
| 102 | + (frames (vector-ref ms 1)) |
| 103 | + (key-count (length keys))) |
| 104 | + (let loop ((frames frames) (result '())) |
| 105 | + (if (null? frames) |
| 106 | + (reverse result) |
| 107 | + (let* ((frame (car frames)) |
| 108 | + ;; Check if this frame has any of our keys |
| 109 | + (has-key? (has-any-key? frame keys))) |
| 110 | + (if has-key? |
| 111 | + (let ((vec (make-vector key-count default))) |
| 112 | + ;; Fill in values for each key |
| 113 | + (let key-loop ((ks keys) (i 0)) |
| 114 | + (if (null? ks) |
| 115 | + (loop (cdr frames) (cons vec result)) |
| 116 | + (let ((entry (assq (car ks) frame))) |
| 117 | + (when entry |
| 118 | + (vector-set! vec i (cdr entry))) |
| 119 | + (key-loop (cdr ks) (+ i 1)))))) |
| 120 | + (loop (cdr frames) result))))))) |
| 121 | + |
| 122 | +(define (continuation-mark-set-first mark-set key |
| 123 | + :optional (default #f) (prompt-tag (default-continuation-prompt-tag))) |
| 124 | + ;; If mark-set is #f, use current-continuation-marks |
| 125 | + (let* ((ms (or mark-set (current-continuation-marks prompt-tag))) |
| 126 | + (frames (vector-ref ms 1))) |
| 127 | + (let loop ((frames frames)) |
| 128 | + (if (null? frames) |
| 129 | + default |
| 130 | + (let* ((frame (car frames)) |
| 131 | + (entry (assq key frame))) |
| 132 | + (if entry |
| 133 | + (cdr entry) |
| 134 | + (loop (cdr frames)))))))) |
| 135 | + |
| 136 | +(define (continuation-mark-set->iterator . arg*) |
| 137 | + (let f ((ls (apply continuation-mark-set->list* arg*))) |
| 138 | + (lambda () |
| 139 | + (if (null? ls) |
| 140 | + (values #f |
| 141 | + (lambda () |
| 142 | + (apply assertion-violation |
| 143 | + 'continuation-mark-set->iterator |
| 144 | + "attempt to iterate past the end" |
| 145 | + arg*))) |
| 146 | + (values (car ls) (f (cdr ls))))))) |
| 147 | + |
| 148 | +(define-record-type continuation-mark-key |
| 149 | + (nongenerative) (sealed #t) (opaque #f) |
| 150 | + (fields (mutable name)) |
| 151 | + (protocol |
| 152 | + (lambda (p) |
| 153 | + (lambda (:optional ((name (or symbol? #f)) #f)) (p name))))) |
| 154 | + |
57 | 155 | ;; From SRFI-226 implementation |
58 | 156 | (define-syntax reset |
59 | 157 | (lambda (x) |
|
0 commit comments