The reason why you are getting the source location from b.rkt is that
in `mk-data` you are getting the info from `stx`.  In this case, `stx`
is the filled-in template you get from `simple-data` in b.rkt.  The
pattern variables `name` and `x` are filled in with `unlucky` and `262`,
which do have location info from c.rkt.  But the parentheses, the
`mk-data` identifier, the quote around the `name` variable, and `42` all
have location info pointing back to b.rkt.  In this case, the outermost
piece of syntax corresponds to the whole list '(mk-data 'name x 42), so
you are getting the location of the parentheses.

In the `simple-data` macro you can copy that location info, and as others
have said, you can stuff it in a syntax property or put it on the new
syntax, or you can have the `mk-data` macro use the location info on
`name` or `y` rather than the info on `stx`.

IE

(define-syntax (mk-data stx)
 (syntax-case stx ()
   [(_ name x y)
    #`(data-internal name x y (srcloc #,(syntax-source #'name))
                                      #,(syntax-line #'name)
                                      #,(syntax-column #'name)
                                      #,(syntax-position #'name)
                                      #,(syntax-span #'name)))]))

This gives you the location of just `name` rather than the whole
s-expression, which may or may not be what you actually want.


On Tue, Jul 04, 2017 at 01:39:01PM -0700, reilithion wrote:
I'd like to be able to get source location information from behind two or more 
layers of macros.

I have a macro, call it mk-data, whose job it is to make an internal data 
structure. Among other things, it records a srcloc for later tracking. In 
another module, I have another macro whose job it is to specialize mk-data and 
present a simpler interface.

Unfortunately, the srcloc that gets stored ends up being the location of the 
simplifying macro. Not what I want. I need to somehow forward the srcloc of its 
use-location. Example follows:

a.rkt:
#lang racket
(provide mk-data getloc)
(struct data-internal
 (name x y srcloc)
 #:guard (λ (n x y srcloc struct-name)
           (unless (real? x)
             (raise-argument-error 'data-internal "real?" x))
           (unless (real? y)
             (raise-argument-error 'data-internal "real?" y))
           (values n x y srcloc)))
(define-syntax (mk-data stx)
 (syntax-case stx ()
   [(_ name x y)
    #`(data-internal name x y (srcloc #,(syntax-source stx)
                                      #,(syntax-line stx)
                                      #,(syntax-column stx)
                                      #,(syntax-position stx)
                                      #,(syntax-span stx)))]))
(define (getloc d) (srcloc->string (data-internal-srcloc d)))

b.rkt:
#lang racket
(provide simple-data)
(require "a.rkt")
(define-syntax (simple-data stx)
 (syntax-case stx ()
   [(_ name x)
    #'(mk-data 'name x 42)]))

c.rkt:
#lang racket
(require "a.rkt" "b.rkt")
(getloc (simple-data unlucky 262))

I want the result in c.rkt to be "c.rkt:3:9" or so, rather than "b.rkt:7:7".
I realize I could probably make the simple-data macro in b.rkt a bit more 
sophisticated to help matters, but I'm really resisting doing so. There are 
going to be a lot of macros like simple-data, and some of them may be written 
by users, so I'd like to make it as simple as possible to make new ones. I'd 
rather change mk-data, even if it means making it significantly more complex. 
What's the best way to accomplish this?

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to