diff --git a/collects/mzlib/defmacro.rkt b/collects/mzlib/defmacro.rkt index 8f0e8d4c7e..1e893e9aae 100644 --- a/collects/mzlib/defmacro.rkt +++ b/collects/mzlib/defmacro.rkt @@ -1,72 +1,8 @@ +#lang racket/base -(module defmacro mzscheme - (require-for-syntax syntax/stx - "private/dmhelp.rkt") +;; deprecated library, see racket/defmacro +;; +;; for legacy use only - (provide define-macro - defmacro) - - (define-syntax define-macro - (lambda (stx) - (syntax-case stx () - [(_ (name . args) proc0 proc ...) - (begin - (unless (identifier? (syntax name)) - (raise-syntax-error - #f - "expected an identifier for the macro name" - stx - (syntax name))) - (let loop ([args (syntax args)]) - (cond - [(stx-null? args) 'ok] - [(identifier? args) 'ok] - [(stx-pair? args) - (unless (identifier? (stx-car args)) - (raise-syntax-error - #f - "expected an identifier for a macro argument" - stx - (stx-car args))) - (loop (stx-cdr args))] - [else (raise-syntax-error - #f - "not a valid argument sequence after the macro name" - stx)])) - (syntax - (define-macro name (lambda args proc0 proc ...))))] - [(_ name proc) - (begin - (unless (identifier? (syntax name)) - (raise-syntax-error - #f - "expected an identifier for the macro name" - stx - (syntax name))) - (syntax - (define-syntax name - (let ([p proc]) - (unless (procedure? p) - (raise-type-error - 'define-macro - "procedure (arity 1)" - p)) - (lambda (stx) - (let ([l (syntax->list stx)]) - (unless (and l (procedure-arity-includes? p (sub1 (length l)))) - (raise-syntax-error - #f - "bad form" - stx)) - (let ([ht (make-hash-table)]) - (datum->syntax-object - stx - (dm-subst - ht - (apply p (cdr (dm-syntax->datum stx ht)))) - stx))))))))]))) - - (define-syntax defmacro - (syntax-rules () - [(_ name formals body1 body ...) - (define-macro (name . formals) body1 body ...)]))) +(require racket/defmacro) +(provide (all-from-out racket/defmacro)) diff --git a/collects/mzlib/private/dmhelp.rkt b/collects/mzlib/private/dmhelp.rkt deleted file mode 100644 index c0e0b89230..0000000000 --- a/collects/mzlib/private/dmhelp.rkt +++ /dev/null @@ -1,61 +0,0 @@ - -(module dmhelp mzscheme - (require syntax/stx) - - (provide dm-syntax->datum - dm-subst) - - ;; `dm-syntax->datum' is like syntax-object->datum, but it also - ;; builds a hash table that maps generated data to original syntax - ;; objects. The hash table can then be used with `dm-subst' to - ;; replace each re-used, unmodified datum with the original syntax - ;; object. - - (define (dm-syntax->datum stx ht) - ;; Easiest to handle cycles by letting `syntax-object->datum' - ;; do all the work. - (let ([v (syntax-object->datum stx)]) - (let loop ([stx stx][v v]) - (let ([already (hash-table-get ht v (lambda () #f))]) - (if already - (hash-table-put! ht v #t) ;; not stx => don't subst later - (hash-table-put! ht v stx)) - (cond - [(stx-pair? stx) - (loop (stx-car stx) (car v)) - (loop (stx-cdr stx) (cdr v))] - [(stx-null? stx) null] - [(vector? (syntax-e stx)) - (for-each - loop - (vector->list - (syntax-e stx)) - (vector->list v))] - [(box? (syntax-e stx)) - (loop (unbox (syntax-e stx)) - (unbox v))] - [else (void)]))) - v)) - - (define (dm-subst ht v) - (define cycle-ht (make-hash-table)) - (let loop ([v v]) - (if (hash-table-get cycle-ht v (lambda () #f)) - v - (begin - (hash-table-put! cycle-ht v #t) - (let ([m (hash-table-get ht v (lambda () #f))]) - (cond - [(syntax? m) m] ;; subst back! - [(pair? v) (cons (loop (car v)) - (loop (cdr v)))] - [(vector? v) (list->vector - (map - loop - (vector->list v)))] - [(box? v) (box (loop (unbox v)))] - [else v]))))))) - - - - diff --git a/collects/mzlib/scribblings/mzlib.scrbl b/collects/mzlib/scribblings/mzlib.scrbl index 9832d8378c..3e243cb0f0 100644 --- a/collects/mzlib/scribblings/mzlib.scrbl +++ b/collects/mzlib/scribblings/mzlib.scrbl @@ -118,7 +118,11 @@ Re-exports @racketmodname[file/gzip]. @; ---------------------------------------------------------------------- -@include-section["defmacro.scrbl"] +@mzlib[defmacro] + +@deprecated[@racketmodname[racket/defmacro]]{} + +Re-exports @racketmodname[racket/defmacro]. @; ---------------------------------------------------------------------- diff --git a/collects/mzlib/scribblings/defmacro.scrbl b/collects/scribblings/reference/defmacro.scrbl similarity index 75% rename from collects/mzlib/scribblings/defmacro.scrbl rename to collects/scribblings/reference/defmacro.scrbl index 9c28c01470..283577d98d 100644 --- a/collects/mzlib/scribblings/defmacro.scrbl +++ b/collects/scribblings/reference/defmacro.scrbl @@ -1,11 +1,20 @@ #lang scribble/doc -@(require "common.rkt" - (for-label mzlib/defmacro - (only-in scheme/base syntax->datum datum->syntax))) +@(require "mz.rkt" + (for-label racket/defmacro)) -@(define ref '(lib "scribblings/reference/reference.scrbl")) +@title[#:tag "defmacro"]{Legacy macro support} -@mzlib[#:mode title defmacro] +@note-lib-only[racket/defmacro] + +This @racketmodname[racket/defmacro] library provides support for +writing legacy macros. Support for @racket[defmacro] is provided +primarily for porting code from other languages (e.g., some +implementations of Scheme or Common Lisp) that use symbol-based +macro systems. + +Use of @racket[defmacro] for modern Racket code is @bold{@italic{strongly}} +discouraged. Instead, consider using @racket[syntax-parse] or +@racket[define-simple-macro]. @deftogether[( @defform*[[(define-macro id expr) @@ -17,8 +26,7 @@ )]{ Defines a (non-hygienic) macro @racket[id] through a procedure that -manipulates S-expressions, as opposed to @techlink[#:doc ref]{syntax -objects}. +manipulates S-expressions, as opposed to @tech{syntax objects}. In the first form, @racket[expr] must produce a procedure. In the second form, @racket[formals] determines the formal arguments of the @@ -26,8 +34,8 @@ procedure, as in @racket[lambda], and the @racket[expr]s are the procedure body. The last form, with @racket[defmacro], is like the second form, but with slightly different parentheses. -In all cases, the procedure is generated in the @techlink[#:doc -ref]{transformer environment}, not the normal environment. +In all cases, the procedure is generated in the +@tech{transformer environment}, not the normal environment. In a use of the macro, diff --git a/collects/scribblings/reference/macros.scrbl b/collects/scribblings/reference/macros.scrbl index 5b380ab99d..3485695777 100644 --- a/collects/scribblings/reference/macros.scrbl +++ b/collects/scribblings/reference/macros.scrbl @@ -25,3 +25,4 @@ called. @include-section["stx-expand.scrbl"] @include-section["include.scrbl"] @include-section["syntax-util.scrbl"] +@include-section["defmacro.scrbl"] diff --git a/collects/swindle/misc.rkt b/collects/swindle/misc.rkt index c35e99ffcf..b779210005 100644 --- a/collects/swindle/misc.rkt +++ b/collects/swindle/misc.rkt @@ -157,7 +157,7 @@ ;;> with `defsubst' above). ;;> * A `letmacro' form for local macros is provided. -(require-for-syntax mzlib/private/dmhelp) +(require (for-syntax (submod racket/defmacro dmhelp))) (provide defmacro letmacro) (define-syntaxes (defmacro letmacro) (let ()