#lang scribble/doc @(require "mz.ss") @title{Reading} @defproc[(read [in input-port? (current-input-port)]) any]{ Reads and returns a single @tech{datum} from @racket[in]. If @racket[in] has a handler associated to it via @racket[port-read-handler], then the handler is called. Otherwise, the default reader is used, as parameterized by the @racket[current-readtable] parameter, as well as many other parameters. See @secref["reader"] for information on the default reader.} @defproc[(read-syntax [source-name any/c (object-name in)] [in input-port? (current-input-port)]) (or/c syntax? eof-object?)]{ Like @racket[read], but produces a @tech{syntax object} with source-location information. The @racket[source-name] is used as the source field of the syntax object; it can be an arbitrary value, but it should generally be a path for the source file. See @secref["reader"] for information on the default reader in @racket[read-syntax] mode.} @defproc[(read/recursive [in input-port? (current-input-port)] [start (or/c char? #f) #f] [readtable (or/c readtable? #f) (current-readtable)] [graph? any/c #t]) any]{ Similar to calling @racket[read], but normally used during the dynamic extent of @racket[read] within a reader-extension procedure (see @secref["reader-procs"]). The main effect of using @racket[read/recursive] instead of @racket[read] is that graph-structure annotations (see @secref["parse-graph"]) in the nested read are considered part of the overall read, at least when the @racket[graph?] argument is true; since the result is wrapped in a placeholder, however, it is not directly inspectable. If @racket[start] is provided and not @racket[#f], it is effectively prefixed to the beginning of @racket[in]'s stream for the read. (To prefix multiple characters, use @racket[input-port-append].) The @racket[readtable] argument is used for top-level parsing to satisfy the read request; recursive parsing within the read (e.g., to read the elements of a list) instead uses the current readtable as determined by the @racket[current-readtable] parameter. A reader macro might call @racket[read/recursive] with a character and readtable to effectively invoke the readtable's behavior for the character. If @racket[readtable] is @racket[#f], the default readtable is used for top-level parsing. When @racket[graph?] is @racket[#f], graph structure annotations in the read datum are local to the datum. When called within the dynamic extent of @racket[read], the @racket[read/recursive] procedure produces either an opaque placeholder value, a special-comment value, or an end-of-file. The result is a special-comment value (see @secref["special-comments"]) when the input stream's first non-whitespace content parses as a comment. The result is end-of-file when @racket[read/recursive] encounters an end-of-file. Otherwise, the result is a placeholder that protects graph references that are not yet resolved. When this placeholder is returned within an S-expression that is produced by any reader-extension procedure (see @secref["reader-procs"]) for the same outermost @racket[read], it will be replaced with the actual read value before the outermost @racket[read] returns. See @secref["readtables"] for an extended example that uses @racket[read/recursive].} @defproc[(read-syntax/recursive [source-name any/c (object-name in)] [in input-port? (current-input-port)] [start (or/c char? #f) #f] [readtable (or/c readtable? #f) (current-readtable)] [graph? any/c #t]) any]{ Analogous to calling @racket[read/recursive], but the resulting value encapsulates S-expression structure with source-location information. As with @racket[read/recursive], when @racket[read-syntax/recursive] is used within the dynamic extent of @racket[read-syntax], the result from @racket[read-syntax/recursive] is either a special-comment value, end-of-file, or opaque graph-structure placeholder (not a syntax object). The placeholder can be embedded in an S-expression or syntax object returned by a reader macro, etc., and it will be replaced with the actual syntax object before the outermost @racket[read-syntax] returns. Using @racket[read/recursive] within the dynamic extent of @racket[read-syntax] does not allow graph structure for reading to be included in the outer @racket[read-syntax] parsing, and neither does using @racket[read-syntax/recursive] within the dynamic extent of @racket[read]. In those cases, @racket[read/recursive] and @racket[read-syntax/recursive] produce results like @racket[read] and @racket[read-syntax], except that a special-comment value is returned when the input stream starts with a comment (after whitespace). See @secref["readtables"] for an extended example that uses @racket[read-syntax/recursive].} @defproc[(read-language [in input-port? (current-input-port)] [fail-thunk (-> any) (lambda () (error ...))]) (any/c any/c . -> . any)]{ Reads from @racket[in] in the same way as @racket[read], but stopping as soon as a @tech{reader language} (or its absence) is determined. A @deftech{reader language} is specified by @litchar{#lang} or @litchar{#!} (see @secref["parse-reader"]) at the beginning of the input, though possibly after comment forms. The default @tech{readtable} is used by @racket[read-language] (instead of the value of @racket[current-readtable]), and @litchar{#reader} forms (which might produce comments) are not allowed before @litchar{#lang} or @litchar{#!}. @guidealso["language-get-info"] When it finds a @litchar{#lang} or @litchar{#!} specification, instead of dispatching to a @racketidfont{read} or @racketidfont{read-syntax} function as @racket[read] and @racket[read-syntax] do, @racket[read-language] dispatches to a @racketidfont{get-info} function (if any) exported by the same module. The result of the @racketidfont{get-info} function is the result of @racket[read-language] if it is a function of two arguments; if @racketidfont{get-info} produces any other kind of result, the @exnraise[exn:fail:contract]. The function produced by @racketidfont{get-info} reflects information about the expected syntax of the input stream. The first argument to the function serves as a key on such information; acceptable keys and the interpretation of results is up to external tools, such as DrRacket. If no information is available for a given key, the result should be the second argument. The @racketidfont{get-info} function itself is applied to five arguments: the input port being read, the module path from which the @racketidfont{get-info} function was extracted, and the source line (positive exact integer or @racket[#f]), column (non-negative exact integer or @racket[#f]), and position (positive exact integer or @racket[#f]) of the start of the @litchar{#lang} or @litchar{#!} form. The @racketidfont{get-info} function may further read from the given input port to determine its result, but it should read no further than necessary. The @racketidfont{get-info} function should not read from the port after returning a function. If @racket[in] starts with a @tech{reader language} specification but the relevant module does not export @racketidfont{get-info} (but perhaps does export @racketidfont{read} and @racketidfont{read-syntax}), then the result of @racket[read-language] is @racket[#f]. If @racket[in] has a @litchar{#lang} or @litchar{#!} specification, but parsing and resolving the specification raises an exception, the exception is propagated by @racket[read-language]. Having at least @litchar{#l} or @litchar{#!} (after comments and whitespace) counts as starting a @litchar{#lang} or @litchar{#!} specification. If @racket[in] does not specify a @tech{reader language} with @litchar{#lang} or @litchar{#!}, then @racket[fail-thunk] is called. The default @racket[fail-thunk] raises @racket[exn:fail:read] or @racket[exn:fail:read:eof].} @defboolparam[read-case-sensitive on?]{ A parameter that controls parsing and printing of symbols. When this parameter's value is @racket[#f], the reader case-folds symbols (e.g., producing @racket['hi] when the input is any one of @litchar{hi}, @litchar{Hi}, @litchar{HI}, or @litchar{hI}). The parameter also affects the way that @racket[write] prints symbols containing uppercase characters; if the parameter's value is @racket[#f], then symbols are printed with uppercase characters quoted by a @litchar{\} or @litchar{|}. The parameter's value is overridden by quoting @litchar{\} or @litchar{|} vertical-bar quotes and the @litchar{#cs} and @litchar{#ci} prefixes; see @secref["parse-symbol"] for more information. While a module is loaded, the parameter is set to @racket[#t] (see @racket[current-load]).} @defboolparam[read-square-bracket-as-paren on?]{ A parameter that controls whether @litchar{[} and @litchar{]} are treated as parentheses. See @secref["parse-pair"] for more information.} @defboolparam[read-curly-brace-as-paren on?]{ A parameter that controls whether @litchar["{"] and @litchar["}"] are treated as parentheses. See @secref["parse-pair"] for more information.} @defboolparam[read-accept-box on?]{ A parameter that controls parsing @litchar{#&} input. See @secref["parse-box"] for more information.} @defboolparam[read-accept-compiled on?]{ A parameter that controls parsing @litchar{#~} compiled input. See @secref["reader"] and @racket[current-compile] for more information.} @defboolparam[read-accept-bar-quote on?]{ A parameter that controls parsing and printing of @litchar{|} in symbols. See @secref["parse-symbol"] and @secref["printing"] for more information.} @defboolparam[read-accept-graph on?]{ A parameter value that controls parsing input with sharing. See @secref["parse-graph"] for more information.} @defboolparam[read-decimal-as-inexact on?]{ A parameter that controls parsing input numbers with a decimal point or exponent (but no explicit exactness tag). See @secref["parse-number"] for more information.} @defboolparam[read-accept-dot on?]{ A parameter that controls parsing input with a dot, which is normally used for literal cons cells. See @secref["parse-pair"] for more information.} @defboolparam[read-accept-infix-dot on?]{ A parameter that controls parsing input with two dots to trigger infix conversion. See @secref["parse-pair"] for more information.} @defboolparam[read-accept-quasiquote on?]{ A parameter that controls parsing input with @litchar{`} or @litchar{,} which is normally used for @racket[quasiquote], @racket[unquote], and @racket[unquote-splicing] abbreviations. See @secref["parse-quote"] for more information.} @defboolparam[read-accept-reader on?]{ A parameter that controls whether @litchar{#reader}, @litchar{#lang}, or @litchar{#!} are allowed for selecting a parser. See @secref["parse-reader"] for more information.} @defboolparam[read-accept-lang on?]{ A parameter that (along with @racket[read-accept-reader] controls whether @litchar{#lang} and @litchar{#!} are allowed for selecting a parser. See @secref["parse-reader"] for more information.} @defparam[current-reader-guard proc (any/c . -> . any)]{ A parameter whose value converts or rejects (by raising an exception) a module-path datum following @litchar{#reader}. See @secref["parse-reader"] for more information.} @defparam[current-readtable readtable (or/c readtable? #f)]{ A parameter whose value determines a readtable that adjusts the parsing of S-expression input, where @racket[#f] implies the default behavior. See @secref["readtables"] for more information.} @defparam[read-on-demand-source path (and/c path? complete-path?)]{ A parameter that enables lazy parsing of compiled code, so that closure bodies and syntax objects are extracted (and validated) from marshaled compiled code on demand. Normally, this parameter is set by the default @tech{load handler} when @racket[load-on-demand-enabled] is @racket[#t]. Even when parsing is delayed, compiled code is loaded into memory. If the @as-index{@envvar{PLT_DELAY_FROM_ZO}} environment variable is set (to any value) on start-up, however, even loading from disk is delayed. If the file at @tech{path} changes before the delayed code or syntax object is demanded, the read-on-demand most likely will encounter garbage, leading to an exception.} @defproc*[([(port-read-handler [in input-port?]) (case-> (input-port? . -> . any) (input-port? any/c . -> . any))] [(port-read-handler [in input-port?] [proc (case-> (input-port? . -> . any) (input-port? any/c . -> . any))]) void?])]{ Gets or sets the @deftech{port read handler} for @racket[in]. The handler called to read from the port when the built-in @racket[read] or @racket[read-syntax] procedure is applied to the port. (The port read handler is not used for @racket[read/recursive] or @racket[read-syntax/recursive].) A port read handler is applied to either one argument or two arguments: @itemize[ @item{A single argument is supplied when the port is used with @racket[read]; the argument is the port being read. The return value is the value that was read from the port (or end-of-file).} @item{Two arguments are supplied when the port is used with @racket[read-syntax]; the first argument is the port being read, and the second argument is a value indicating the source. The return value is a syntax object that was read from the port (or end-of-file).} ] The default port read handler reads standard Racket expressions with Racket's built-in parser (see @secref["reader"]). It handles a special result from a custom input port (see @racket[make-custom-input-port]) by treating it as a single expression, except that special-comment values (see @secref["special-comments"]) are treated as whitespace. The default port read handler itself can be customized through a readtable; see @secref["readtables"] for more information.} @defproc[(read-honu [in input-port? (current-input-port)]) any]{ Like @racket[read], but for Honu mode (see @secref["parse-honu"]).} @defproc[(read-honu-syntax [source-name any/c (object-name in)] [in input-port? (current-input-port)]) (or/c syntax? eof-object?)]{ Like @racket[read-syntax], but for Honu mode (see @secref["parse-honu"]).} @defproc[(read-honu/recursive [in input-port? (current-input-port)] [start (or/c char? #f) #f] [readtable (or/c readtable? #f) (current-readtable)] [graph? any/c #t]) any]{ Like @racket[read/recursive], but for Honu mode (see @secref["parse-honu"]).} @defproc[(read-honu-syntax/recursive [source-name any/c (object-name in)] [in input-port? (current-input-port)] [start (or/c char? #f) #f] [readtable (or/c readtable? #f) (current-readtable)] [graph? any/c #f]) any]{ Like @racket[read-syntax/recursive], but for Honu mode (see @secref["parse-honu"]).}