1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#lang scribble/manual
@(define ((line chars) . expl)
(list (hspace 1) (litchar chars) expl))
@(define (litchars s)
(tabular
#:sep (hspace 1)
(list (cons (hspace 1) (map (lambda (c) (litchar (string c))) (string->list s))))))
@title[#:tag "reader"]{Zuo S-Expression Reader}
The Zuo reader recognizes a subset (roughly) of Racket S-expression
notation. The reader works in terms of bytes as characters, not
Unicode. It reads and potentially recurs based on a starting character
sequence after skipping ASCII whitespace characters:
@tabular[
#:sep @hspace[1]
(list
@@line{;}{starts a line comment}
@@line{#!}{starts a line comment; @litchar{\} at then end of a line to the next}
@@line{#;}{comments out the next S-expression}
@@line{(}{starts a pair or list; see @secref["read-list"]}
@@line{[}{starts a pair or list; see @secref["read-list"]}
@@line{.}{creates a pair when delimited afterward; see @secref["read-list"]}
@@line{"}{starts a string; see @secref["read-string"]}
@@line{#"}{starts a string; see @secref["read-string"]}
@@line{#t}{starts a boolean; see @secref["read-boolean"]}
@@line{#f}{starts a boolean; see @secref["read-boolean"]}
@@line{'}{creates a list with @racket[quote] and the next S-expression}
@@line{`}{creates a list with @racket[quasiquote] and the next S-expression}
@@line{,}{creates a list with @racket[unquote] and the next S-expression}
@@line|{,@}|{creates a list with @racket[unquote-splicing] and the next S-expression})
]
A @litchar{#} followed by any other character is not allowed. Other
starting character sequences either create a number (see
@secref["read-number"]) or symbol (see @secref["read-symbol"]), or
they are disallowed. Any character that is not allowed with a symbol
(see @secref["read-symbol"]) counts as a delimiter.
@section[#:tag "read-number"]{Reading Numbers}
A Zuo number starts optionally @litchar{-} and then one or more
decimal digits. It must be delimited afterward. The resulting integer
must fit into a 64-bit two's complement representation. Any number of
leading @litchar{0}s is allowed.
Zuo does not support floating-point numbers, and it does not allow
@litchar{+} at the beginning of a number. Such sequences will parse as
symbols.
@section[#:tag "read-symbol"]{Reading Symbols}
A symbol can include any ASCII digit, alphabetic character for the
following characters:
@litchars|{~!@#$%^&*-_=+:<>?/.}|
Although @litchar{#} is allowed within a symbol, a symbol cannot start with
@litchar{#}. A sequence that optional starts @litchar{-} with one or
more digits up to a delimited is parsed as a number (see
@secref["read-number"]) instead of a symbol. A delimited @litchar{.}
is not a symbol.
@section[#:tag "read-string"]{Reading Strings}
A string starts with @litchar{#"} or @litchar{"} and ends with a matching
@litchar{"}. Any character is allowed in a string, except for a
newline or return character. The following escapes are supported with
the usual meaning: @litchar{\"}, @litchar{\\}, @litchar{\n},
@litchar{\r}, @litchar{\t}, and @litchar{\} followed by one to three
octal digits.
@section[#:tag "read-list"]{Reading Lists}
An @litchar{(} or @litchar{[} starts a list or pair that runs until
the matching @litchar{)} or @litchar{]}, respectively. S-expressions
between the matching pair are the elements of the list or pair. If a
delimited @litchar{.} appears where a list element is expected, then
exactly one S-expressioon must appear afterward within the matching
pair.
@section[#:tag "read-boolean"]{Reading Booleans}
A boolean is @litchar{#t}, @litchar{#f}, @litchar{#true}, or
@litchar{#false}, and it must be followed by a delimiter. Any other
sequence after @litchar{#}, other than a string or line comment, is an
error.
|