[plt-scheme] match-lambda and syntax objects

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Tue May 29 14:05:34 EDT 2007

On May 29, 2007, at 1:06 PM, Sridhar Ratna wrote:

> hi!
>
> I am reading sexps from a file and parsing them using `match.ss'..
> something like this:
>
>  (define @> 'a-macro-that-constructs-Python-AST)
>
>  (define T
>    (match-lambda
>      ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>      ;; MATH operators
>
>      (('+ left right)
>       (@> Add (list (T left) (T right))))
>
>  (T (read in-port))
>
> (Note: complete code is here 
> <http://srid.nfshost.com/code/boalisp/compile.ss>)
>
> Now that instead of READ I will have to use READ-SYNTAX which returns
> a SYNTAX object. The goal is to make use of the `lineno' information
> in the syntax object and construct the Python AST along with line
> number information. Thus, the ADD example above, I envision, would
> become,
>
>     (('+ left right)
>      (@> %lineno% Add (T left) (T right)))
>
> Here we could presume `left' and `right' as SYNTAX objects as opposed
> to sexps. To add to the complexity, I might have to lookup up the
> %lineno% for `left' and `right' forms too, rather than just the `+'
> form.

It would be difficult to use 'match' gracefully to destructure syntax 
objects.

If you are representing your programs with syntax objects, then 
consider using 'syntax-case' to  destructure them. Here's how the first 
couple cases of your 'T' function would look:

   (require (lib "stx.ss" "syntax")) ;; provides 
module-or-top-identifier=?

   (define (T expr)
     (syntax-case* expr (+ and not : <more...>) 
module-or-top-identifier=?
       ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       ;; MATH operators

       ((+ left right)
        (@> Add (list (T #'left) (T #'right))))

       ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       ;; BOOLEAN operators

       ((and node ...)
        (@> And : (map T (syntax->list #'(node ...)))))
       ((not node)
        (@> Not (T #'node)))

       ___))

Instead of using quote-patterns, you put the literals to match in the 
keyword list. Since you aren't matching Scheme code, you need to tell 
'syntax-case*' to use a different identifier comparison function, one 
that ignores bindings. I've also left out the '+' optimization; that 
would probably be easier to do as a pass over the AST afterwards.

> My question is how to hack `lineno' support, in a code that uses
> match-lambda, this way (or the other)?

No matter whether you use 'syntax-case' or 'match', the source lines, 
columns, etc, are available by using 'syntax-line', 'syntax-column', 
etc:
   (syntax-line expr)

Ryan


>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.