|
339 | 339 | (symbol? x)
|
340 | 340 | (eq? x (top-level-value x)))))
|
341 | 341 |
|
342 |
| -(define-macro (quasiquote x) (bq-process x)) |
343 |
| - |
344 |
| -(define (bq-process x) |
345 |
| - (define (splice-form? x) |
346 |
| - (or (and (pair? x) (or (eq? (car x) 'unquote-splicing) |
347 |
| - (eq? (car x) 'unquote-nsplicing))) |
348 |
| - (eq? x 'unquote))) |
349 |
| - ; bracket without splicing |
350 |
| - (define (bq-bracket1 x) |
351 |
| - (if (and (pair? x) (eq? (car x) 'unquote)) |
352 |
| - (cadr x) |
353 |
| - (bq-process x))) |
354 |
| - (cond ((self-evaluating? x) |
355 |
| - (if (vector? x) |
356 |
| - (let ((body (bq-process (vector->list x)))) |
357 |
| - (if (eq? (car body) 'list) |
358 |
| - (cons vector (cdr body)) |
359 |
| - (list apply vector body))) |
360 |
| - x)) |
361 |
| - ((atom? x) (list 'quote x)) |
362 |
| - ((eq? (car x) 'quasiquote) (bq-process (bq-process (cadr x)))) |
363 |
| - ((eq? (car x) 'unquote) (cadr x)) |
| 342 | +(define-macro (quasiquote x) (bq-process x 0)) |
| 343 | + |
| 344 | +(define (splice-form? x) |
| 345 | + (or (and (pair? x) (or (eq? (car x) 'unquote-splicing) |
| 346 | + (eq? (car x) 'unquote-nsplicing) |
| 347 | + (and (eq? (car x) 'unquote) |
| 348 | + (length> x 2)))) |
| 349 | + (eq? x 'unquote))) |
| 350 | + |
| 351 | +;; bracket without splicing |
| 352 | +(define (bq-bracket1 x d) |
| 353 | + (if (and (pair? x) (eq? (car x) 'unquote)) |
| 354 | + (if (= d 0) |
| 355 | + (cadr x) |
| 356 | + (list cons ''unquote |
| 357 | + (bq-process (cdr x) (- d 1)))) |
| 358 | + (bq-process x d))) |
| 359 | + |
| 360 | +(define (bq-bracket x d) |
| 361 | + (cond ((atom? x) (list list (bq-process x d))) |
| 362 | + ((eq? (car x) 'unquote) |
| 363 | + (if (= d 0) |
| 364 | + (cons list (cdr x)) |
| 365 | + (list list (list cons ''unquote |
| 366 | + (bq-process (cdr x) (- d 1)))))) |
| 367 | + ((eq? (car x) 'unquote-splicing) |
| 368 | + (if (= d 0) |
| 369 | + (list 'copy-list (cadr x)) |
| 370 | + (list list (list list ''unquote-splicing |
| 371 | + (bq-process (cadr x) (- d 1)))))) |
| 372 | + ((eq? (car x) 'unquote-nsplicing) |
| 373 | + (if (= d 0) |
| 374 | + (cadr x) |
| 375 | + (list list (list list ''unquote-nsplicing |
| 376 | + (bq-process (cadr x) (- d 1)))))) |
| 377 | + (else (list list (bq-process x d))))) |
| 378 | + |
| 379 | +(define (bq-process x d) |
| 380 | + (cond ((symbol? x) (list 'quote x)) |
| 381 | + ((vector? x) |
| 382 | + (let ((body (bq-process (vector->list x) d))) |
| 383 | + (if (eq? (car body) list) |
| 384 | + (cons vector (cdr body)) |
| 385 | + (list apply vector body)))) |
| 386 | + ((atom? x) x) |
| 387 | + ((eq? (car x) 'quasiquote) |
| 388 | + (list list ''quasiquote (bq-process (cadr x) (+ d 1)))) |
| 389 | + ((eq? (car x) 'unquote) |
| 390 | + (if (and (= d 0) (length= x 2)) |
| 391 | + (cadr x) |
| 392 | + (list cons ''unquote (bq-process (cdr x) (- d 1))))) |
364 | 393 | ((not (any splice-form? x))
|
365 | 394 | (let ((lc (lastcdr x))
|
366 |
| - (forms (map bq-bracket1 x))) |
| 395 | + (forms (map (lambda (x) (bq-bracket1 x d)) x))) |
367 | 396 | (if (null? lc)
|
368 |
| - (cons 'list forms) |
369 |
| - (if (null? (cdr forms)) |
370 |
| - (list cons (car forms) (bq-process lc)) |
371 |
| - (nconc (cons 'list* forms) (list (bq-process lc))))))) |
372 |
| - (#t (let ((p x) (q ())) |
373 |
| - (while (and (pair? p) |
374 |
| - (not (eq? (car p) 'unquote))) |
375 |
| - (set! q (cons (bq-bracket (car p)) q)) |
376 |
| - (set! p (cdr p))) |
377 |
| - (let ((forms |
378 |
| - (cond ((pair? p) (nreconc q (list (cadr p)))) |
379 |
| - ((null? p) (reverse! q)) |
380 |
| - (#t (nreconc q (list (bq-process p))))))) |
381 |
| - (if (null? (cdr forms)) |
382 |
| - (car forms) |
383 |
| - (if (and (length= forms 2) |
384 |
| - (length= (car forms) 2) |
385 |
| - (eq? list (caar forms))) |
386 |
| - (list cons (cadar forms) (cadr forms)) |
387 |
| - (cons 'nconc forms)))))))) |
388 |
| - |
389 |
| -(define (bq-bracket x) |
390 |
| - (cond ((atom? x) (list list (bq-process x))) |
391 |
| - ((eq? (car x) 'unquote) (list list (cadr x))) |
392 |
| - ((eq? (car x) 'unquote-splicing) (list 'copy-list (cadr x))) |
393 |
| - ((eq? (car x) 'unquote-nsplicing) (cadr x)) |
394 |
| - (#t (list list (bq-process x))))) |
| 397 | + (cons list forms) |
| 398 | + (if (null? (cdr forms)) |
| 399 | + (list cons (car forms) (bq-process lc d)) |
| 400 | + (nconc (cons list* forms) (list (bq-process lc d))))))) |
| 401 | + (else |
| 402 | + (let loop ((p x) (q ())) |
| 403 | + (cond ((null? p) ;; proper list |
| 404 | + (cons 'nconc (reverse! q))) |
| 405 | + ((pair? p) |
| 406 | + (cond ((eq? (car p) 'unquote) |
| 407 | + ;; (... . ,x) |
| 408 | + (cons 'nconc |
| 409 | + (nreconc q |
| 410 | + (if (= d 0) |
| 411 | + (cdr p) |
| 412 | + (list (list list ''unquote) |
| 413 | + (bq-process (cdr p) |
| 414 | + (- d 1))))))) |
| 415 | + (else |
| 416 | + (loop (cdr p) (cons (bq-bracket (car p) d) q))))) |
| 417 | + (else |
| 418 | + ;; (... . x) |
| 419 | + (cons 'nconc (reverse! (cons (bq-process p d) q))))))))) |
395 | 420 |
|
396 | 421 | ; standard macros -------------------------------------------------------------
|
397 | 422 |
|
|
0 commit comments