[plt-scheme] match-lambda and syntax objects
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