[plt-scheme] Some more syntax-handling fun --- trying to extract all the definitions in an arbitrary file
On 21/03/06, Danny Yoo <dyoo at hkn.eecs.berkeley.edu> wrote:
> Hi everyone,
>
> I know there's some code out there that does this already (DrScheme does
> it of course!), but to better-understand macros and the subtleties of
> module-or-top-identifier=?, I wrote a quick and dirty definition name
> extractor. Here's the code:
>
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (module get-definitions mzscheme
> (provide get-definitions/path
> get-definitions
> extract-definition)
> (require (lib "stx.ss" "syntax"))
> (require (lib "file.ss"))
>
> ;; get-definitions/path: path -> (listof symbol)
> ;;
> ;; Given a filename, opens it up and tries to extract out all the
> ;; definitions.
> (define (get-definitions/path path)
> (call-with-input-file*
> path
> (lambda (ip)
> (let ((stx (read-syntax path ip)))
> (get-definitions stx)))))
>
>
> ;; get-definitions: syntax -> (listof symbol)
> ;;
> ;; Given a syntax, tries to return all the toplevel defined names in
> ;; that syntax.
> (define (get-definitions stx)
> (syntax-case* stx (module) module-or-top-identifier=?
> ((module m-name lang s-expr ...)
> (mappend extract-definition (syntax->list (syntax (s-expr ...)))))
> ((s-expr ...)
> (mappend extract-definition (syntax->list (syntax (s-expr ...)))))))
>
>
> ;; mappend: (X -> (listof Y)) (listof X) -> (listof Y)
> ;;
> ;; mapping append.
> (define (mappend f l)
> (apply append (map f l)))
>
As a side note, there is already an append-map in srfi1. :)
>
> ;; extract-definition: syntax -> (listof symbol)
> ;;
> ;; If the form looks like a define, tries to extract the toplevel
> ;; name. Otherwise, returns the empty list.
> (define (extract-definition stx)
> (syntax-case* stx (define) module-or-top-identifier=?
> ((define (name args ...) body ...)
> (list (syntax-e (syntax name))))
> ((define name value)
> (list (syntax-e (syntax name))))
> (else
> (list)))))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
>
> Of course, I can't resist running this on itself. *grin*
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> > (get-definitions/path "~/get-definitions.ss")
> (get-definitions/path get-definitions mappend extract-definition)
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> I'm really happy that this worked, but I know this is not quite robust
> yet. If I use other forms that expand out to DEFINEs, then I'm sunk at
> the moment. I need to understand how to use the expander functions.
>
>
> I'm studying the reference manual about "Expanding Expressions to
> Primitive Syntax", and was wondering: is EXPAND generally the right tool
> to use to make sure the syntax is top-level-expr form before I start doing
> the preprocessing stuff? In what contexts might one want to use the other
> expand-* functions?
>
>
> Thanks a lot!
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
--
Paulo Jorge Matos - pocm at sat inesc-id pt
Web: http://sat.inesc-id.pt/~pocm
Computer and Software Engineering
INESC-ID - SAT Group