/collects/syntax/scribblings/struct.scrbl

http://github.com/gmarceau/PLT · Racket · 163 lines · 132 code · 31 blank · 0 comment · 13 complexity · 5fb42642dcec176f3d84e5e910164af4 MD5 · raw file

  1. #lang scribble/doc
  2. @(require "common.rkt" (for-label syntax/struct))
  3. @title[#:tag "struct"]{Expanding @racket[define-struct]-like Forms}
  4. @defmodule[syntax/struct]
  5. @defproc[(parse-define-struct [stx syntax?] [orig-stx syntax?])
  6. (values identifier?
  7. (or/c identifier? false/c)
  8. (listof identifier?)
  9. syntax?)]{
  10. Parses @racket[stx] as a @racket[define-struct] form, but uses
  11. @racket[orig-stx] to report syntax errors (under the assumption that
  12. @racket[orig-stx] is the same as @racket[stx], or that they at least share
  13. sub-forms). The result is four values: an identifier for the struct
  14. type name, a identifier or #f for the super-name, a list of
  15. identifiers for fields, and a syntax object for the inspector
  16. expression.}
  17. @defproc[(build-struct-names [name-id identifier?]
  18. [field-ids (listof identifier?)]
  19. [#:constructor-name ctr-name (or/c identifier? #f) #f]
  20. [omit-sel? boolean?]
  21. [omit-set? boolean?]
  22. [src-stx (or/c syntax? false/c) #f])
  23. (listof identifier?)]{
  24. Generates the names bound by @racket[define-struct] given an
  25. identifier for the struct type name and a list of identifiers for the
  26. field names. The result is a list of identifiers:
  27. @itemize[
  28. @item{@racketidfont{struct:}@racket[name-id]}
  29. @item{@racket[ctr-name], or @racketidfont{make-}@racket[name-id] if @racket[ctr-name] is @racket[#f]}
  30. @item{@racket[name-id]@racketidfont{?}}
  31. @item{@racket[name-id]@racketidfont{-}@racket[_field], for each
  32. @racket[_field] in @racket[field-ids].}
  33. @item{@racketidfont{set-}@racket[name-id]@racketidfont{-}@racket[_field]@racketidfont{!}
  34. (getter and setter names alternate).}
  35. @item{....}]
  36. If @racket[omit-sel?] is true, then the selector names are omitted from the
  37. result list. If @racket[omit-set?] is true, then the setter names are omitted
  38. from the result list.
  39. The default @racket[src-stx] is @racket[#f]; it is used to provide a
  40. source location to the generated identifiers.}
  41. @defproc[(build-struct-generation [name-id identifier?]
  42. [field-ids (listof identifier?)]
  43. [#:constructor-name ctr-name (or/c identifier? #f) #f]
  44. [omit-sel? boolean?]
  45. [omit-set? boolean?]
  46. [super-type any/c #f]
  47. [prop-value-list list? empty]
  48. [immutable-k-list list? empty])
  49. (listof identifier?)]{
  50. Takes the same arguments as @racket[build-struct-names] and generates
  51. an S-expression for code using @racket[make-struct-type] to generate
  52. the structure type and return values for the identifiers created by
  53. @racket[build-struct-names]. The optional @racket[super-type],
  54. @racket[prop-value-list], and @racket[immutable-k-list] parameters take
  55. S-expression values that are used as the corresponding arguments to
  56. @racket[make-struct-type].}
  57. @defproc[(build-struct-generation* [all-name-ids (listof identifier?)]
  58. [name-id identifier?]
  59. [field-ids (listof identifier?)]
  60. [#:constructor-name ctr-name (or/c identifier? #f) #f]
  61. [omit-sel? boolean?]
  62. [omit-set? boolean?]
  63. [super-type any/c #f]
  64. [prop-value-list list? empty]
  65. [immutable-k-list list? empty])
  66. (listof identifier?)]{
  67. Like @racket[build-struct-generation], but given the names produced by
  68. @racket[build-struct-names], instead of re-generating them.}
  69. @defproc[(build-struct-expand-info [name-id identifier?]
  70. [field-ids (listof identifier?)]
  71. [#:omit-constructor? no-ctr? any/c #f]
  72. [#:constructor-name ctr-name (or/c identifier? #f) #f]
  73. [#:omit-struct-type? no-type? any/c #f]
  74. [omit-sel? boolean?]
  75. [omit-set? boolean?]
  76. [base-name (or/c identifier? boolean?)]
  77. [base-getters (listof (or/c identifier? false/c))]
  78. [base-setters (listof (or/c identifier? false/c))])
  79. any]{
  80. Takes mostly the same arguments as @racket[build-struct-names], plus a parent
  81. identifier/@racket[#t]/@racket[#f] and a list of accessor and mutator
  82. identifiers (possibly ending in @racket[#f]) for a parent type, and
  83. generates an S-expression for expansion-time code to be used in the
  84. binding for the structure name.
  85. If @racket[no-ctr?] is true, then the constructor name is omitted from
  86. the expansion-time information. Similarly, if @racket[no-type?] is
  87. true, then the structure-type name is omitted.
  88. A @racket[#t] for the @racket[base-name] means no super-type,
  89. @racket[#f] means that the super-type (if any) is unknown, and an
  90. identifier indicates the super-type identifier.}
  91. @defproc[(struct-declaration-info? [v any/c]) boolean?]{
  92. Returns @racket[#t] if @racket[x] has the shape of expansion-time
  93. information for structure type declarations, @racket[#f] otherwise.
  94. See @secref[#:doc refman]{structinfo}.}
  95. @defproc[(generate-struct-declaration [orig-stx syntax?]
  96. [name-id identifier?]
  97. [super-id-or-false (or/c identifier? false/c)]
  98. [field-id-list (listof identifier?)]
  99. [current-context any/c]
  100. [make-make-struct-type procedure?]
  101. [omit-sel? boolean? #f]
  102. [omit-set? boolean? #f])
  103. syntax?]{
  104. This procedure implements the core of a @racket[define-struct]
  105. expansion.
  106. The @racket[generate-struct-declaration] procedure is called by a
  107. macro expander to generate the expansion, where the @racket[name-id],
  108. @racket[super-id-or-false], and @racket[field-id-list] arguments
  109. provide the main parameters. The @racket[current-context] argument is
  110. normally the result of @racket[syntax-local-context]. The
  111. @racket[orig-stx] argument is used for syntax errors. The optional
  112. @racket[omit-sel?] and @racket[omit-set?] arguments default to
  113. @racket[#f]; a @racket[#t] value suppresses definitions of field
  114. selectors or mutators, respectively.
  115. The @racket[make-struct-type] procedure is called to generate the
  116. expression to actually create the struct type. Its arguments are
  117. @racket[orig-stx], @racket[name-id-stx], @racket[defined-name-stxes],
  118. and @racket[super-info]. The first two are as provided originally to
  119. @racket[generate-struct-declaration], the third is the set of names
  120. generated by @racket[build-struct-names], and the last is super-struct
  121. info obtained by resolving @racket[super-id-or-false] when it is not
  122. @racket[#f], @racket[#f] otherwise.
  123. The result should be an expression whose values are the same as the
  124. result of @racket[make-struct-type]. Thus, the following is a basic
  125. @racket[make-make-struct-type]:
  126. @RACKETBLOCK[
  127. (lambda (orig-stx name-stx defined-name-stxes super-info)
  128. #`(make-struct-type '#,name-stx
  129. #,(and super-info (list-ref super-info 0))
  130. #,(/ (- (length defined-name-stxes) 3) 2)
  131. 0 #f))]
  132. but an actual @racket[make-make-struct-type] will likely do more.}