[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Opaque syntax objects



Andre van Tonder wrote:
On Sun, 14 Aug 2005, [ISO-8859-1] Jens Axel Søgaard wrote:

What should I do if I want to give a piece of (expanded) syntax the
same source information as, say, the macro call?

There can be a primitive for that.  E.g.,
  annotate : (syntax-object, syntax-object) -> syntax-object
In the hash-table, this would insert a new entry for the pair representing the second syntax object, copying the annotation of the first.

Of course. Syntax objects are still ordinary pairs. No change to car/cdr is required. The hash table with source information is kept separately.

Hmm. How do you represent identifiers?

The same way, once you give them a wrap to give them separate identities.

So identifiers are represented as a special type. How about atoms?
Can I annotate a piece of syntax representing, say, a number?

I believe with-syntax behaves that way in order to be (more) compatible
with the psyntax-implementation. Note that the source location
information for stx-expr in

 (with-syntax ((pattern stx-expr) ...) expr)

is taken from stx-expr, when stx-expr is not returning a list. That
is the source location is still tracked.

Do you know what location is assigned when stx-expr is a list?

(with-syntax ((a-list #'(1 2 3))) (syntax-position #'a-list))
evaluates to 25

(with-syntax ((a-list (list 1 2 3))) (syntax-position #'a-list))
evalutes to #f

(with-syntax ((a-list (list #'x)))
  (syntax-case #'a-list ()
    [(y)
     (syntax-position #'y)]))
evaluates to 31

As an aside, it is sometimes easy to throw away too much information when using the destructuring idiom. For example, in

  (define-syntax let1
    (lambda (form)
      (syntax-case form ()
        ((_ ((i e) ...) e1 e2 ...)
         (syntax (let ((i e) ...) e1 e2 ...))))))

it is unlikely that most implementations would keep the location of the input subnode ((i e) ...) in the result.

Keeping them makes it possible to give much better error messages.
As a quick test this:

(define-syntax let1
  (lambda (form)
    (syntax-case form ()
      ((_ ((i e) ...) e1 e2 ...)
       (syntax (let2 ((i e) ...) e1 e2 ...))))))

(define-syntax let2
  (lambda (form)
    (syntax-case form ()
      ((_ ((i e) ...) e1 e2 ...)
       (with-syntax (((i1 . _) #'(i ...)))
         (display "line: ")
         (display (syntax-line #'i1))
         (display " col: ")
         (display (syntax-column #'i1))
         (newline)
         #'(let ((i e) ...) e1 e2 ...))))))

(let1 ((x 41))
  (+ x 1))

prints  "line: 19 col: 8" and evaluates to 42 in DrScheme.

--
Jens Axel Søgaard