Move mzlib/defmacro => racket/defmacro
With both @bold and @italics warning against its use. No @blink though.
This commit is contained in:
parent
4a90c6c1fe
commit
3582b57bcc
|
@ -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))
|
||||
|
|
|
@ -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])))))))
|
||||
|
||||
|
||||
|
||||
|
|
@ -118,7 +118,11 @@ Re-exports @racketmodname[file/gzip].
|
|||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@include-section["defmacro.scrbl"]
|
||||
@mzlib[defmacro]
|
||||
|
||||
@deprecated[@racketmodname[racket/defmacro]]{}
|
||||
|
||||
Re-exports @racketmodname[racket/defmacro].
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
@ -25,3 +25,4 @@ called.
|
|||
@include-section["stx-expand.scrbl"]
|
||||
@include-section["include.scrbl"]
|
||||
@include-section["syntax-util.scrbl"]
|
||||
@include-section["defmacro.scrbl"]
|
||||
|
|
|
@ -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 ()
|
||||
|
|
Loading…
Reference in New Issue
Block a user