#lang scribble/doc @(require "mz.rkt") @title[#:tag "stxops"]{Syntax Object Content} @defproc[(syntax? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @tech{syntax object}, @racket[#f] otherwise. See also @secref["stxobj-model"].} @defproc[(identifier? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @tech{syntax object} and @racket[(syntax-e stx)] produces a symbol.} @defproc[(syntax-source [stx syntax?]) any]{ Returns the source for the @tech{syntax object} @racket[stx], or @racket[#f] if none is known. The source is represented by an arbitrary value (e.g., one passed to @racket[read-syntax]), but it is typically a file path string. Source-location information is dropped for a syntax object that is marshaled as part of compiled code; see also @racket[current-compile].} @defproc[(syntax-line [stx syntax?]) (or/c exact-positive-integer? #f)]{ Returns the line number (positive exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the line number or source is unknown. The result is @racket[#f] if and only if @racket[(syntax-column stx)] produces @racket[#f]. See also @secref["linecol"], and see @racket[syntax-source] for information about marshaling compiled @tech{syntax object}s.} @defproc[(syntax-column [stx syntax?]) (or/c exact-nonnegative-integer? #f)]{ Returns the column number (non-negative exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the source column is unknown. The result is @racket[#f] if and only if @racket[(syntax-line stx)] produces @racket[#f]. See also @secref["linecol"], and see @racket[syntax-source] for information about marshaling compiled @tech{syntax object}s.} @defproc[(syntax-position [stx syntax?]) (or/c exact-positive-integer? #f)]{ Returns the character position (positive exact integer) for the start of the @tech{syntax object} in its source, or @racket[#f] if the source position is unknown. See also @secref["linecol"], and see @racket[syntax-source] for information about marshaling compiled @tech{syntax object}s.} @defproc[(syntax-span [stx syntax?]) (or/c exact-nonnegative-integer? #f)]{ Returns the span (non-negative exact integer) in characters of the @tech{syntax object} in its source, or @racket[#f] if the span is unknown. See also @racket[syntax-source] for information about marshaling compiled @tech{syntax object}s.} @defproc[(syntax-original? [stx syntax?]) boolean?]{ Returns @racket[#t] if @racket[stx] has the property that @racket[read-syntax] attaches to the @tech{syntax object}s that they generate (see @secref["stxprops"]), and if @racket[stx]'s @tech{lexical information} does not indicate that the object was introduced by a syntax transformer (see @secref["stxobj-model"]). The result is @racket[#f] otherwise. This predicate can be used to distinguish @tech{syntax object}s in an expanded expression that were directly present in the original expression, as opposed to @tech{syntax object}s inserted by macros.} @defproc[(syntax-source-module [stx syntax?] [source? any/c #f]) (or/c module-path-index? symbol? path? resolved-module-path? #f)]{ Returns an indication of the module whose source contains @racket[stx], or @racket[#f] if @racket[stx] has no source module. If @racket[source?] is @racket[#f], then result is a module path index or symbol (see @secref["modpathidx"]) or a @tech{resolved module path}; if @racket[source?] is true, the result is a path or symbol corresponding to the loaded module's source in the sense of @racket[current-module-declare-source].} @defproc[(syntax-e [stx syntax?]) any]{ Unwraps the immediate datum structure from a @tech{syntax object}, leaving nested syntax structure (if any) in place. The result of @racket[(syntax-e stx)] is one of the following: @itemize[ @item{a symbol} @item{a @tech{syntax pair} (described below)} @item{the empty list} @item{an immutable vector containing @tech{syntax object}s} @item{an immutable box containing @tech{syntax object}s} @item{an immutable @tech{hash table} containing @tech{syntax object} values (but not necessarily @tech{syntax object} keys)} @item{an immutable @tech{prefab} structure containing @tech{syntax object}s} @item{some other kind of datum---usually a number, boolean, or string---that is @tech{interned} when @racket[datum-intern-literal] would convert the value} ] A @deftech{syntax pair} is a pair containing a @tech{syntax object} as its first element, and either the empty list, a syntax pair, or a syntax object as its second element. A @tech{syntax object} that is the result of @racket[read-syntax] reflects the use of delimited @litchar{.} in the input by creating a syntax object for every pair of parentheses in the source, and by creating a pair-valued @tech{syntax object} @italic{only} for parentheses in the source. See @secref["parse-pair"] for more information. If @racket[stx] is @tech{tainted} or @tech{armed}, then any syntax object in the result of @racket[(syntax-e stx)] is @tech{tainted}, and multiple calls to @racket[syntax-e] may return values that are not @racket[eq?]. For a @racket[stx] that is not @tech{armed}, the results from multiple calls to @racket[syntax-e] of @racket[stx] are @racket[eq?].} @defproc[(syntax->list [stx syntax?]) (or/c list? #f)]{ Returns a list of @tech{syntax object}s or @racket[#f]. The result is a list of @tech{syntax object}s when @racket[(syntax->datum stx)] would produce a list. In other words, @tech{syntax pairs} in @racket[(syntax-e stx)] are flattened. If @racket[stx] is @tech{tainted} or @tech{armed}, then any syntax object in the result of @racket[(syntax->list stx)] is @tech{tainted}.} @defproc[(syntax->datum [stx syntax?]) any]{ Returns a datum by stripping the lexical information, source-location information, properties, and tamper status from @racket[stx]. Inside of pairs, (immutable) vectors, (immutable) boxes, immutable @tech{hash table} values (not keys), and immutable @tech{prefab} structures, @tech{syntax object}s are recursively stripped. The stripping operation does not mutate @racket[stx]; it creates new pairs, vectors, boxes, hash tables, and @tech{prefab} structures as needed to strip lexical and source-location information recursively.} @defproc[(datum->syntax [ctxt (or/c syntax? #f)] [v any/c] [srcloc (or/c syntax? #f (list/c any/c (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f)) (vector/c any/c (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f) (or/c exact-nonnegative-integer? #f))) #f] [prop (or/c syntax? #f) #f] [ignored (or/c syntax? #f) #f]) syntax?]{ Converts the @tech{datum} @racket[v] to a @tech{syntax object}. The contents of pairs, vectors, and boxes, the fields of @tech{prefab} structures, and the values of immutable hash tables are recursively converted. The keys of @tech{prefab} structures and the keys of immutable hash tables are not converted. Mutable vectors and boxes are replaced by immutable vectors and boxes. For any kind of value other than a pair, vector, box, immutable @tech{hash table}, immutable @tech{prefab} structure, or @tech{syntax object}, conversion means wrapping the value with lexical information, source-location information, and properties after the value is @tech{interned} via @racket[datum-intern-literal]. Converted objects in @racket[v] are given the lexical context information of @racket[ctxt] and the source-location information of @racket[srcloc]. If @racket[v] is not already a @tech{syntax object}, then the resulting immediate @tech{syntax object} is given the properties (see @secref["stxprops"]) of @racket[prop]; if @racket[v] is a pair, vector, box, immutable @tech{hash table}, or immutable @tech{prefab} structure, recursively converted values are not given properties. If @racket[ctxt] is @tech{tainted} or @tech{armed}, then the resulting syntax object from @racket[datum->syntax] is @tech{tainted}. Any of @racket[ctxt], @racket[srcloc], or @racket[prop] can be @racket[#f], in which case the resulting syntax has no lexical context, source information, and/or new properties. If @racket[srcloc] is not @racket[#f] or a @tech{syntax object}, it must be a list or vector of five elements: @racketblock[ (list source-name line column position span) @#,elem{or} (vector source-name line column position span) ] where @racket[source-name-v] is an arbitrary value for the source name; @racket[line] is an integer for the source line, or @racket[#f]; @racket[column] is an integer for the source column, or @racket[#f]; @racket[position] is an integer for the source position, or @racket[#f]; and @racket[span] is an integer for the source span, or @racket[#f]. The @racket[line] and @racket[column] values must both be numbers or both be @racket[#f], otherwise the @exnraise[exn:fail:contract]. Graph structure is not preserved by the conversion of @racket[v] to a @tech{syntax object}. Instead, @racket[v] is essentially unfolded into a tree. If @racket[v] has a cycle through pairs, vectors, boxes, immutable @tech{hash tables}, and immutable @tech{prefab} structures, then the @exnraise[exn:fail:contract]. The @racket[ignored] argument is allowed for backward compatibility and has no effect on the returned syntax object.} @defproc[(datum-intern-literal [v any/c]) any/c]{ Converts some values to be consistent with an @tech{interned} result produced by the default reader in @racket[read-syntax] mode. If @racket[v] is a @tech{number}, @tech{character}, @tech{string}, @tech{byte string}, or @tech{regular expression}, then the result is a value that is @racket[equal?] to @racket[v] and @racket[eq?] to a potential result of the default reader. (Note that mutable strings and byte strings are @tech{interned} as immutable strings and byte strings.) If @racket[v] is an @tech{uninterned} or an @tech{unreadable symbol}, the result is still @racket[v], since an @tech{interned} symbol would not be @racket[equal?] to @racket[v]. The conversion process does not traverse compound values. For example, if @racket[v] is a @tech{pair} containing strings, then the strings within @racket[v] are not @tech{interned}. If @racket[_v1] and @racket[_v2] are @racket[equal?] but not @racket[eq?], then it is possible that @racket[(datum-intern-literal _v1)] will return @racket[_v1] and---sometime after @racket[_v1] becomes unreachable as determined by the garbage collector (see @secref["gc-model"])---@racket[(datum-intern-literal _v2)] can still return @racket[_v2]. In other words, @racket[datum-intern-literal] may adopt a given value as an @tech{interned} representative, but if a former representative becomes otherwise unreachable, then @racket[datum-intern-literal] may adopt a new representative.} @defproc[(syntax-shift-phase-level [stx syntax?] [shift (or/c exact-integer? #f)]) syntax?]{ Returns a syntax object that is like @racket[stx], but with all of its top-level and module binding shifted by @racket[shift] @tech{phase levels}. If @racket[shift] is @racket[#f], then only bindings at @tech{phase level} 0 are shifted to the @tech{label phase level}. If @racket[shift] is @racket[0], then the result is @racket[stx].} @defproc[(generate-temporaries [stx-pair (or syntax? list?)]) (listof identifier?)]{ Returns a list of identifiers that are distinct from all other identifiers. The list contains as many identifiers as @racket[stx-pair] contains elements. The @racket[stx-pair] argument must be a syntax pair that can be flattened into a list. The elements of @racket[stx-pair] can be anything, but string, symbol, keyword (possibly wrapped as syntax), and identifier elements will be embedded in the corresponding generated name, which is useful for debugging purposes. The generated identifiers are built with interned symbols (not @racket[gensym]s); see also @secref["print-compiled"].} @defproc[(identifier-prune-lexical-context [id-stx identifier?] [syms (listof symbol?) (list (syntax-e id-stx))]) identifier?]{ Returns an identifier with the same binding as @racket[id-stx], but without lexical information from @racket[id-stx] that does not apply to the symbols in @racket[syms], where even further extension of the lexical information drops information for other symbols. In particular, transferring the lexical context via @racket[datum->syntax] from the result of this function to a symbol other than one in @racket[syms] produces an identifier with no binding. See also @racket[quote-syntax/prune].} @defproc[(identifier-prune-to-source-module [id-stx identifier?]) identifier?]{ Returns an identifier with its lexical context minimized to that needed for @racket[syntax-source-module]. The minimized lexical context does not include any bindings.} @defproc[(syntax-recertify [new-stx syntax?] [old-stx syntax?] [inspector inspector?] [key any/c]) syntax?]{ For backward compatibility only; returns @racket[new-stx].}