Next: , Previous: , Up: stdlib syntax-case intro   [Index]


5.12.1.2 Unwrapping syntax objects

Let’s focus on unwrapped syntax objects, which are easier to deal with; it is always possible to convert a wrapped syntax object into an unwrapped one by applying the unwrap function defined in the following library (it is not important to understand it at first reading):

(library (syntax-utilities)
  (export unwrap)
  (import (rnrs))
  (define (unwrap stx)
    (syntax-case stx ()
      (()
       '())
      ((?car . ?cdr)
       (cons (unwrap (syntax ?car))
             (unwrap (syntax ?cdr))))
      (#(?item ...)
       (list->vector (unwrap (syntax (?item ...)))))
      (?atom
       (identifier? (syntax ?atom))
       (syntax ?atom))
      (?atom
       (syntax->datum (syntax ?atom))))))

it is possible to define alternative versions of this function with different properties, depending on the intended usage.

Now let’s define the following library:

(library (try-it-macros)
  (export the-macro)
  (import (rnrs)
    (for (syntax-utilities) expand))
  (define-syntax the-macro
    (lambda (stx)
      (let ((sexp (unwrap stx)))
        (write sexp)(newline)
        #f))))

the macro use in the following program:

(import (rnrs) (try-it-macros))

(the-macro 1 hello #(ciao 2) 3 salut)

will cause the input form to be unwrapped and bound to sexp, then the S-expression is displayed as something like:

(#<syntax the-macro>
 1
 #<syntax hello>
 #(#<syntax ciao> 2)
 3
 #<syntax salut>)

we see that where symbols appear in the input form, in the unwrapped syntax object we have identifiers: syntax objects holding only a symbol marked with its originating lexical context. We can process sexp with the ordinary Scheme functions, then return an S–expression holding datums and identifiers that do what we want.