[racket] Lesson from the macro exercise

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Tue Oct 12 17:27:05 EDT 2010

2010/10/12 Jens Axel Søgaard <jensaxel at soegaard.net>:
> Syntax/parse looks great!
> I haven't played with it before, but it I like the approach.
> Two questions:
>   1. What does the error
>          pattern: attribute has wrong depth (expected 0, found 1) in: d
>      mean?  The program belows gives this error.

I figured this one out, by studying section 8.2.2 in the docs.

The following program is a bare bones syntax-parse version.
I still need to figure out how to improve the error messages though.

For example (casc) and (casc 3) just result in "bad syntax".

/Jens Axel

#lang racket
 (for-syntax unstable/syntax ; for generate-temporary
;;    <cas-cad-e>   ::= (cas-cad-e <val-expr> <case-clause> ...+)
;;    <case-clause> ::= [(<datum> ...) <then-expr> ...+]

(define-syntax-parameter break
  (λ (stx) (raise-syntax-error 'break "The keywork break was used of
context." stx)))

(define-syntax (casc stx)

  (define-syntax-class datum
    #:attributes (d)
    (pattern d:expr))

  (define-syntax-class case-clause
    #:attributes ((d 1) (te 1))
    (pattern [(d:datum ...) te:expr ...+]))

  (syntax-parse stx
    [(_ value-expr:expr clause:case-clause ... last-clause:case-clause)
     (with-syntax* ([(label ...)      (generate-temporaries #'(clause ...))]
                    [last-label       (generate-temporary)]
                    [(next ...)       (stx-cdr #'(label ... last-label))])
       #'(let/ec break1
             (syntax-parameterize ([break (make-rename-transformer #'break1)])
              (letrec ([label      (λ () clause.te ... (next))]
                       [last-label (λ () last-clause.te ...)])
                (case value-expr
                  [(clause.d ...)      (label)]
                  [(last-clause.d ...) (last-label)]
                  [else (void)])))))]))

Jens Axel Søgaard

Posted on the users mailing list.