On this page:
3.1 Extracting Inferred Names
syntax-local-infer-name
3.2 Support for local-expand
build-expand-context
generate-expand-context
3.3 Parsing define-like Forms
normalize-definition
3.4 Expanding define-struct-like Forms
parse-define-struct
build-struct-names
build-struct-generation
build-struct-generation*
build-struct-expand-info
struct-declaration-info?
generate-struct-declaration
3.5 Resolving include-like Paths
resolve-path-spec
Version: 4.1

3 Macro Transformer Helpers

3.1 Extracting Inferred Names

 (require syntax/name)

(syntax-local-infer-name stx)  (or/c symbol? false/c)

  stx : syntax?

Similar to syntax-local-name except that stx is checked for an 'inferred-name property (which overrides any inferred name). If neither syntax-local-name nor 'inferred-name produce a name, then a name is constructed from the source-location information in stx, if any. If no name can be constructed, the result is #f.

3.2 Support for local-expand

 (require syntax/context)

(build-expand-context v)  list?

  v : (or/c symbol? list?)

Returns a list suitable for use as a context argument to local-expand for an internal-definition context. The v argument represents the immediate context for expansion. The context list builds on (syntax-local-context) if it is a list.

(generate-expand-context)  list?

Calls build-expand-context with a generated symbol.

3.3 Parsing define-like Forms

 (require syntax/define)

(normalize-definition

 

defn-stx

 

 

 

 

 

 

lambda-id-stx

 

 

 

 

 

 [

check-context?

 

 

 

 

 

 

opt+kws?])

 

 

identifier?

 

syntax?

  defn-stx : syntax?

  lambda-id-stx : identifier?

  check-context? : boolean? = #t

  opt+kws? : boolean? = #t

Takes a definition form whose shape is like define (though possibly with a different name) and returns two values: the defined identifier and the right-hand side expression.

To generate the right-hand side, this function may need to insert uses of lambda. The lambda-id-stx argument provides a suitable lambda identifier.

If the definition is ill-formed, a syntax error is raised. If check-context? is true, then a syntax error is raised if (syntax-local-context) indicates that the current context is an expression context. The default value of check-context? is #t.

If opt-kws? is #t, then arguments of the form [id expr], keyword id, and keyword [id expr] are allowed, and they are preserved in the expansion.

3.4 Expanding define-struct-like Forms

 (require syntax/struct)

(parse-define-struct stx orig-stx)

 

 

identifier?

(or/c identifier? false/c)

(listof identifier?)

syntax?

  stx : syntax?

  orig-stx : syntax?

Parses stx as a define-struct form, but uses orig-stx to report syntax errors (under the assumption that orig-stx is the same as stx, or that they at least share sub-forms). The result is four values: an identifier for the struct type name, a identifier or #f for the super-name, a list of identifiers for fields, and a syntax object for the inspector expression.

(build-struct-names

 

name-id

 

 

 

 

 

 

field-ids

 

 

 

 

 

 

omit-sel?

 

 

 

 

 

 

omit-set?

 

 

 

 

 

 [

src-stx])

 

 

(listof identifier?)

  name-id : identifier?

  field-ids : (listof identifier?)

  omit-sel? : boolean?

  omit-set? : boolean?

  src-stx : (or/c syntax? false/c) = #f

Generates the names bound by define-struct given an identifier for the struct type name and a list of identifiers for the field names. The result is a list of identifiers:

If omit-sel? is true, then the selector names are omitted from the result list. If omit-set? is true, then the setter names are omitted from the result list.

The default src-stx is #f; it is used to provide a source location to the generated identifiers.

(build-struct-generation

 

name-id

 

 

 

field-ids

 

 

 

omit-sel?

 

 

 

omit-set?

 

 

 [

super-type

 

 

 

prop-value-list

 

 

 

immutable-k-list])

 

  (listof identifier?)

  name-id : identifier?

  field-ids : (listof identifier?)

  omit-sel? : boolean?

  omit-set? : boolean?

  super-type : any/c = #f

  prop-value-list : list? = empty

  immutable-k-list : list? = empty

Takes the same arguments as build-struct-names and generates an S-expression for code using make-struct-type to generate the structure type and return values for the identifiers created by build-struct-names. The optional super-type, prop-value-list, and immutable-k-list parameters take S-expression values that are used as the corresponding arguments to make-struct-type.

(build-struct-generation*

 

all-name-ids

 

 

 

name-id

 

 

 

field-ids

 

 

 

omit-sel?

 

 

 

omit-set?

 

 

 [

super-type

 

 

 

prop-value-list

 

 

 

immutable-k-list])

 

  (listof identifier?)

  all-name-ids : (listof identifier?)

  name-id : identifier?

  field-ids : (listof identifier?)

  omit-sel? : boolean?

  omit-set? : boolean?

  super-type : any/c = #f

  prop-value-list : list? = empty

  immutable-k-list : list? = empty

Like build-struct-generation, but given the names produced by build-struct-names, instead of re-generating them.

(build-struct-expand-info

 

name-id

 

 

 

 

 

 

field-ids

 

 

 

 

 

 

omit-sel?

 

 

 

 

 

 

omit-set?

 

 

 

 

 

 

base-name

 

 

 

 

 

 

base-getters

 

 

 

 

 

 

base-setters)

 

 

any

  name-id : identifier?

  field-ids : (listof identifier?)

  omit-sel? : boolean?

  omit-set? : boolean?

  base-name : (or/c identifier? boolean?)

  base-getters : (listof (or/c identifier? false/c))

  base-setters : (listof (or/c identifier? false/c))

Takes the same arguments as build-struct-names, plus a parent identifier/#t/#f and a list of accessor and mutator identifiers (possibly ending in #f) for a parent type, and generates an S-expression for expansion-time code to be used in the binding for the structure name. A #t for the base-name means no super-type, #f means that the super-type (if any) is unknown, and an identifier indicates the super-type identifier.

(struct-declaration-info? v)  boolean?

  v : any/c

Returns #t if x has the shape of expansion-time information for structure type declarations, #f otherwise. See Structure Type Transformer Binding.

(generate-struct-declaration

 

orig-stx

 

 

 

 

 

 

name-id

 

 

 

 

 

 

super-id-or-false

 

 

 

 

 

 

field-id-list

 

 

 

 

 

 

current-context

 

 

 

 

 

 

make-make-struct-type

 

 

 

 

 

 [

omit-sel?

 

 

 

 

 

 

omit-set?])

 

 

syntax?

  orig-stx : syntax?

  name-id : identifier?

  super-id-or-false : (or/c identifier? false/c)

  field-id-list : (listof identifier?)

  current-context : any/c

  make-make-struct-type : procedure?

  omit-sel? : boolean? = #f

  omit-set? : boolean? = #f

This procedure implements the core of a define-struct expansion.

The generate-struct-declaration procedure is called by a macro expander to generate the expansion, where the name-id, super-id-or-false, and field-id-list arguments provide the main parameters. The current-context argument is normally the result of syntax-local-context. The orig-stx argument is used for syntax errors. The optional omit-sel? and omit-set? arguments default to #f; a #t value suppresses definitions of field selectors or mutators, respectively.

The make-struct-type procedure is called to generate the expression to actually create the struct type. Its arguments are orig-stx, name-id-stx, defined-name-stxes, and super-info. The first two are as provided originally to generate-struct-declaration, the third is the set of names generated by build-struct-names, and the last is super-struct info obtained by resolving super-id-or-false when it is not #f, #f otherwise.

The result should be an expression whose values are the same as the result of make-struct-type. Thus, the following is a basic make-make-struct-type:

  (lambda (orig-stx name-stx defined-name-stxes super-info)

    #`(make-struct-type '#,name-stx

                         #,(and super-info (list-ref super-info 0))

                         #,(/ (- (length defined-name-stxes) 3) 2)

                         0 #f))

but an actual make-make-struct-type will likely do more.

3.5 Resolving include-like Paths

 (require syntax/path-spec)

(resolve-path-spec

 

path-spec-stx

 

 

 

 

 

 

source-stx

 

 

 

 

 

 

expr-stx

 

 

 

 

 

 

build-path-stx)

 

 

complete-path?

  path-spec-stx : syntax?

  source-stx : syntax?

  expr-stx : syntax?

  build-path-stx : syntax?

Resolves the syntactic path specification path-spec-stx as for include.

The source-stx specifies a syntax object whose source-location information determines relative-path resolution. The expr-stx is used for reporting syntax errors. The build-path-stx is usually #'build-path; it provides an identifier to compare to parts of path-spec-stx to recognize the build-path keyword.