home *** CD-ROM | disk | FTP | other *** search
- ;;; extend-syntax macros
-
- (require 'extend-syntax)
- (provide 'macros)
-
- (extend-syntax (do)
- [(do ([var init . step] ...) (test texp ...) dexp ...)
- (andmap symbol? '(var ...))
- (with ([do-loop (gensym)]
- [(do-step ...)
- (map (lambda (x y)
- (if (null? y) x (car y)))
- '(var ...) '(step ...))])
- (letrec ((do-loop
- (lambda (var ...)
- (if test
- (begin texp ...)
- (begin dexp ... (do-loop do-step ...))))))
- (do-loop init ...)))])
-
- (extend-syntax (record-case else)
- [(record-case val (else exp ...))
- (begin exp ...)]
- [(record-case val clause ...)
- (pair? 'val)
- (with ([temp (gensym)])
- (let ([temp val])
- (record-case temp clause ...)))]
- [(record-case val (key idspec exp ...) more ...)
- (with ([bindings
- (let parse ([pat 'idspec] [acc 'val] [recs '()])
- (cond ((symbol? pat)
- (cons (list pat acc) recs))
- ((pair? pat)
- (parse (car pat)
- `(car ,acc)
- (parse (cdr pat)
- `(cdr ,acc)
- recs)))
- (else recs)))]
- [same? (if (symbol? 'key) eq? eqv?)])
- (if (same? (car val) 'key)
- (let bindings exp ...)
- (record-case val more ...)))]
- [(record-case val) #f])
-
- (extend-syntax (define-structure)
- ;; from "The Scheme Programming Language" by R. Kent Dybvig
- [(define-structure (name id1 ...))
- (define-structure (name id1 ...) ())]
- [(define-structure (name id1 ...) ([id2 val] ...))
- (with ([constructor
- (string->symbol (string-append "make-" 'name))]
- [predicate
- (string->symbol (string-append 'name "?"))]
- [(access ...)
- (map (lambda (x)
- (string->symbol (string-append 'name "-" x)))
- '(id1 ... id2 ...))]
- [(assign ...)
- (map (lambda (x)
- (string->symbol
- (string-append "set-" 'name "-" x "!")))
- '(id1 ... id2 ...))]
- [count (length '(name id1 ... id2 ...))])
- (with ([(index ...)
- (let f ([i 1])
- (if (= i 'count)
- '()
- (cons i (f (+ i 1)))))])
- (begin
- (define constructor
- (lambda (id1 ...)
- (let* ([id2 val] ...)
- (vector 'name id1 ... id2 ...))))
- (define predicate
- (lambda (obj)
- (and (vector? obj)
- (= (vector-length obj) count)
- (eq? (vector-ref obj 0) 'name))))
- (define access
- (lambda (obj)
- (vector-ref obj index)))
- ...
- (define assign
- (lambda (obj newval)
- (vector-set! obj index newval)))
- ...)))])
-