[racket] Passing info from reader level

From: Rajah Mahsohn Omega (rajahmahsohn at gmail.com)
Date: Sun Dec 16 16:16:27 EST 2012

Thanks Matthew for all your help, it would have been tough figuring this
out on my own.

you said:
>I think you should imagine that a program is read and compiled on a
>different machine where it is run, and so you can't directly share
>state between the reader and run-time code.

Ok, I'm starting to get the feeling that I shouldn't be doing what I'm
trying to do, especially if I would like to keep updating meta-count at
runtime.

meta-count was just an example and doesn't actually reflect what I am
trying to do.

My new approach is instead of discarding the metadata, I create a syntax
object for it and discard it at expansion time or compile time. I plan to
keep a copy of the syntax tree with the metadata inside for later use. I'm
not seeing any documentation on how to get involved in the expansion or
compilation stages, removing the metadata is not as easy as creating a
macro as the metadata can be embedded anywhere. What I'd like to know is
where is read-syntax being called from so that I can step in and filter out
the metadata before expansion begins. Is there a way to do this without
modifying any racket code?


On Sun, Dec 16, 2012 at 9:08 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:

> At Sat, 15 Dec 2012 13:12:50 -0800, Rajah Mahsohn Omega wrote:
> > So from what I'm gathering the only way to share data with the reader and
> > expander layer is to add the reader as a submodue in the main.rkt file.
>
> No, I don't think that works. It might work under some circumstances,
> but I think you should imagine that a program is read and compiled on a
> different machine where it is run, and so you can't directly share
> state between the reader and run-time code. (Ideally, Racket would
> enforce that separation, but it currently doesn't.)
>
> Instead, I meant instead that the reader needs to produce module that
> has a submodule.
>
> > So
> > I've done that and it works but now I have a new problem, provide doesn't
> > seem to be providing anything. Here is an example main.rkt file that
> > provides meta-count.
>
> The module that your reader produces uses the language `racket' (as
> specified after the `syntax/module-reader' language), which doesn't
> export `meta-count'.
>
> More generally, I think you will need to use `#:wrapper2' so that you
> get control over the whole `module' form to add a nested `module' form
> to hold metadata. Here's an example, based on your code.
>
> ------------------------------------------------------------
> "meta-count.rkt"
> ------------------------------------------------------------
> #lang racket
>
> (module* reader syntax/module-reader
>   racket
>   #:wrapper2 wrapper2
>   (require syntax/readerr)
>
>   (define meta-count 0)
>
>   (define (wrapper2 in f)
>     (define mod
>       (parameterize ([current-readtable (make-meta-readtable)])
>         (f in)))
>     (define new-mod
>       (syntax-case mod ()
>         [(_mod _name _lang (_mb body ...))
>          (quasisyntax/loc (if (syntax? mod) mod #'here)
>            (_mod _name _lang
>                  (_mb (module meta-count racket/base #,meta-count)
>                       body ...)))]))
>     (if (syntax? mod)
>         new-mod
>         (syntax->datum new-mod)))
>
>   (define (make-meta-readtable)
>     (make-readtable (current-readtable)
>                     #\^ 'terminating-macro read-meta))
>   (define read-meta
>     (case-lambda
>      [(ch in)
>       (rread (object-name in) in)]
>      [(ch in src line col pos)
>       (rread src in)]))
>
>   (define (rread src in)
>     (define-values (line col pos) (port-next-location in))
>     (let ([meta (regexp-match #rx"[^ (['`#]+" in)])
>       (if meta
>           (begin
>             (set! meta-count (add1 meta-count))
>             (make-special-comment meta))
>           (raise-read-error "expected a metadata name" src line col pos
> 1)))))
>
> ------------------------------------------------------------
> "m.rkt":
> ------------------------------------------------------------
> #lang reader (submod "meta-count.rkt" reader)
> ^meta (+ ^meta1 1 2)
>
> ------------------------------------------------------------
> Comamnd line, looking at the expanded form of "m.rkt":
> ------------------------------------------------------------
> % raco expand m.rkt
> (module m racket
>   (#%module-begin
>    (module meta-count racket/base
>      (#%module-begin (#%app call-with-values (lambda () '2) print-values)))
>    (#%app call-with-values (lambda () (#%app + '1 '2)) print-values)))
>
> ------------------------------------------------------------
> REPL:
> ------------------------------------------------------------
> > (require "m.rkt")
> 3
> > (require (submod "m.rkt" meta-count))
> 2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20121216/40219909/attachment.html>

Posted on the users mailing list.