[racket] Passing info from reader level

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Dec 14 08:49:23 EST 2012

I hope it's ok that I'm cc'ing the list. You ask good questions and
others might be interested in the answers or in improving my answers.

At Thu, 13 Dec 2012 22:09:18 -0800, Rajah Mahsohn Omega wrote:
> You gave this example for
> specifying a language in a submodule.
> 
> #lang racket/base
> 
>   (provide (all-from-out racket/base)
>            fish)
>   (define fish '(1 2 3))
> 
>   (module reader syntax/module-reader
>     #:language 'ocean)
> 
> Right now I am just playing around with my language so I have not created a
> collection directory for it, but do I have to create a collection to be
> able to implement this?

Yes, that example is intended for use as "main.rkt" in an "ocean"
collection.

> I moved my reader functions into a reader submodule, but instead of
> providing #:language I directly provided the #:read and #:read-synax
> functions, then at the top of another file I added
> 
> #lang reader "my-reader.rkt"
> 
> but I got the error
> " read-syntax: cannot find reader for `#lang reader "my-reader.rkt""

The module path after `reader' specifies the module that directly
exports the `read' and `read-syntax' functions. So, if you put the
module above in "my-reader.rkt", then

  #lang reader (submod "my-reader.rkt" reader)

should work... at least to the point of complaining that no "ocean"
collection can be found, since the `reader' submodule's reader
generates a reference to `ocean'.

In other words, to use `#lang reader', you probably don't want to put
the reader in a sub-module, since `#lang reader' is intended to refer
to a reader module directly.

> In the article you said that racket will search for a reader submodule
> first, but now I can only assume that it only works for a collection with a
> main.rkt and a /lang/reader. Is this correct?

Yes, essentially.

Maybe we should have a new `something' so that `#lang something' is
like `#lang reader', except that it looks for a `reader' submodule.

> You responded that special comments are used for comment boxes in drracket,
> I was looking for a little more detail about where those special-comments
> are stored and how to access them later on. Also does using
> make-special-comment have any side affects I need to know about? Or can I
> use it any way I like? Is there any other way of removing metadata from
> code? (an empty syntax object?)

Special comments aren't stored by `read' or `read-syntax'; they're just
discarded. Creating a special comment has no side effect.

One way to attach metadata to a syntax object is to use a syntax
property. For example, the reader preserves the information that `[1
2]' is written qith suqare brackets by attaching a 'paren-shape
property to the result of `read-syntax'.

> And I have one more question, it's nice that I can get the line and column
> number of the token I am parsing through read-syntax, but how hard would it
> be to get the actual path of the token? For Instance
> 
> (define (func1)
>    (define (func2 n)
>       (if (eq? n ^metadata-here^5)
>          #t
>          #f)))
> 
> when the reader finds the ^metadata-here^ tag I would also like it to give
> me the path:
> 
> func1->func2->if[0]->[0][2]
> 
> meaning the third argument of the first argument of the first if inside
> func2 inside func1
> as the actual path of the token
> 
> How difficult would this be to implement?

I think you could probably post-process a result from `read-syntax' to
add that path information in a syntax property. In other words, you
could traverse the syntax-object tree and construct a copy with syntax
objects that have an 's-exp-path property, or something like that.


Posted on the users mailing list.