/racket-5-0-2-bin-i386-osx-mac-dmg/collects/scribblings/reference/stx-comp.scrbl

http://github.com/smorin/f4f.arc · Racket · 217 lines · 170 code · 47 blank · 0 comment · 26 complexity · 436e25c933109f4ab0e9858aca80a7e6 MD5 · raw file

  1. #lang scribble/doc
  2. @(require "mz.ss")
  3. @(define stx-eval (make-base-eval))
  4. @(interaction-eval #:eval stx-eval (require (for-syntax racket/base)))
  5. @title[#:tag "stxcmp"]{Syntax Object Bindings}
  6. @defproc[(bound-identifier=? [a-id syntax?] [b-id syntax?]
  7. [phase-level (or/c exact-integer? #f)
  8. (syntax-local-phase-level)])
  9. boolean?]{
  10. Returns @scheme[#t] if the identifier @scheme[a-id] would bind
  11. @scheme[b-id] (or vice versa) if the identifiers were substituted in a
  12. suitable expression context at the @tech{phase level} indicated by
  13. @scheme[phase-level], @scheme[#f] otherwise. A @scheme[#f] value for
  14. @scheme[phase-level] corresponds to the @tech{label phase level}.
  15. @examples[
  16. #:eval stx-eval
  17. (define-syntax (check stx)
  18. (syntax-case stx ()
  19. [(_ x y)
  20. (if (bound-identifier=? #'x #'y)
  21. #'(let ([y 'wrong]) (let ([x 'binds]) y))
  22. #'(let ([y 'no-binds]) (let ([x 'wrong]) y)))]))
  23. (check a a)
  24. (check a b)
  25. (define-syntax-rule (check-a x) (check a x))
  26. (check-a a)
  27. ]}
  28. @defproc[(free-identifier=? [a-id syntax?] [b-id syntax?]
  29. [phase-level (or/c exact-integer? #f)
  30. (syntax-local-phase-level)])
  31. boolean?]{
  32. Returns @scheme[#t] if @scheme[a-id] and @scheme[b-id] access the same
  33. @tech{local binding}, @tech{module binding}, or @tech{top-level
  34. binding}---perhaps via @tech{rename transformers}---at the @tech{phase
  35. level} indicated by @scheme[phase-level]. A @scheme[#f] value for
  36. @scheme[phase-level] corresponds to the @tech{label phase level}.
  37. ``Same module binding'' means that the identifiers refer to the same
  38. original definition site, and not necessarily to the same
  39. @scheme[require] or @scheme[provide] site. Due to renaming in
  40. @scheme[require] and @scheme[provide], or due to a transformer binding
  41. to a @tech{rename transformer}, the identifiers may return distinct
  42. results with @scheme[syntax-e].
  43. @examples[
  44. #:eval stx-eval
  45. (define-syntax (check stx)
  46. (syntax-case stx ()
  47. [(_ x)
  48. (if (free-identifier=? #'car #'x)
  49. #'(list 'same: x)
  50. #'(list 'different: x))]))
  51. (check car)
  52. (check mcar)
  53. (let ([car list])
  54. (check car))
  55. (require (rename-in racket/base [car kar]))
  56. (check kar)
  57. ]}
  58. @defproc[(free-transformer-identifier=? [a-id syntax?] [b-id syntax?]) boolean?]{
  59. Same as @scheme[(free-identifier=? a-id b-id (add1 (syntax-local-phase-level)))].}
  60. @defproc[(free-template-identifier=? [a-id syntax?] [b-id syntax?]) boolean?]{
  61. Same as @scheme[(free-identifier=? a-id b-id (sub1 (syntax-local-phase-level)))].}
  62. @defproc[(free-label-identifier=? [a-id syntax?] [b-id syntax?]) boolean?]{
  63. Same as @scheme[(free-identifier=? a-id b-id #f)].}
  64. @defproc[(check-duplicate-identifier [ids (listof identifier?)])
  65. (or/c identifier? #f)]{
  66. Compares each identifier in @scheme[ids] with every other identifier
  67. in the list with @scheme[bound-identifier=?]. If any comparison
  68. returns @scheme[#t], one of the duplicate identifiers is returned (the
  69. first one in @scheme[ids] that is a duplicate), otherwise the result
  70. is @scheme[#f].}
  71. @defproc[(identifier-binding [id-stx syntax?]
  72. [phase-level (or/c exact-integer? #f)
  73. (syntax-local-phase-level)])
  74. (or/c 'lexical
  75. #f
  76. (listof module-path-index?
  77. symbol?
  78. module-path-index?
  79. symbol?
  80. (or/c 0 1)
  81. (or/c exact-integer? #f)
  82. (or/c exact-integer? #f)))]{
  83. Returns one of three kinds of values, depending on the binding of
  84. @scheme[id-stx] at the @tech{phase level} indicated by
  85. @scheme[phase-level] (where a @scheme[#f] value for
  86. @scheme[phase-level] corresponds to the @tech{label phase level}):
  87. @itemize[
  88. @item{The result is @indexed-scheme['lexical] if @scheme[id-stx]
  89. has a @tech{local binding}. If @scheme['lexical] is produced for
  90. any @scheme[phase-level] value, then it is produced for all
  91. @scheme[phase-level] values.}
  92. @item{The result is a list of seven items when @scheme[id-stx]
  93. has a @tech{module binding}: @scheme[(list _source-mod _source-id
  94. _nominal-source-mod _nominal-source-id _source-phase _import-phase
  95. _nominal-export-phase)].
  96. @itemize[
  97. @item{@scheme[_source-mod] is a module path index (see
  98. @secref["modpathidx"]) that indicates the defining module.}
  99. @item{@scheme[_source-id] is a symbol for the identifier's name
  100. at its definition site in the source module. This can be
  101. different from the local name returned by
  102. @scheme[syntax->datum] for several reasons: the identifier is
  103. renamed on import, it is renamed on export, or it is
  104. implicitly renamed because the identifier (or its import) was
  105. generated by a macro invocation.}
  106. @item{@scheme[_nominal-source-mod] is a module path index (see
  107. @secref["modpathidx"]) that indicates the module
  108. @scheme[require]d into the context of @scheme[id-stx] to
  109. provide its binding. It can be different from
  110. @scheme[_source-mod] due to a re-export in
  111. @scheme[_nominal-source-mod] of some imported identifier. If
  112. the same binding is imported in multiple ways, an arbitrary
  113. representative is chosen.}
  114. @item{@scheme[_nominal-source-id] is a symbol for the
  115. identifier's name as exported by
  116. @scheme[_nominal-source-mod]. It can be different from
  117. @scheme[_source-id] due to a renaming @scheme[provide], even if
  118. @scheme[_source-mod] and @scheme[_nominal-source-mod] are the
  119. same.}
  120. @item{@scheme[_source-phase] is @scheme[1] if the source
  121. definition is for-syntax, @scheme[0] otherwise.}
  122. @item{@scheme[_import-phase] is @scheme[0] if the binding
  123. import of @scheme[_nominal-source-mode] is a plain
  124. @scheme[require], @scheme[1] if it is from a
  125. @scheme[for-syntax] import, etc.}
  126. @item{@scheme[_nominal-export-phase] is the @tech{phase level}
  127. of the export from @scheme[_nominal-source-mod].}
  128. ]}
  129. @item{The result is @scheme[#f] if @scheme[id-stx] has a
  130. @tech{top-level binding} (or, equivalently, if it is
  131. @tech{unbound}).}
  132. ]
  133. If @scheme[id-stx] is bound to a @tech{rename-transformer}, the result
  134. from @scheme[identifier-binding] is for the identifier in the
  135. transformer, so that @scheme[identifier-binding] is consistent with
  136. @scheme[free-identifier=?].}
  137. @defproc[(identifier-transformer-binding [id-stx syntax?])
  138. (or/c 'lexical
  139. #f
  140. (listof module-path-index?
  141. symbol?
  142. module-path-index?
  143. symbol?
  144. (or/c 0 1)
  145. (or/c exact-integer? #f)
  146. (or/c exact-integer? #f)))]{
  147. Same as @scheme[(identifier-binding id-stx (add1 (syntax-local-phase-level)))].}
  148. @defproc[(identifier-template-binding [id-stx syntax?])
  149. (or/c 'lexical
  150. #f
  151. (listof module-path-index?
  152. symbol?
  153. module-path-index?
  154. symbol?
  155. (or/c 0 1)
  156. (or/c exact-integer? #f)
  157. (or/c exact-integer? #f)))]{
  158. Same as @scheme[(identifier-binding id-stx (sub1 (syntax-local-phase-level)))].}
  159. @defproc[(identifier-label-binding [id-stx syntax?])
  160. (or/c 'lexical
  161. #f
  162. (listof module-path-index?
  163. symbol?
  164. module-path-index?
  165. symbol?
  166. (or/c 0 1)
  167. (or/c exact-integer? #f)
  168. (or/c exact-integer? #f)))]{
  169. Same as @scheme[(identifier-binding id-stx #f)].}
  170. @close-eval[stx-eval]