quasiquote is now safe for nesting
This commit is contained in:
parent
234c573bb6
commit
c69687d234
|
@ -120,24 +120,55 @@
|
||||||
(r 'it)
|
(r 'it)
|
||||||
(cons (r 'or) (cdr exprs))))))))))
|
(cons (r 'or) (cdr exprs))))))))))
|
||||||
|
|
||||||
|
(define (quasiquote? form compare?)
|
||||||
|
(and (pair? form) (compare? (car form) 'quasiquote)))
|
||||||
|
|
||||||
|
(define (unquote? form compare?)
|
||||||
|
(and (pair? form) (compare? (car form) 'unquote)))
|
||||||
|
|
||||||
|
(define (unquote-splicing? form compare?)
|
||||||
|
(and (pair? form) (pair? (car form)) (compare? (car (car form)) 'unquote-splicing)))
|
||||||
|
|
||||||
(define-syntax quasiquote
|
(define-syntax quasiquote
|
||||||
(er-macro-transformer
|
(ir-macro-transformer
|
||||||
(lambda (expr r compare?)
|
(lambda (form inject compare)
|
||||||
(let ((x (cadr expr)))
|
|
||||||
|
(define (qq depth expr)
|
||||||
(cond
|
(cond
|
||||||
((symbol? x) (list (r 'quote) x))
|
;; unquote
|
||||||
((pair? x) (cond
|
((unquote? expr compare)
|
||||||
((compare? (r 'unquote) (car x))
|
(if (= depth 1)
|
||||||
(cadr x))
|
(car (cdr expr))
|
||||||
((and (pair? (car x))
|
(list 'list
|
||||||
(compare? (r 'unquote-splicing) (caar x)))
|
(list 'quote (inject 'unquote))
|
||||||
(list (r 'append) (cadar x)
|
(qq (- depth 1) (car (cdr expr))))))
|
||||||
(list (r 'quasiquote) (cdr x))))
|
;; unquote-splicing
|
||||||
(#t
|
((unquote-splicing? expr compare)
|
||||||
(list (r 'cons)
|
(if (= depth 1)
|
||||||
(list (r 'quasiquote) (car x))
|
(list 'append
|
||||||
(list (r 'quasiquote) (cdr x))))))
|
(car (cdr (car expr)))
|
||||||
(#t x))))))
|
(qq depth (cdr expr)))
|
||||||
|
(list 'cons
|
||||||
|
(list 'list
|
||||||
|
(list 'quote (inject 'unquote-splicing))
|
||||||
|
(qq (- depth 1) (car (cdr (car expr)))))
|
||||||
|
(qq depth (cdr expr)))))
|
||||||
|
;; quasiquote
|
||||||
|
((quasiquote? expr compare)
|
||||||
|
(list 'list
|
||||||
|
(list 'quote (inject 'quasiquote))
|
||||||
|
(qq (+ depth 1) (car (cdr expr)))))
|
||||||
|
;; list
|
||||||
|
((pair? expr)
|
||||||
|
(list 'cons
|
||||||
|
(qq depth (car expr))
|
||||||
|
(qq depth (cdr expr))))
|
||||||
|
;; simple datum
|
||||||
|
(else
|
||||||
|
(list 'quote expr))))
|
||||||
|
|
||||||
|
(let ((x (cadr form)))
|
||||||
|
(qq 1 x)))))
|
||||||
|
|
||||||
#;
|
#;
|
||||||
(define-syntax let*
|
(define-syntax let*
|
||||||
|
|
Loading…
Reference in New Issue