Perpetual Weekend

26 November 2006

Quasiquote

Filed under: Uncategorized — shaurz @ 2:05

Today I added support for “non-hygenic” macros to my interpreter. I decided to implement the quasiquote feature of Lisp, which is very useful for writing macros, so that I can more comfortably implement more special-forms such as let.

I found an implementation of quasiquote here. My interpreter does not support all the functions it uses so I couldn’t drop it in. It was rather more complicated than I expected and I do not understand exactly how it works. I have written my own version:

(define (expand-quasiquote x)
  (if (pair? x)
      (if (is? (car x) 'unquote)
          (cadr x)
          (list 'cons
                (expand-quasiquote (car x))
                (expand-quasiquote (cdr x))))
      (list 'quote x)))

(define-macro (quasiquote x) (expand-quasiquote x))

(Note: is? is a pointer comparison roughly like Scheme’s eqv?)

I haven’t tested thoroughly, but it seems to work just fine. It uses simple recursive strategy: replace atoms by quotation of the atom, replace an unquote form by the raw argument of unquote so it can be evaluated, and replace non-unquoted pairs by the code to cons the car and cdr which are recursively handled. Quasiquotes inside unquotes inside quasiquotes inside … are automatically handled by macro expansion. It doesn’t handle vectors since the interpreter doesn’t have them yet. It is also doesn’t handle unquote-splicing which might complicate matters.

Am I missing something?

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.