extend {read,peek}-char-or-special
Support an external implementation of `read-syntax` by exposing functionality that is currently internal to `read-syntax`: a srcloc argument to a "special"-producing port function and wrapping special results to reliably distinguish them from characters.
This commit is contained in:
parent
74909ff06b
commit
08ca76b741
|
@ -12,7 +12,7 @@
|
|||
|
||||
(define collection 'multi)
|
||||
|
||||
(define version "6.8.0.1")
|
||||
(define version "6.8.0.2")
|
||||
|
||||
(define deps `("racket-lib"
|
||||
["racket" #:version ,version]))
|
||||
|
|
|
@ -381,17 +381,20 @@ The arguments implement the port as follows:
|
|||
|
||||
@itemize[
|
||||
|
||||
@item{When the special read is triggered by @racket[read-syntax]
|
||||
or @racket[read-syntax/recursive], the
|
||||
@item{When the special read is triggered by @racket[read-syntax],
|
||||
@racket[read-syntax/recursive] the
|
||||
procedure is passed four arguments that represent a source
|
||||
location.}
|
||||
location. Four arguments for a source location are also provided when
|
||||
the read is triggered by @racket[read-byte-or-special],
|
||||
@racket[read-char-or-special], @racket[peek-byte-or-special], or
|
||||
@racket[peek-char-or-special] with a non-@racket[#f] source name.}
|
||||
|
||||
@item{When the special read is triggered by @racket[read],
|
||||
@racket[read-byte-or-special],
|
||||
@racket[read-char-or-special], @racket[peek-byte-or-special], or
|
||||
@racket[peek-char-or-special], the procedure is passed no arguments
|
||||
if it accepts zero arguments, otherwise it is passed four arguments
|
||||
that are all @racket[#f].}
|
||||
@racket[read/recursive], or other calls to
|
||||
@racket[read-byte-or-special], @racket[read-char-or-special],
|
||||
@racket[peek-byte-or-special], or @racket[peek-char-or-special], the
|
||||
procedure is passed no arguments if it accepts zero arguments,
|
||||
otherwise it is passed four arguments that are all @racket[#f].}
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -366,19 +366,32 @@ with @racket[skip-bytes-amt] and @racket[progress] arguments like
|
|||
@racket[peek-bytes-avail!].}
|
||||
|
||||
|
||||
@defproc[(read-char-or-special [in input-port? (current-input-port)])
|
||||
@defproc[(read-char-or-special [in input-port? (current-input-port)]
|
||||
[source-name any/c #f]
|
||||
[special-wrap (or/c (any/c -> any/c) #f) #f])
|
||||
(or/c char? eof-object? any/c)]{
|
||||
|
||||
Like @racket[read-char], but if the input port returns a @tech{special}
|
||||
value (through a value-generating procedure in a custom port; see
|
||||
@secref["customport"] and @secref["special-comments"] for
|
||||
details), then the @tech{special} value is returned.}
|
||||
Like @racket[read-char], but if the input port returns a
|
||||
@tech{special} value (through a value-generating procedure in a custom
|
||||
port, where @racket[source-name] is provided to the procedure; see
|
||||
@secref["customport"] and @secref["special-comments"] for details),
|
||||
then the result of applying @racket[special-wrap] to the
|
||||
@tech{special} value is returned. A @racket[#f] value for
|
||||
@racket[special-wrap] is treated the same as the identity function.
|
||||
|
||||
@defproc[(read-byte-or-special [in input-port? (current-input-port)])
|
||||
@history[#:changed "6.8.0.2" @elem{Added the @racket[sourve-name] and
|
||||
@racket[special-wrap] arguments.}]}
|
||||
|
||||
@defproc[(read-byte-or-special [in input-port? (current-input-port)]
|
||||
[source-name any/c #f]
|
||||
[special-wrap (or/c (any/c -> any/c) #f) #f])
|
||||
(or/c byte? eof-object? any/c)]{
|
||||
|
||||
Like @racket[read-char-or-special], but reads and returns a byte
|
||||
instead of a character.}
|
||||
instead of a character.
|
||||
|
||||
@history[#:changed "6.8.0.2" @elem{Added the @racket[sourve-name] and
|
||||
@racket[special-wrap] arguments.}]}
|
||||
|
||||
@defproc[(peek-char [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt exact-nonnegative-integer? 0])
|
||||
|
@ -396,20 +409,30 @@ Like @racket[peek-char], but @tech{peeks} and returns a byte instead of a
|
|||
character.}
|
||||
|
||||
@defproc[(peek-char-or-special [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt exact-nonnegative-integer? 0])
|
||||
[skip-bytes-amt exact-nonnegative-integer? 0]
|
||||
[source-name any/c #f]
|
||||
[special-wrap (or/c (any/c -> any/c) #f) #f])
|
||||
(or/c char? eof-object? any/c)]{
|
||||
|
||||
Like @racket[peek-char], but if the input port returns a non-byte
|
||||
value after @racket[skip-bytes-amt] byte positions, then it is returned.}
|
||||
value after @racket[skip-bytes-amt] byte positions, then it is returned.
|
||||
|
||||
@history[#:changed "6.8.0.2" @elem{Added the @racket[sourve-name] and
|
||||
@racket[special-wrap] arguments.}]}
|
||||
|
||||
@defproc[(peek-byte-or-special [in input-port? (current-input-port)]
|
||||
[skip-bytes-amt exact-nonnegative-integer? 0]
|
||||
[progress (or/c progress-evt? #f) #f])
|
||||
[progress (or/c progress-evt? #f) #f]
|
||||
[source-name any/c #f]
|
||||
[special-wrap (or/c (any/c -> any/c) #f) #f])
|
||||
(or/c byte? eof-object? any/c)]{
|
||||
|
||||
Like @racket[peek-char-or-special], but @tech{peeks} and returns a byte
|
||||
instead of a character, and it supports a @racket[progress] argument
|
||||
like @racket[peek-bytes-avail!].}
|
||||
like @racket[peek-bytes-avail!].
|
||||
|
||||
@history[#:changed "6.8.0.2" @elem{Added the @racket[sourve-name] and
|
||||
@racket[special-wrap] arguments.}]}
|
||||
|
||||
|
||||
@defproc[(port-progress-evt [in (and/c input-port? port-provides-progress-evts?)
|
||||
|
|
|
@ -37,10 +37,10 @@
|
|||
(err/rt-test (current-error-port (current-input-port)))
|
||||
(test #\; peek-char this-file)
|
||||
(arity-test peek-char 0 2)
|
||||
(arity-test peek-char-or-special 0 2)
|
||||
(arity-test peek-char-or-special 0 4)
|
||||
(test #\; read-char this-file)
|
||||
(arity-test read-char 0 1)
|
||||
(arity-test read-char-or-special 0 1)
|
||||
(arity-test read-char-or-special 0 3)
|
||||
(test '(define cur-section '()) read this-file)
|
||||
(arity-test read 0 1)
|
||||
(test #\( peek-char this-file)
|
||||
|
|
|
@ -275,9 +275,9 @@ scheme_init_port_fun(Scheme_Env *env)
|
|||
GLOBAL_NONCM_PRIM("read-syntax/recursive", read_syntax_recur_f, 0, 5, env);
|
||||
GLOBAL_PRIM_W_ARITY2("read-language", read_language, 0, 2, 0, -1, env);
|
||||
GLOBAL_NONCM_PRIM("read-char", read_char, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("read-char-or-special", read_char_spec, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("read-char-or-special", read_char_spec, 0, 3, env);
|
||||
GLOBAL_NONCM_PRIM("read-byte", read_byte, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("read-byte-or-special", read_byte_spec, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("read-byte-or-special", read_byte_spec, 0, 3, env);
|
||||
GLOBAL_NONCM_PRIM("read-bytes-line", read_byte_line, 0, 2, env);
|
||||
GLOBAL_NONCM_PRIM("read-line", read_line, 0, 2, env);
|
||||
GLOBAL_NONCM_PRIM("read-string", sch_read_string, 1, 2, env);
|
||||
|
@ -305,9 +305,9 @@ scheme_init_port_fun(Scheme_Env *env)
|
|||
GLOBAL_NONCM_PRIM("write-special", scheme_write_special, 1, 2, env);
|
||||
GLOBAL_NONCM_PRIM("write-special-avail*", scheme_write_special_nonblock, 1, 2, env);
|
||||
GLOBAL_NONCM_PRIM("peek-char", peek_char, 0, 2, env);
|
||||
GLOBAL_NONCM_PRIM("peek-char-or-special", peek_char_spec, 0, 2, env);
|
||||
GLOBAL_NONCM_PRIM("peek-char-or-special", peek_char_spec, 0, 4, env);
|
||||
GLOBAL_NONCM_PRIM("peek-byte", peek_byte, 0, 2, env);
|
||||
GLOBAL_NONCM_PRIM("peek-byte-or-special", peek_byte_spec, 0, 3, env);
|
||||
GLOBAL_NONCM_PRIM("peek-byte-or-special", peek_byte_spec, 0, 5, env);
|
||||
GLOBAL_NONCM_PRIM("byte-ready?", byte_ready_p, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("char-ready?", char_ready_p, 0, 1, env);
|
||||
GLOBAL_NONCM_PRIM("newline", newline, 0, 1, env);
|
||||
|
@ -3038,7 +3038,8 @@ static Scheme_Object *
|
|||
do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, int is_byte)
|
||||
{
|
||||
Scheme_Object *port;
|
||||
int ch;
|
||||
Scheme_Object *skip, *unless_evt, *src, *spec_wrap;
|
||||
int ch, pos;
|
||||
|
||||
if (argc && !SCHEME_INPUT_PORTP(argv[0]))
|
||||
scheme_wrong_contract(name, "input-port?", 0, argc, argv);
|
||||
|
@ -3049,8 +3050,7 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in
|
|||
port = CURRENT_INPUT_PORT(scheme_current_config());
|
||||
|
||||
if (peek) {
|
||||
Scheme_Object *skip, *unless_evt = NULL;
|
||||
|
||||
unless_evt = NULL;
|
||||
if (argc > 1) {
|
||||
skip = argv[1];
|
||||
if (!(SCHEME_INTP(skip) && (SCHEME_INT_VAL(skip) >= 0))
|
||||
|
@ -3058,7 +3058,7 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in
|
|||
scheme_wrong_contract(name, "exact-nonnegative-integer?", 1, argc, argv);
|
||||
return NULL;
|
||||
}
|
||||
if (argc > 2) {
|
||||
if (is_byte && (argc > 2)) {
|
||||
if (SCHEME_TRUEP(argv[2])) {
|
||||
unless_evt = argv[2];
|
||||
if (!SAME_TYPE(SCHEME_TYPE(unless_evt), scheme_progress_evt_type)) {
|
||||
|
@ -3077,7 +3077,31 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in
|
|||
}
|
||||
} else
|
||||
skip = NULL;
|
||||
} else {
|
||||
unless_evt = NULL;
|
||||
skip = NULL;
|
||||
}
|
||||
|
||||
pos = (peek ? (is_byte ? 3 : 2) : 1);
|
||||
if (argc > pos) {
|
||||
spec_wrap = argv[pos];
|
||||
if (SCHEME_FALSEP(spec_wrap))
|
||||
spec_wrap = NULL;
|
||||
else
|
||||
scheme_check_proc_arity2(name, 1, pos, argc, argv, 1);
|
||||
pos++;
|
||||
if (argc > pos) {
|
||||
src = argv[pos++];
|
||||
if (SCHEME_FALSEP(src))
|
||||
src = NULL;
|
||||
} else
|
||||
src = NULL;
|
||||
} else {
|
||||
src = NULL;
|
||||
spec_wrap = NULL;
|
||||
}
|
||||
|
||||
if (peek) {
|
||||
if (spec) {
|
||||
if (is_byte) {
|
||||
ch = scheme_peek_byte_special_ok_skip(port, skip, unless_evt);
|
||||
|
@ -3104,7 +3128,13 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in
|
|||
}
|
||||
|
||||
if (ch == SCHEME_SPECIAL) {
|
||||
return scheme_get_ready_special(port, NULL, peek);
|
||||
src = scheme_get_ready_special(port, src, peek);
|
||||
if (spec_wrap) {
|
||||
Scheme_Object *a[1];
|
||||
a[0] = src;
|
||||
return _scheme_tail_apply(spec_wrap, 1, a);
|
||||
} else
|
||||
return src;
|
||||
} else if (ch == EOF)
|
||||
return scheme_eof;
|
||||
else if (is_byte)
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
consistently.)
|
||||
*/
|
||||
|
||||
#define MZSCHEME_VERSION "6.8.0.1"
|
||||
#define MZSCHEME_VERSION "6.8.0.2"
|
||||
|
||||
#define MZSCHEME_VERSION_X 6
|
||||
#define MZSCHEME_VERSION_Y 8
|
||||
#define MZSCHEME_VERSION_Z 0
|
||||
#define MZSCHEME_VERSION_W 1
|
||||
#define MZSCHEME_VERSION_W 2
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||
|
|
Loading…
Reference in New Issue
Block a user