diff --git a/trans.scm b/trans.scm index 40b37e75..79d9063c 100644 --- a/trans.scm +++ b/trans.scm @@ -287,6 +287,37 @@ `(,(rename 'begin) ,@(cdar ls)))) ((check (caar ls)) `(,(rename 'begin) ,@(cdar ls))) (else (expand (cdr ls))))))) + (cons 'quasiquote + ;; Based on the quasiquote macro from Chibi scheme + (lambda (expr rename compare) + (define (qq x d) + (cond + ((pair? x) + (cond + ((compare (rename 'unquote) (car x)) + (if (<= d 0) + (cadr x) + (list (rename 'list) (list (rename 'quote) 'unquote) + (qq (cadr x) (- d 1))))) + ((compare (rename 'unquote-splicing) (car x)) + (if (<= d 0) + (list (rename 'cons) (qq (car x) d) (qq (cdr x) d)) + (list (rename 'list) (list (rename 'quote) 'unquote-splicing) + (qq (cadr x) (- d 1))))) + ((compare (rename 'quasiquote) (car x)) + (list (rename 'list) (list (rename 'quote) 'quasiquote) + (qq (cadr x) (+ d 1)))) + ((and (<= d 0) (pair? (car x)) + (compare (rename 'unquote-splicing) (caar x))) + (if (null? (cdr x)) + (cadr (car x)) + (list (rename 'append) (cadr (car x)) (qq (cdr x) d)))) + (else + (list (rename 'cons) (qq (car x) d) (qq (cdr x) d))))) + ((vector? x) (list (rename 'list->vector) (qq (vector->list x) d))) + ((if (symbol? x) #t (null? x)) (list (rename 'quote) x)) + (else x))) + (qq (cadr expr) 0))) ))