diff --git a/collects/syntax/scribblings/boundmap.scrbl b/collects/syntax/scribblings/boundmap.scrbl index 533fcdb31c..89bfc8416f 100644 --- a/collects/syntax/scribblings/boundmap.scrbl +++ b/collects/syntax/scribblings/boundmap.scrbl @@ -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. +} diff --git a/collects/syntax/scribblings/id-table.scrbl b/collects/syntax/scribblings/id-table.scrbl index 4aede4f9cd..95b2741371 100644 --- a/collects/syntax/scribblings/id-table.scrbl +++ b/collects/syntax/scribblings/id-table.scrbl @@ -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. } diff --git a/collects/syntax/scribblings/syntax-object-helpers.scrbl b/collects/syntax/scribblings/syntax-object-helpers.scrbl index 78f46edf2d..300e165968 100644 --- a/collects/syntax/scribblings/syntax-object-helpers.scrbl +++ b/collects/syntax/scribblings/syntax-object-helpers.scrbl @@ -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"]