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.