| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
(define-syntax define-macro |
|---|
| 5 |
(syntax-rules () |
|---|
| 6 |
((_ (id . llist) . body) |
|---|
| 7 |
(define-syntax id |
|---|
| 8 |
(rsc-macro-transformer |
|---|
| 9 |
(lambda (exp env) |
|---|
| 10 |
(apply (lambda llist . body) (cdr exp)))))) |
|---|
| 11 |
((_ id expander) |
|---|
| 12 |
(define-syntax id |
|---|
| 13 |
(rsc-macro-transformer |
|---|
| 14 |
(lambda (exp env) |
|---|
| 15 |
(apply expander (cdr exp)))))))) |
|---|
| 16 |
|
|---|
| 17 |
(define-syntax include |
|---|
| 18 |
(rsc-macro-transformer |
|---|
| 19 |
(lambda (exp env) |
|---|
| 20 |
(syntax-check '(keyword expression) exp) |
|---|
| 21 |
(let ((filename (cadr exp))) |
|---|
| 22 |
(let ((path (##sys#resolve-include-filename filename #t))) |
|---|
| 23 |
(if (load-verbose) (print "; including " path " ...")) |
|---|
| 24 |
`(,(make-syntactic-closure env '() 'begin) |
|---|
| 25 |
,@(with-input-from-file path |
|---|
| 26 |
(lambda () |
|---|
| 27 |
(do ((x (read) (read)) |
|---|
| 28 |
(xs '() (cons x xs))) |
|---|
| 29 |
((eof-object? x) |
|---|
| 30 |
(reverse xs))))))))))) |
|---|
| 31 |
|
|---|
| 32 |
(define-syntax cond-expand |
|---|
| 33 |
(sc-macro-transformer |
|---|
| 34 |
(lambda (form env) |
|---|
| 35 |
(capture-syntactic-environment |
|---|
| 36 |
(lambda (transformer-env) |
|---|
| 37 |
|
|---|
| 38 |
(define (err x) |
|---|
| 39 |
(syntax-error "syntax error in `cond-expand' form" x form)) |
|---|
| 40 |
(define (literal=? usage-id transformer-id) |
|---|
| 41 |
(and (identifier? usage-id) |
|---|
| 42 |
(identifier=? env usage-id transformer-env transformer-id))) |
|---|
| 43 |
(define (close-forms forms) |
|---|
| 44 |
(map (lambda (form) (make-syntactic-closure env '() form)) forms)) |
|---|
| 45 |
(define (test fx) |
|---|
| 46 |
(cond ((identifier? fx) |
|---|
| 47 |
(##sys#feature? (identifier->symbol fx))) |
|---|
| 48 |
((not (pair? fx)) (err fx)) |
|---|
| 49 |
(else |
|---|
| 50 |
(let ((bool (##sys#slot fx 0)) |
|---|
| 51 |
(rest (##sys#slot fx 1))) |
|---|
| 52 |
(if (literal=? bool bool) |
|---|
| 53 |
(case bool |
|---|
| 54 |
((and) |
|---|
| 55 |
(or (eq? rest '()) |
|---|
| 56 |
(if (pair? rest) |
|---|
| 57 |
(and (test (##sys#slot rest 0)) |
|---|
| 58 |
(test `(and ,@(##sys#slot rest 1)))) |
|---|
| 59 |
(err fx)))) |
|---|
| 60 |
((or) |
|---|
| 61 |
(and (not (eq? rest '())) |
|---|
| 62 |
(if (pair? rest) |
|---|
| 63 |
(or (test (##sys#slot rest 0)) |
|---|
| 64 |
(test `(or ,@(##sys#slot rest 1)))) |
|---|
| 65 |
(err fx)))) |
|---|
| 66 |
((not) (not (test (cadr fx)))) |
|---|
| 67 |
(else (err fx))) |
|---|
| 68 |
(err fx)))))) |
|---|
| 69 |
|
|---|
| 70 |
(let ((clauses (cdr form))) |
|---|
| 71 |
(let expand ((cls clauses)) |
|---|
| 72 |
(cond ((null? cls) |
|---|
| 73 |
(##sys#apply |
|---|
| 74 |
##sys#error "no matching clause in `cond-expand' form" |
|---|
| 75 |
(map car clauses))) |
|---|
| 76 |
((not (pair? cls)) (err cls)) |
|---|
| 77 |
(else |
|---|
| 78 |
(let ((clause (##sys#slot cls 0)) |
|---|
| 79 |
(rclauses (##sys#slot cls 1))) |
|---|
| 80 |
(if (not (pair? clause)) |
|---|
| 81 |
(err clause) |
|---|
| 82 |
(let ((id (##sys#slot clause 0))) |
|---|
| 83 |
(cond ((literal=? id 'else) |
|---|
| 84 |
(let ((rest (##sys#slot clause 1))) |
|---|
| 85 |
(if (null? rest) |
|---|
| 86 |
'(##core#undefined) |
|---|
| 87 |
`(begin ,@(close-forms rest))))) |
|---|
| 88 |
((test id) `(begin ,@(close-forms |
|---|
| 89 |
(##sys#slot clause 1)))) |
|---|
| 90 |
(else (expand rclauses))))))))))))))) |
|---|
| 91 |
|
|---|
| 92 |
(define-syntax when |
|---|
| 93 |
(syntax-rules () |
|---|
| 94 |
((_ x y z ...) (if x (begin y z ...))))) |
|---|
| 95 |
|
|---|
| 96 |
(define-syntax unless |
|---|
| 97 |
(syntax-rules () |
|---|
| 98 |
((_ x y z ...) (if x (##core#undefined) (begin y z ...))))) |
|---|
| 99 |
|
|---|
| 100 |
(define-syntax receive |
|---|
| 101 |
(syntax-rules () |
|---|
| 102 |
((_ vars) (##sys#call-with-values (lambda () vars) ##sys#list)) |
|---|
| 103 |
((_ vars x0 x1 x2 ...) |
|---|
| 104 |
(##sys#call-with-values |
|---|
| 105 |
(lambda () x0) |
|---|
| 106 |
(lambda vars x1 x2 ...))))) |
|---|
| 107 |
|
|---|
| 108 |
(define-syntax time |
|---|
| 109 |
(syntax-rules () |
|---|
| 110 |
((_ exp ...) |
|---|
| 111 |
(begin |
|---|
| 112 |
(##sys#start-timer) |
|---|
| 113 |
(##sys#call-with-values |
|---|
| 114 |
(lambda () exp ...) |
|---|
| 115 |
(lambda tmp |
|---|
| 116 |
(##sys#display-times (##sys#stop-timer)) |
|---|
| 117 |
(##sys#apply ##sys#values tmp))))))) |
|---|
| 118 |
|
|---|
| 119 |
(define-syntax assert |
|---|
| 120 |
(syntax-rules () |
|---|
| 121 |
((_ exp) |
|---|
| 122 |
(assert exp (##core#immutable '"assertion failed"))) |
|---|
| 123 |
((_ exp msg arg1 ...) |
|---|
| 124 |
(if (##core#check exp) |
|---|
| 125 |
(##core#undefined) |
|---|
| 126 |
(##sys#error msg 'exp arg1 ...))))) |
|---|
| 127 |
|
|---|
| 128 |
(define-syntax ensure |
|---|
| 129 |
(syntax-rules () |
|---|
| 130 |
((_ pred exp) |
|---|
| 131 |
(let ((tmp exp)) |
|---|
| 132 |
(if (##core#check (pred tmp)) |
|---|
| 133 |
tmp |
|---|
| 134 |
(##sys#error (##core#immutable '"argument has incorrect type") tmp 'pred)))) |
|---|
| 135 |
((_ pred exp arg1 arg2 ...) |
|---|
| 136 |
(let ((tmp exp)) |
|---|
| 137 |
(if (##core#check (pred tmp)) |
|---|
| 138 |
tmp |
|---|
| 139 |
(##sys#error arg1 arg2 ...)))))) |
|---|
| 140 |
|
|---|
| 141 |
(define-syntax case-lambda |
|---|
| 142 |
(syntax-rules () |
|---|
| 143 |
((case-lambda |
|---|
| 144 |
(?a1 ?e1 ...) |
|---|
| 145 |
?clause1 ...) |
|---|
| 146 |
(lambda args |
|---|
| 147 |
(let ((l (length args))) |
|---|
| 148 |
(case-lambda "CLAUSE" args l |
|---|
| 149 |
(?a1 ?e1 ...) |
|---|
| 150 |
?clause1 ...)))) |
|---|
| 151 |
((case-lambda "CLAUSE" ?args ?l |
|---|
| 152 |
((?a1 ...) ?e1 ...) |
|---|
| 153 |
?clause1 ...) |
|---|
| 154 |
(if (eq? ?l (length '(?a1 ...))) |
|---|
| 155 |
(##sys#apply (lambda (?a1 ...) ?e1 ...) ?args) |
|---|
| 156 |
(case-lambda "CLAUSE" ?args ?l |
|---|
| 157 |
?clause1 ...))) |
|---|
| 158 |
((case-lambda "CLAUSE" ?args ?l |
|---|
| 159 |
((?a1 . ?ar) ?e1 ...) |
|---|
| 160 |
?clause1 ...) |
|---|
| 161 |
(case-lambda "IMPROPER" ?args ?l 1 (?a1 . ?ar) (?ar ?e1 ...) |
|---|
| 162 |
?clause1 ...)) |
|---|
| 163 |
((case-lambda "CLAUSE" ?args ?l |
|---|
| 164 |
(?a1 ?e1 ...) |
|---|
| 165 |
?clause1 ...) |
|---|
| 166 |
(let ((?a1 ?args)) |
|---|
| 167 |
?e1 ...)) |
|---|
| 168 |
((case-lambda "CLAUSE" ?args ?l) |
|---|
| 169 |
(##core#check (##sys#error (##core#immutable '"wrong number of arguments to CASE-LAMBDA.")))) |
|---|
| 170 |
((case-lambda "IMPROPER" ?args ?l ?k ?al ((?a1 . ?ar) ?e1 ...) |
|---|
| 171 |
?clause1 ...) |
|---|
| 172 |
(case-lambda "IMPROPER" ?args ?l (+ ?k 1) ?al (?ar ?e1 ...) |
|---|
| 173 |
?clause1 ...)) |
|---|
| 174 |
((case-lambda "IMPROPER" ?args ?l ?k ?al (?ar ?e1 ...) |
|---|
| 175 |
?clause1 ...) |
|---|
| 176 |
(if (fx>= ?l ?k) |
|---|
| 177 |
(##sys#apply (lambda ?al ?e1 ...) ?args) |
|---|
| 178 |
(case-lambda "CLAUSE" ?args ?l |
|---|
| 179 |
?clause1 ...))))) |
|---|
| 180 |
|
|---|
| 181 |
(define-syntax and-let* |
|---|
| 182 |
(syntax-rules () |
|---|
| 183 |
((and-let* () body ...) |
|---|
| 184 |
(begin body ...)) |
|---|
| 185 |
|
|---|
| 186 |
((and-let* ((var expr) clauses ...) body ...) |
|---|
| 187 |
(let ((var expr)) |
|---|
| 188 |
(if var (and-let* (clauses ...) body ...) #f))) |
|---|
| 189 |
|
|---|
| 190 |
((and-let* ((expr) clauses ...) body ...) |
|---|
| 191 |
(if expr (and-let* (clauses ...) body ...) #f)) |
|---|
| 192 |
|
|---|
| 193 |
((and-let* (var clauses ...) body ...) |
|---|
| 194 |
(if var (and-let* (clauses ...) body ...) #f)))) |
|---|
| 195 |
|
|---|
| 196 |
(define-syntax let*-values |
|---|
| 197 |
(syntax-rules () |
|---|
| 198 |
((_ () exp1 ...) (let () exp1 ...)) |
|---|
| 199 |
((_ (binding0 binding1 ...) exp0 exp1 ...) |
|---|
| 200 |
(let-values (binding0) |
|---|
| 201 |
(let*-values (binding1 ...) exp0 exp1 ...))))) |
|---|
| 202 |
|
|---|
| 203 |
(define-syntax let-values |
|---|
| 204 |
(syntax-rules () |
|---|
| 205 |
((let-values (?binding ...) ?body0 ?body1 ...) |
|---|
| 206 |
(let-values "bind" (?binding ...) () (begin ?body0 ?body1 ...))) |
|---|
| 207 |
|
|---|
| 208 |
((let-values "bind" () ?tmps ?body) |
|---|
| 209 |
(let ?tmps ?body)) |
|---|
| 210 |
|
|---|
| 211 |
((let-values "bind" ((?b0 ?e0) ?binding ...) ?tmps ?body) |
|---|
| 212 |
(let-values "mktmp" ?b0 ?e0 () (?binding ...) ?tmps ?body)) |
|---|
| 213 |
|
|---|
| 214 |
((let-values "mktmp" () ?e0 ?args ?bindings ?tmps ?body) |
|---|
| 215 |
(call-with-values |
|---|
| 216 |
(lambda () ?e0) |
|---|
| 217 |
(lambda ?args |
|---|
| 218 |
(let-values "bind" ?bindings ?tmps ?body)))) |
|---|
| 219 |
|
|---|
| 220 |
((let-values "mktmp" (?a . ?b) ?e0 (?arg ...) ?bindings (?tmp ...) ?body) |
|---|
| 221 |
(let-values "mktmp" ?b ?e0 (?arg ... x) ?bindings (?tmp ... (?a x)) ?body)) |
|---|
| 222 |
|
|---|
| 223 |
((let-values "mktmp" ?a ?e0 (?arg ...) ?bindings (?tmp ...) ?body) |
|---|
| 224 |
(call-with-values |
|---|
| 225 |
(lambda () ?e0) |
|---|
| 226 |
(lambda (?arg ... . x) |
|---|
| 227 |
(let-values "bind" ?bindings (?tmp ... (?a x)) ?body)))))) |
|---|
| 228 |
|
|---|
| 229 |
(define-syntax switch |
|---|
| 230 |
(syntax-rules (else) |
|---|
| 231 |
((_ v (else e1 e2 ...)) |
|---|
| 232 |
(begin e1 e2 ...)) |
|---|
| 233 |
((_ v (k e1 e2 ...)) |
|---|
| 234 |
(let ((x v)) |
|---|
| 235 |
(if (eqv? x k) (begin e1 e2 ...)))) |
|---|
| 236 |
((_ v (k e1 e2 ...) c1 c2 ...) |
|---|
| 237 |
(let ((x v)) |
|---|
| 238 |
(if (eqv? x k) |
|---|
| 239 |
(begin e1 e2 ...) |
|---|
| 240 |
(switch x c1 c2 ...)))))) |
|---|
| 241 |
|
|---|
| 242 |
(define-syntax optional |
|---|
| 243 |
(syntax-rules () |
|---|
| 244 |
((_ rest default) |
|---|
| 245 |
(let ((tmp rest)) |
|---|
| 246 |
(cond ((null? tmp) default) |
|---|
| 247 |
((null? (cdr tmp)) (car tmp)) |
|---|
| 248 |
(else (##core#check (##sys#error (##core#immutable '"too many optional arguments") tmp)))))))) |
|---|
| 249 |
|
|---|
| 250 |
(define-syntax :optional |
|---|
| 251 |
(syntax-rules () |
|---|
| 252 |
((_ . rest) (optional . rest)))) |
|---|
| 253 |
|
|---|
| 254 |
(define-syntax let-optionals* |
|---|
| 255 |
(syntax-rules () |
|---|
| 256 |
((_ rest () body ...) (let () body ...)) |
|---|
| 257 |
((_ rest ((var default) . more) body ...) |
|---|
| 258 |
(let* ((tmp rest) |
|---|
| 259 |
(var (if (null? tmp) default (car tmp))) |
|---|
| 260 |
(rest2 (if (null? tmp) '() (cdr tmp)))) |
|---|
| 261 |
(let-optionals* rest2 more body ...))) |
|---|
| 262 |
((_ rest (var) body ...) (let ((var rest)) body ...)))) |
|---|
| 263 |
|
|---|
| 264 |
|
|---|
| 265 |
|
|---|
| 266 |
|
|---|
| 267 |
|
|---|
| 268 |
(define-syntax let-optionals |
|---|
| 269 |
(syntax-rules () |
|---|
| 270 |
((let-optionals ("step") rest (tmps ...) ((var default) . vars) body) |
|---|
| 271 |
(let-optionals ("step") rest (tmps ... (var tmp default)) vars body)) |
|---|
| 272 |
((let-optionals ("step") rest ((var tmp default) ...) () body) |
|---|
| 273 |
(let-optionals* rest ((tmp default) ...) |
|---|
| 274 |
(let ((var tmp) ...) |
|---|
| 275 |
body))) |
|---|
| 276 |
((let-optionals rest vars body ...) |
|---|
| 277 |
(let-optionals ("step") rest () vars (begin body ...))))) |
|---|
| 278 |
|
|---|
| 279 |
(define-syntax define-inline |
|---|
| 280 |
(syntax-rules () |
|---|
| 281 |
((_ head . body) |
|---|
| 282 |
(define head . body)))) |
|---|
| 283 |
|
|---|
| 284 |
(define-syntax define-constant |
|---|
| 285 |
(syntax-rules () |
|---|
| 286 |
((_ name val) (define name val)))) |
|---|
| 287 |
|
|---|
| 288 |
(define-syntax critical-section |
|---|
| 289 |
(syntax-rules () |
|---|
| 290 |
((_ body ...) |
|---|
| 291 |
(##sys#dynamic-wind |
|---|
| 292 |
##sys#disable-interrupts |
|---|
| 293 |
(lambda () body ...) |
|---|
| 294 |
##sys#enable-interrupts)))) |
|---|
| 295 |
|
|---|
| 296 |
(define-syntax nth-value |
|---|
| 297 |
(syntax-rules () |
|---|
| 298 |
((_ i exp) |
|---|
| 299 |
(##sys#call-with-values |
|---|
| 300 |
(lambda () exp) |
|---|
| 301 |
(lambda lst (list-ref lst i)))))) |
|---|
| 302 |
|
|---|
| 303 |
(define-syntax define-record-printer |
|---|
| 304 |
(syntax-rules () |
|---|
| 305 |
((_ (name var1 var2) body ...) |
|---|
| 306 |
(##sys#register-record-printer 'name (lambda (var1 var2) body ...))) |
|---|
| 307 |
((_ name proc) (##sys#register-record-printer 'name proc)))) |
|---|
| 308 |
|
|---|
| 309 |
(define-syntax handle-exceptions |
|---|
| 310 |
(syntax-rules () |
|---|
| 311 |
((_ var handle-body e1 e2 ...) |
|---|
| 312 |
((call-with-current-continuation |
|---|
| 313 |
(lambda (k) |
|---|
| 314 |
(with-exception-handler |
|---|
| 315 |
(lambda (var) (k (lambda () handle-body))) |
|---|
| 316 |
(lambda () |
|---|
| 317 |
(##sys#call-with-values |
|---|
| 318 |
(lambda () e1 e2 ...) |
|---|
| 319 |
(lambda args (k (lambda () (##sys#apply ##sys#values args))))))))))))) |
|---|
| 320 |
|
|---|
| 321 |
(define-syntax condition-case |
|---|
| 322 |
(syntax-rules () |
|---|
| 323 |
((_ "1" exvar kvar) (##sys#signal exvar)) |
|---|
| 324 |
((_ "1" exvar kvar (() body ...) . more) (let () body ...)) |
|---|
| 325 |
((_ "1" exvar kvar (var () body ...) . more) (let ((var exvar)) body ...)) |
|---|
| 326 |
((_ "1" exvar kvar ((kind ...) body ...) . more) |
|---|
| 327 |
(if (and kvar (memv 'kind kvar) ...) |
|---|
| 328 |
(let () body ...) |
|---|
| 329 |
(condition-case "1" exvar kvar . more))) |
|---|
| 330 |
((_ "1" exvar kvar (var (kind ...) body ...) . more) |
|---|
| 331 |
(if (and kvar (memv 'kind kvar) ...) |
|---|
| 332 |
(let ((var exvar)) body ...) |
|---|
| 333 |
(condition-case "1" exvar kvar . more))) |
|---|
| 334 |
((_ exp clauses ...) |
|---|
| 335 |
(handle-exceptions exvar |
|---|
| 336 |
(let ((kvar (and (##sys#structure? exvar 'condition) (##sys#slot exvar 1)))) |
|---|
| 337 |
(condition-case "1" exvar kvar clauses ...)) |
|---|
| 338 |
exp)))) |
|---|
| 339 |
|
|---|
| 340 |
(define-syntax define-class |
|---|
| 341 |
(syntax-rules () |
|---|
| 342 |
((_ name () slots) |
|---|
| 343 |
(define-class name (<object>) slots)) |
|---|
| 344 |
((_ name supers slots) |
|---|
| 345 |
(define-class name supers slots <class>)) |
|---|
| 346 |
((_ name () slots meta) |
|---|
| 347 |
(define-class name (<object>) slots meta)) |
|---|
| 348 |
((_ cname (supers ...) (slots ...) meta) |
|---|
| 349 |
(define cname (make meta 'name 'cname 'direct-supers (list supers ...) 'direct-slots (list 'slots ...)))))) |
|---|
| 350 |
|
|---|
| 351 |
(define-syntax define-generic |
|---|
| 352 |
(syntax-rules () |
|---|
| 353 |
((_ n class) (define n (make class 'name 'n))) |
|---|
| 354 |
((_ n) (define n (make-generic 'n))))) |
|---|
| 355 |
|
|---|
| 356 |
(define-syntax require-for-syntax |
|---|
| 357 |
(syntax-rules () |
|---|
| 358 |
((_ names ...) |
|---|
| 359 |
(##core#require-for-syntax names ...)))) |
|---|
| 360 |
|
|---|
| 361 |
(define-syntax require-extension |
|---|
| 362 |
(syntax-rules () |
|---|
| 363 |
((_ names ...) (##core#require-extension 'names ...)))) |
|---|
| 364 |
|
|---|
| 365 |
(define-syntax use require-extension) |
|---|
| 366 |
|
|---|
| 367 |
(define-syntax cut |
|---|
| 368 |
(syntax-rules (<> <...>) |
|---|
| 369 |
|
|---|
| 370 |
|
|---|
| 371 |
|
|---|
| 372 |
((_ "1" (slot-name ...) (proc arg ...)) |
|---|
| 373 |
(lambda (slot-name ...) ((begin proc) arg ...))) |
|---|
| 374 |
((_ "1" (slot-name ...) (proc arg ...) <...>) |
|---|
| 375 |
(lambda (slot-name ... . rest-slot) (apply proc arg ... rest-slot))) |
|---|
| 376 |
|
|---|
| 377 |
|
|---|
| 378 |
((_ "1" (slot-name ...) (position ...) <> . se) |
|---|
| 379 |
(cut "1" (slot-name ... x) (position ... x) . se)) |
|---|
| 380 |
((_ "1" (slot-name ...) (position ...) nse . se) |
|---|
| 381 |
(cut "1" (slot-name ...) (position ... nse) . se)) |
|---|
| 382 |
|
|---|
| 383 |
((_ . slots-or-exprs) |
|---|
| 384 |
(cut "1" () () . slots-or-exprs)))) |
|---|
| 385 |
|
|---|
| 386 |
(define-syntax cute |
|---|
| 387 |
(syntax-rules (<> <...>) |
|---|
| 388 |
|
|---|
| 389 |
|
|---|
| 390 |
|
|---|
| 391 |
((_ "1" |
|---|
| 392 |
(slot-name ...) nse-bindings (proc arg ...)) |
|---|
| 393 |
(let nse-bindings (lambda (slot-name ...) (proc arg ...)))) |
|---|
| 394 |
|
|---|
| 395 |
((_ "1" |
|---|
| 396 |
(slot-name ...) nse-bindings (proc arg ...) <...>) |
|---|
| 397 |
(let nse-bindings (lambda (slot-name ... . x) (apply proc arg ... x)))) |
|---|
| 398 |
|
|---|
| 399 |
|
|---|
| 400 |
((_ "1" |
|---|
| 401 |
(slot-name ...) nse-bindings (position ...) <> . se) |
|---|
| 402 |
(cute "1" |
|---|
| 403 |
(slot-name ... x) nse-bindings (position ... x) . se)) |
|---|
| 404 |
|
|---|
| 405 |
((_ "1" |
|---|
| 406 |
slot-names nse-bindings (position ...) nse . se) |
|---|
| 407 |
(cute "1" |
|---|
| 408 |
slot-names ((x nse) . nse-bindings) (position ... x) . se)) |
|---|
| 409 |
|
|---|
| 410 |
((cute . slots-or-exprs) |
|---|
| 411 |
(cute "1" () () () . slots-or-exprs)))) |
|---|
| 412 |
|
|---|
| 413 |
(define-syntax let-string-start+end |
|---|
| 414 |
(syntax-rules () |
|---|
| 415 |
((let-string-start+end (start end) proc s-exp args-exp body ...) |
|---|
| 416 |
(receive (start end) (string-parse-final-start+end proc s-exp args-exp) |
|---|
| 417 |
body ...)) |
|---|
| 418 |
((let-string-start+end (start end rest) proc s-exp args-exp body ...) |
|---|
| 419 |
(receive (rest start end) (string-parse-start+end proc s-exp args-exp) |
|---|
| 420 |
body ...)))) |
|---|
| 421 |
|
|---|
| 422 |
(define-syntax rec |
|---|
| 423 |
(syntax-rules () |
|---|
| 424 |
((rec (NAME . VARIABLES) . BODY) |
|---|
| 425 |
(letrec ( (NAME (lambda VARIABLES . BODY))) NAME)) |
|---|
| 426 |
((rec NAME EXPRESSION) |
|---|
| 427 |
(letrec ( (NAME EXPRESSION)) NAME)))) |
|---|
| 428 |
|
|---|
| 429 |
(define-syntax define-record |
|---|
| 430 |
(sc-macro-transformer |
|---|
| 431 |
(lambda (form env) |
|---|
| 432 |
(define (identifier->string x) |
|---|
| 433 |
(symbol->string (identifier->symbol x))) |
|---|
| 434 |
(define construct-name |
|---|
| 435 |
(lambda (prefix . args) |
|---|
| 436 |
(##sys#string->qualified-symbol |
|---|
| 437 |
prefix |
|---|
| 438 |
(##sys#apply string-append |
|---|
| 439 |
(map (lambda (x) (if (string? x) x (identifier->string x))) |
|---|
| 440 |
args))))) |
|---|
| 441 |
(syntax-check '(keyword identifier * identifier) form) |
|---|
| 442 |
(let* ((name (cadr form)) |
|---|
| 443 |
(slots (cddr form)) |
|---|
| 444 |
(setters (memq #:record-setters ##sys#features)) |
|---|
| 445 |
(prefix (##sys#qualified-symbol-prefix (identifier->symbol name)))) |
|---|
| 446 |
(capture-syntactic-environment |
|---|
| 447 |
(lambda (xenv) |
|---|
| 448 |
(define (close id) |
|---|
| 449 |
(make-syntactic-closure xenv '() id)) |
|---|
| 450 |
`(begin |
|---|
| 451 |
(define ,(construct-name prefix "make-" name) |
|---|
| 452 |
(lambda ,slots (,(close '##sys#make-structure) ',name ,@slots))) |
|---|
| 453 |
(define ,(construct-name prefix name "?") |
|---|
| 454 |
(lambda (x) (##sys#structure? x ',name))) |
|---|
| 455 |
,@(let mapslots ((slots slots) (i 1)) |
|---|
| 456 |
(if (eq? slots '()) |
|---|
| 457 |
slots |
|---|
| 458 |
(let* ((slotname (identifier->string (##sys#slot slots 0))) |
|---|
| 459 |
(setr (construct-name prefix name "-" slotname "-set!")) |
|---|
| 460 |
(getr (construct-name prefix name "-" slotname))) |
|---|
| 461 |
(cons |
|---|
| 462 |
`(begin |
|---|
| 463 |
(define ,setr |
|---|
| 464 |
(lambda (x val) |
|---|
| 465 |
(##core#check (##sys#check-structure x ',name)) |
|---|
| 466 |
(##sys#block-set! x ,i val))) |
|---|
| 467 |
(define ,getr |
|---|
| 468 |
,(if setters |
|---|
| 469 |
`(getter-with-setter |
|---|
| 470 |
(lambda (x) |
|---|
| 471 |
(##core#check (##sys#check-structure x ',name)) |
|---|
| 472 |
(##sys#block-ref x ,i)) |
|---|
| 473 |
,setr) |
|---|
| 474 |
`(lambda (x) |
|---|
| 475 |
(##core#check (##sys#check-structure x ',name)) |
|---|
| 476 |
(##sys#block-ref x ,i))))) |
|---|
| 477 |
(mapslots (##sys#slot slots 1) (fx+ i 1))))))))))))) |
|---|
| 478 |
|
|---|
| 479 |
|
|---|
| 480 |
|
|---|
| 481 |
(define-syntax define-record-type |
|---|
| 482 |
(sc-macro-transformer |
|---|
| 483 |
(lambda (form env) |
|---|
| 484 |
(define (memi id ids) |
|---|
| 485 |
(and (not (null? ids)) |
|---|
| 486 |
(or (identifier=? env id env (car ids)) |
|---|
| 487 |
(memi id (cdr ids))))) |
|---|
| 488 |
(define (close id) |
|---|
| 489 |
(make-syntactic-closure env '() id)) |
|---|
| 490 |
(syntax-check '(keyword identifier (+ identifier) |
|---|
| 491 |
identifier * (+ identifier)) form) |
|---|
| 492 |
(let ((t (cadr form)) |
|---|
| 493 |
(conser (caddr form)) |
|---|
| 494 |
(pred (cadddr form)) |
|---|
| 495 |
(slots (cddddr form))) |
|---|
| 496 |
(let ((vars (cdr conser)) |
|---|
| 497 |
(slotnames (map car slots)) |
|---|
| 498 |
(setters? (memq #:record-setters ##sys#features))) |
|---|
| 499 |
|
|---|
| 500 |
`(begin |
|---|
| 501 |
(define ,conser |
|---|
| 502 |
(##sys#make-structure |
|---|
| 503 |
',t |
|---|
| 504 |
,@(map (lambda (sname) |
|---|
| 505 |
(if (memi sname vars) |
|---|
| 506 |
sname |
|---|
| 507 |
'(##sys#void))) |
|---|
| 508 |
slotnames))) |
|---|
| 509 |
(define (,pred x) (##sys#structure? x ',t)) |
|---|
| 510 |
,@(let loop ((slots slots) (i 1) (deferred-sets '())) |
|---|
| 511 |
(if (null? slots) |
|---|
| 512 |
deferred-sets |
|---|
| 513 |
(let* ((slot (car slots)) |
|---|
| 514 |
(get (cadr slot)) |
|---|
| 515 |
(set (and (pair? (cddr slot)) (caddr slot))) |
|---|
| 516 |
(getr `(lambda (x) |
|---|
| 517 |
(##core#check (##sys#check-structure x ',t)) |
|---|
| 518 |
(##sys#block-ref x ,i))) |
|---|
| 519 |
(get/set (and set setters? |
|---|
| 520 |
`(set! ,(close get) |
|---|
| 521 |
(getter-with-setter ,getr ,(close set)))))) |
|---|
| 522 |
`(,@(if set |
|---|
| 523 |
`((define (,set x y) |
|---|
| 524 |
(##core#check (##sys#check-structure x ',t)) |
|---|
| 525 |
(##sys#block-set! x ,i y))) |
|---|
| 526 |
'()) |
|---|
| 527 |
(define ,get ,(if get/set (##sys#void) getr)) |
|---|
| 528 |
,@(loop (cdr slots) (add1 i) |
|---|
| 529 |
(if get/set |
|---|
| 530 |
(cons get/set deferred-sets) |
|---|
| 531 |
deferred-sets)))))))))))) |
|---|
| 532 |
|
|---|
| 533 |
(define-syntax define-extension |
|---|
| 534 |
(sc-macro-transformer |
|---|
| 535 |
(lambda (form env) |
|---|
| 536 |
(syntax-check '(keyword identifier * (identifier * expression)) form) |
|---|
| 537 |
(capture-syntactic-environment |
|---|
| 538 |
(lambda (xenv) |
|---|
| 539 |
(define (literal=? usage-id transformer-id) |
|---|
| 540 |
(and (identifier? usage-id) |
|---|
| 541 |
(identifier=? env usage-id xenv transformer-id))) |
|---|
| 542 |
(define (close expr) |
|---|
| 543 |
(make-syntactic-closure env '() expr)) |
|---|
| 544 |
|
|---|
| 545 |
(let ((name (identifier->symbol (cadr form))) |
|---|
| 546 |
(clauses (cddr form))) |
|---|
| 547 |
(let loop ((s '()) (d '()) (cs clauses) (exports #f)) |
|---|
| 548 |
(if (null? cs) |
|---|
| 549 |
(let ((exps (if exports `(declare (export ,@(map close exports))) '(begin)))) |
|---|
| 550 |
`(cond-expand |
|---|
| 551 |
(chicken-compile-shared ,exps ,@d) |
|---|
| 552 |
((not compiling) ,@d) |
|---|
| 553 |
(else |
|---|
| 554 |
(declare (unit ,name)) |
|---|
| 555 |
,exps |
|---|
| 556 |
(provide ',name) |
|---|
| 557 |
,@s))) |
|---|
| 558 |
(let ((t (caar cs)) |
|---|
| 559 |
(next (cdr cs))) |
|---|
| 560 |
(cond ((literal=? t 'static) (loop (cons `(begin ,@(map close (cdar cs))) s) d next exports)) |
|---|
| 561 |
((literal=? t 'dynamic) (loop s (cons `(begin ,@(map close (cdar cs))) d) next exports)) |
|---|
| 562 |
((literal=? t 'export) (loop s d next (append (or exports '()) (cdar cs)))) |
|---|
| 563 |
(else (syntax-error 'define-extension "invalid clause specifier" t)))))))))))) |
|---|
| 564 |
|
|---|
| 565 |
(define-macro (define-for-syntax head . body) |
|---|
| 566 |
(let* ((body (if (null? body) '((void)) body)) |
|---|
| 567 |
(name (if (pair? head) (car head) head)) |
|---|
| 568 |
(body (if (pair? head) `(lambda ,(cdr head) ,@body) (car body)))) |
|---|
| 569 |
(if (symbol? name) |
|---|
| 570 |
(##sys#setslot name 0 (eval body)) |
|---|
| 571 |
(syntax-error 'define-for-syntax "invalid identifier" name)) |
|---|
| 572 |
(if ##sys#enable-runtime-macros |
|---|
| 573 |
`(define ,name ,body) |
|---|
| 574 |
'(begin)))) |
|---|
| 575 |
|
|---|
| 576 |
(define-syntax fluid-let |
|---|
| 577 |
(syntax-rules () |
|---|
| 578 |
((_ ((v1 e1) ...) b1 b2 ...) |
|---|
| 579 |
(fluid-let "temps" () ((v1 e1) ...) b1 b2 ...)) |
|---|
| 580 |
((_ "temps" (t ...) ((v1 e1) x ...) b1 b2 ...) |
|---|
| 581 |
(let ((temp e1)) |
|---|
| 582 |
(fluid-let "temps" ((temp e1 v1) t ...) (x ...) b1 b2 ...))) |
|---|
| 583 |
((_ "temps" ((t e v) ...) () b1 b2 ...) |
|---|
| 584 |
(let-syntax ((swap! |
|---|
| 585 |
(syntax-rules () |
|---|
| 586 |
((swap! a b) |
|---|
| 587 |
(let ((tmp a)) |
|---|
| 588 |
(set! a b) |
|---|
| 589 |
(set! b tmp)))))) |
|---|
| 590 |
(dynamic-wind |
|---|
| 591 |
(lambda () |
|---|
| 592 |
(swap! t v) ...) |
|---|
| 593 |
(lambda () |
|---|
| 594 |
b1 b2 ...) |
|---|
| 595 |
(lambda () |
|---|
| 596 |
(swap! t v) ...)))))) |
|---|
| 597 |
|
|---|