[racket] Lesson from the macro exercise
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
(require
racket/stxparam
(for-syntax unstable/syntax ; for generate-temporary
syntax/parse
syntax/stx))
;;; SYNTAX
;; <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