emphasize syntax/id-table over syntax/boundmap
This commit is contained in:
parent
00c6f91e7c
commit
528c05b228
|
@ -1,115 +1,72 @@
|
|||
#lang scribble/doc
|
||||
@(require "common.rkt" (for-label syntax/boundmap))
|
||||
@(require "common.rkt" (for-label syntax/boundmap syntax/id-table))
|
||||
|
||||
@title[#:tag "boundmap"]{Hashing on @racket[bound-identifier=?] and @racket[free-identifier=?]}
|
||||
|
||||
See also @racketmodname[syntax/id-table] for an implementation of
|
||||
identifier mappings using the @racketmodname[scheme/dict] dictionary
|
||||
interface.
|
||||
This library is for backwards-compatibility. Do not use it for new
|
||||
libraries; use @racketmodname[syntax/id-table] instead.
|
||||
|
||||
@defmodule[syntax/boundmap]
|
||||
|
||||
@defproc[(make-bound-identifier-mapping) bound-identifier-mapping?]{
|
||||
|
||||
Produces a hash-table-like value for storing a mapping from syntax
|
||||
identifiers to arbitrary values.
|
||||
|
||||
The mapping uses @racket[bound-identifier=?] to compare mapping keys,
|
||||
but also uses a hash table based on symbol equality to make the
|
||||
mapping efficient in the common case (i.e., where non-equivalent
|
||||
identifiers are derived from different symbolic names).}
|
||||
|
||||
|
||||
@defproc[(bound-identifier-mapping? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] was produced by
|
||||
@racket[make-bound-identifier-mapping], @racket[#f] otherwise.}
|
||||
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(make-bound-identifier-mapping) bound-identifier-mapping?]
|
||||
@defproc[(bound-identifier-mapping? [v any/c]) boolean?]
|
||||
@defproc[(bound-identifier-mapping-get [bound-map bound-identifier-mapping?]
|
||||
[id identifier?]
|
||||
[failure-thunk any/c (lambda () (raise (make-exn:fail ....)))])
|
||||
any]{
|
||||
|
||||
Like @racket[hash-table-get] for bound-identifier mappings.}
|
||||
|
||||
|
||||
[failure-thunk (-> any)
|
||||
(lambda () (raise (make-exn:fail ....)))])
|
||||
any]
|
||||
@defproc[(bound-identifier-mapping-put! [bound-map bound-identifier-mapping?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-table-put!] for bound-identifier mappings.}
|
||||
|
||||
void?]
|
||||
@defproc[(bound-identifier-mapping-for-each [bound-map boud-identifier-mapping?]
|
||||
[proc (identifier? any/c . -> . any)])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-table-for-each].}
|
||||
|
||||
|
||||
void?]
|
||||
@defproc[(bound-identifier-mapping-map [bound-map bound-identifier-mapping?]
|
||||
[proc (identifier? any/c . -> . any)])
|
||||
(listof any?)]{
|
||||
(listof any?)]
|
||||
]]{
|
||||
|
||||
Like @racket[hash-table-map].}
|
||||
|
||||
|
||||
@defproc[(make-free-identifier-mapping) free-identifier-mapping?]{
|
||||
|
||||
Produces a hash-table-like value for storing a mapping from syntax
|
||||
identifiers to arbitrary values.
|
||||
|
||||
The mapping uses @racket[free-identifier=?] to compare mapping keys,
|
||||
but also uses a hash table based on symbol equality to make the
|
||||
mapping efficient in the common case (i.e., where non-equivalent
|
||||
identifiers are derived from different symbolic names at their
|
||||
definition sites).}
|
||||
|
||||
|
||||
@defproc[(free-identifier-mapping? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] was produced by
|
||||
@racket[make-free-identifier-mapping], @racket[#f] otherwise.
|
||||
Similar to @racket[make-bound-id-table], @racket[bound-id-table?],
|
||||
@racket[bound-id-table-ref], @racket[bound-id-table-set!],
|
||||
@racket[bound-id-table-for-each], and @racket[bound-id-table-map],
|
||||
respectively.
|
||||
}
|
||||
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(make-free-identifier-mapping) free-identifier-mapping?]
|
||||
@defproc[(free-identifier-mapping? [v any/c]) boolean?]
|
||||
@defproc[(free-identifier-mapping-get [free-map free-identifier-mapping?]
|
||||
[id identifier?]
|
||||
[failure-thunk any/c (lambda () (raise (make-exn:fail ....)))])
|
||||
any]{
|
||||
|
||||
Like @racket[hash-table-get] for free-identifier mappings.}
|
||||
|
||||
|
||||
[failure-thunk (-> any)
|
||||
(lambda () (raise (make-exn:fail ....)))])
|
||||
any]
|
||||
@defproc[(free-identifier-mapping-put! [free-map free-identifier-mapping?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-table-put!] for free-identifier mappings.}
|
||||
|
||||
|
||||
void?]
|
||||
@defproc[(free-identifier-mapping-for-each [free-map free-identifier-mapping?]
|
||||
[proc (identifier? any/c . -> . any)])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-table-for-each].}
|
||||
|
||||
|
||||
void?]
|
||||
@defproc[(free-identifier-mapping-map [free-map free-identifier-mapping?]
|
||||
[proc (identifier? any/c . -> . any)])
|
||||
(listof any?)]{
|
||||
|
||||
Like @racket[hash-table-map].}
|
||||
(listof any?)]
|
||||
]]{
|
||||
|
||||
Similar to @racket[make-free-id-table], @racket[free-id-table?],
|
||||
@racket[free-id-table-ref], @racket[free-id-table-set!],
|
||||
@racket[free-id-table-for-each], and @racket[free-id-table-map],
|
||||
respectively.
|
||||
}
|
||||
|
||||
@deftogether[(
|
||||
@defproc[(make-module-identifier-mapping) module-identifier-mapping?]
|
||||
@defproc[(module-identifier-mapping? [v any/c]) boolean?]
|
||||
@defproc[(module-identifier-mapping-get [module-map module-identifier-mapping?]
|
||||
[id identifier?]
|
||||
[failure-thunk any/c (lambda () (raise (make-exn:fail ....)))])
|
||||
[failure-thunk (-> any)
|
||||
(lambda () (raise (make-exn:fail ....)))])
|
||||
any]
|
||||
@defproc[(module-identifier-mapping-put! [module-map module-identifier-mapping?]
|
||||
[id identifier?]
|
||||
|
@ -123,4 +80,5 @@ Like @racket[hash-table-map].}
|
|||
(listof any?)]
|
||||
)]{
|
||||
|
||||
The same as @racket[make-free-identifier-mapping], etc.}
|
||||
The same as @racket[make-free-identifier-mapping], etc.
|
||||
}
|
||||
|
|
|
@ -1,132 +1,210 @@
|
|||
#lang scribble/doc
|
||||
@(require "common.rkt" (for-label syntax/id-table scheme/dict))
|
||||
@(require "common.rkt" (for-label syntax/id-table racket/dict))
|
||||
|
||||
@title[#:tag "idtable"]{Identifier dictionaries}
|
||||
@title[#:tag "idtable"]{Dictionaries with Identifier Keys}
|
||||
|
||||
@defmodule[syntax/id-table]
|
||||
|
||||
This module provides functionality like that of
|
||||
@racketmodname[syntax/boundmap] but with more operations, standard
|
||||
names, implementation of the @racketmodname[scheme/dict] interface,
|
||||
and immutable (functionally-updating) variants.
|
||||
This module provides two implementations of @deftech{identifier tables}:
|
||||
dictionaries with identifier keys that use identifier-specific
|
||||
comparisons instead of @racket[eq?] or @racket[equal?]. Identifier
|
||||
tables implement the @racketmodname[racket/dict] interface, and they
|
||||
are available in both mutable and immutable variants.
|
||||
|
||||
@section{Dictionaries for @racket[bound-identifier=?]}
|
||||
@section{Dictionaries for @racket[free-identifier=?]}
|
||||
|
||||
Bound-identifier tables implement the dictionary interface of
|
||||
@racket[scheme/dict]. Consequently, all of the appropriate generic
|
||||
functions (@racket[dict-ref], @racket[dict-map], etc) can be used on
|
||||
free-identifier tables.
|
||||
A free-identifier table is a dictionary whose keys are compared using
|
||||
@racket[free-identifier=?]. Free-identifier tables implement the
|
||||
dictionary interface of @racket[racket/dict], so all of the
|
||||
appropriate generic functions (@racket[dict-ref], @racket[dict-map],
|
||||
etc) can be used on free-identifier tables.
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(make-bound-id-table
|
||||
@defproc[(make-free-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
mutable-bound-id-table?]
|
||||
@defproc[(make-immutable-bound-id-table
|
||||
mutable-free-id-table?]
|
||||
@defproc[(make-immutable-free-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
immutable-bound-id-table?]]]{
|
||||
immutable-free-id-table?]]]{
|
||||
|
||||
Produces a dictionary mapping syntax identifiers to arbitrary
|
||||
values. The mapping uses @racket[bound-identifier=?] to compare keys,
|
||||
but also uses a hash table based on symbol equality to make the
|
||||
mapping efficient in the common case. The two procedures produce
|
||||
mutable and immutable dictionaries, respectively.
|
||||
Produces a mutable free-identifier table or immutable free-identifier
|
||||
table, respectively. The dictionary uses @racket[free-identifier=?]
|
||||
to compare keys, but also uses a hash table based on symbol equality
|
||||
to make the dictionary efficient in the common case.
|
||||
|
||||
The identifiers are compared at phase level @racket[phase]. The
|
||||
default value is generally appropriate for identifier tables used by
|
||||
macros, but code that analyzes fully-expanded programs may need to
|
||||
create identifier tables at multiple different phases.
|
||||
default phase, @racket[(syntax-local-phase-level)], is generally
|
||||
appropriate for identifier tables used by macros, but code that
|
||||
analyzes fully-expanded programs may need to create separate
|
||||
identifier tables for each phase of the module.
|
||||
|
||||
The optional @racket[init-dict] argument provides the initial
|
||||
mappings. It must be a dictionary, and its keys must all be
|
||||
identifiers. If the @racket[init-dict] dictionary has multiple
|
||||
distinct entries whose keys are @racket[bound-identifier=?], only one
|
||||
distinct entries whose keys are @racket[free-identifier=?], only one
|
||||
of the entries appears in the new id-table, and it is not specified
|
||||
which entry is picked.
|
||||
}
|
||||
|
||||
@defproc[(bound-id-table? [v any/c]) boolean?]{
|
||||
@defproc[(free-id-table? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] was produced by
|
||||
@racket[make-bound-id-table] or
|
||||
@racket[make-immutable-bound-id-table], @racket[#f] otherwise.
|
||||
@racket[make-free-id-table] or
|
||||
@racket[make-immutable-free-id-table], @racket[#f] otherwise.
|
||||
}
|
||||
|
||||
@defproc[(mutable-free-id-table? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] was produced by
|
||||
@racket[make-free-id-table], @racket[#f] otherwise.
|
||||
}
|
||||
|
||||
@defproc[(immutable-free-id-table? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] was produced by
|
||||
@racket[make-immutable-free-id-table], @racket[#f] otherwise.
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-ref [table free-id-table?]
|
||||
[id identifier?]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
any]{
|
||||
|
||||
Like @racket[hash-ref]. In particular, if @racket[id] is not found,
|
||||
the @racket[failure] argument is applied if it is a procedure, or
|
||||
simply returned otherwise.
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-set! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-set!].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-set [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-free-id-table?]{
|
||||
|
||||
Like @racket[hash-set].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-remove! [table mutable-free-id-table?]
|
||||
[id identifier?])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-remove!].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-remove [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-free-id-table?]{
|
||||
|
||||
Like @racket[hash-remove].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-map [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
list?]{
|
||||
|
||||
Like @racket[hash-map].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-for-each [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-for-each].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-count [table free-id-table?])
|
||||
exact-nonnegative-integer?]{
|
||||
|
||||
Like @racket[hash-count].
|
||||
}
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(mutable-bound-id-table? [v any/c]) boolean?]
|
||||
@defproc[(immutable-bound-id-table? [v any/c]) boolean?]
|
||||
]]{
|
||||
@defproc[(free-id-table-iterate-first [table free-id-table?])
|
||||
id-table-iter?]
|
||||
@defproc[(free-id-table-iterate-next [table free-id-table?]
|
||||
[position id-table-iter?])
|
||||
id-table-iter?]
|
||||
@defproc[(free-id-table-iterate-key [table free-id-table?]
|
||||
[position id-table-iter?])
|
||||
identifier?]
|
||||
@defproc[(free-id-table-iterate-value [table bound-it-table?]
|
||||
[position id-table-iter?])
|
||||
identifier?]]]{
|
||||
|
||||
Predicate for the mutable and immutable variants of bound-identifier
|
||||
tables, respectively.
|
||||
Like @racket[hash-iterate-first], @racket[hash-iterate-next],
|
||||
@racket[hash-iterate-key], and @racket[hash-iterate-value],
|
||||
respectively.
|
||||
}
|
||||
|
||||
@defproc[(id-table-iter? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] represents a position in an
|
||||
identifier table (free or bound, mutable or immutable), @racket[#f]
|
||||
otherwise.
|
||||
}
|
||||
|
||||
|
||||
@;{----------}
|
||||
@section{Dictionaries for @racket[bound-identifier=?]}
|
||||
|
||||
A bound-identifier table is a dictionary whose keys are compared using
|
||||
@racket[bound-identifier=?]. Bound-identifier tables implement the
|
||||
dictionary interface of @racket[racket/dict], so all of the
|
||||
appropriate generic functions (@racket[dict-ref], @racket[dict-map],
|
||||
etc) can be used on bound-identifier tables.
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(make-bound-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
mutable-bound-id-table?]
|
||||
@defproc[(make-immutable-bound-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table? [v any/c]) boolean?]
|
||||
@defproc[(mutable-bound-id-table? [v any/c]) boolean?]
|
||||
@defproc[(immutable-bound-id-table? [v any/c]) boolean?]
|
||||
@defproc[(bound-id-table-ref [table bound-id-table?]
|
||||
[id identifier?]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
any]{
|
||||
|
||||
Like @racket[hash-ref] for bound identifier tables. In particular, if
|
||||
@racket[id] is not found, the @racket[failure] argument is applied if
|
||||
it is a procedure, or simply returned otherwise.
|
||||
}
|
||||
|
||||
any]
|
||||
@defproc[(bound-id-table-set! [table mutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-set!] for mutable bound-identifier tables.
|
||||
}
|
||||
|
||||
void?]
|
||||
@defproc[(bound-id-table-set [table immutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-bound-id-table?]{
|
||||
|
||||
Like @racket[hash-set] for immutable bound-identifier tables.
|
||||
}
|
||||
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-remove! [table mutable-bound-id-table?]
|
||||
[id identifier?])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-remove!] for mutable bound-identifier tables.
|
||||
}
|
||||
|
||||
void?]
|
||||
@defproc[(bound-id-table-remove [table immutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-bound-id-table?]{
|
||||
|
||||
Like @racket[hash-remove] for immutable bound-identifier tables.
|
||||
}
|
||||
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-map [table bound-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
list?]{
|
||||
|
||||
Like @racket[hash-map] for bound-identifier tables.
|
||||
}
|
||||
|
||||
list?]
|
||||
@defproc[(bound-id-table-for-each [table bound-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-for-each] for bound-identifier tables.
|
||||
}
|
||||
|
||||
void?]
|
||||
@defproc[(bound-id-table-count [table bound-id-table?])
|
||||
exact-nonnegative-integer?]{
|
||||
|
||||
Like @racket[hash-count] for bound-identifier tables.
|
||||
|
||||
}
|
||||
|
||||
exact-nonnegative-integer?]
|
||||
@;{
|
||||
@deftogether[[
|
||||
@defproc[(bound-id-table-iterate-first [table bound-id-table?])
|
||||
id-table-position?]
|
||||
@defproc[(bound-id-table-iterate-next [table bound-id-table?]
|
||||
|
@ -135,79 +213,13 @@ Like @racket[hash-count] for bound-identifier tables.
|
|||
@defproc[(bound-id-table-iterate-key [table bound-id-table?]
|
||||
[position id-table-position?])
|
||||
identifier?]
|
||||
@defproc[(bound-id-table-iterate-value [table bound-it-table?]
|
||||
[position id-table-position?])
|
||||
identifier?]]]{
|
||||
|
||||
Like the corresponding dictionary procedures from
|
||||
@racketmodname[scheme/dict] for for bound-identifier tables.
|
||||
}
|
||||
}
|
||||
|
||||
@;{----------}
|
||||
@section{Dictionaries for @racket[free-identifier=?]}
|
||||
|
||||
Free-identifier tables implement the dictionary interface of
|
||||
@racket[scheme/dict]. Consequently, all of the appropriate generic
|
||||
functions (@racket[dict-ref], @racket[dict-map], etc) can be used on
|
||||
free-identifier tables.
|
||||
|
||||
@deftogether[[
|
||||
@defproc[(make-free-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
mutable-free-id-table?]
|
||||
@defproc[(make-immutable-free-id-table
|
||||
[init-dict dict? null]
|
||||
[#:phase phase (or/c exact-integer? #f) (syntax-local-phase-level)])
|
||||
immutable-free-id-table?]
|
||||
@defproc[(free-id-table? [v any/c]) boolean?]
|
||||
@defproc[(mutable-free-id-table? [v any/c]) boolean?]
|
||||
@defproc[(immutable-free-id-table? [v any/c]) boolean?]
|
||||
@defproc[(free-id-table-ref [table free-id-table?]
|
||||
[id identifier?]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
any]
|
||||
@defproc[(free-id-table-set! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
void?]
|
||||
@defproc[(free-id-table-set [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-free-id-table?]
|
||||
@defproc[(free-id-table-remove! [table mutable-free-id-table?]
|
||||
[id identifier?])
|
||||
void?]
|
||||
@defproc[(free-id-table-remove [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-free-id-table?]
|
||||
@defproc[(free-id-table-map [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
list?]
|
||||
@defproc[(free-id-table-for-each [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
void?]
|
||||
@defproc[(free-id-table-count [table free-id-table?])
|
||||
exact-nonnegative-integer?]
|
||||
@;{
|
||||
@defproc[(free-id-table-iterate-first [table free-id-table?])
|
||||
id-table-position?]
|
||||
@defproc[(free-id-table-iterate-next [table free-id-table?]
|
||||
[position id-table-position?])
|
||||
id-table-position?]
|
||||
@defproc[(free-id-table-iterate-key [table free-id-table?]
|
||||
[position id-table-position?])
|
||||
identifier?]
|
||||
@defproc[(free-id-table-iterate-value [table free-it-table?]
|
||||
@defproc[(bound-id-table-iterate-value [table bound-id-table?]
|
||||
[position id-table-position?])
|
||||
identifier?]
|
||||
}]]{
|
||||
|
||||
Like the procedures for bound-identifier tables
|
||||
(@racket[make-bound-id-table], @racket[bound-id-table-ref], etc), but
|
||||
for free-identifier tables, which use @racket[free-identifier=?] to
|
||||
Like the procedures for free-identifier tables
|
||||
(@racket[make-free-id-table], @racket[free-id-table-ref], etc), but
|
||||
for bound-identifier tables, which use @racket[bound-identifier=?] to
|
||||
compare keys.
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
@include-section["stx.scrbl"]
|
||||
@include-section["kerncase.scrbl"]
|
||||
@include-section["boundmap.scrbl"]
|
||||
@include-section["id-table.scrbl"]
|
||||
@include-section["boundmap.scrbl"]
|
||||
@include-section["to-string.scrbl"]
|
||||
@include-section["free-vars.scrbl"]
|
||||
@include-section["strip-context.scrbl"]
|
||||
|
|
Loading…
Reference in New Issue
Block a user