fix printer for (unquote @d)

Avoid printing `(unquote @d)` or `(unsyntax @d)` as `,@d` or `#,@d`,
which would mean `(unquote-splicing @d)` or `(unsyntax-splicing @d)`
to the reader, by adding an extra space before the `@`.
This commit is contained in:
Matthew Flatt 2017-06-22 13:33:51 -06:00
parent 4bbe7a241d
commit 3c07250db4
4 changed files with 46 additions and 2 deletions

View File

@ -199,7 +199,10 @@ or @litchar["#,@"], respectively. After the reader syntax, the second
element of the list is printed. When the list is a tail of an
enclosing list, the tail is printed after a @litchar{.} in the
enclosing list (after which the reader abbreviations work), instead of
including the tail as two elements of the enclosing list.
including the tail as two elements of the enclosing list. If the
reader syntax @litchar{,} or @litchar{#,} is followed by a symbol
that prints with a leading @litchar["@"], then the printer adds an
extra space before the @litchar["@"].
The printed form of a pair is the same in both @racket[write] and
@racket[display] modes, except as the printed form of the pair's
@ -251,6 +254,10 @@ always @tech{quotable}, a pair is @tech{quotable} when its
@racket[car] and @racket[cdr] are @tech{quotable}, and a mutable list
is never @tech{quotable}.
@history[#:changed "6.9.0.6" @elem{Added a space when printing @litchar{,}
or @litchar{#,} followed by a symbol
that prints with a leading @litchar["@"].}]
@section[#:tag "print-string"]{Printing Strings}
All @tech{strings} @racket[display] as their literal character sequences.

View File

@ -193,6 +193,10 @@
(ptest "'`a" '`a)
(ptest "'`,#,#`a" '`,#,#`a)
(ptest "'`,#,#`,@#,@a" '`,#,#`,@#,@a)
(ptest "'`,#,#`,@, @a" '`,#,#`,@, @a)
(ptest "'`,#,#`,@#, @a" '`,#,#`,@#, @a)
(ptest "'`,#,#`,@,|@a,|" '`,#,#`,@,|@a,|)
(ptest "'`,#,#`,@#,|@a,|" '`,#,#`,@#,|@a,|)
(ptest "(fxvector 1 10000 3)" (fxvector 1 10000 3))
(ptest "(flvector 1.1 10000.1 3.1 0.0)" (flvector 1.1 10000.1 3.1 0.0))

View File

@ -763,7 +763,21 @@
(equal? open "("))
(begin
(out (read-macro-prefix expr car))
(wr (read-macro-body expr car cdr) depth qd))
;; Special case: "," or "#," followed by a symbol that might start "@"
(cond
[(and (or (eq? (car expr) 'unquote)
(eq? (car expr) 'unsyntax))
(symbol? (cadr expr)))
(define s (if display?
(symbol->string (cadr expr))
(format "~s" (cadr expr))))
(when (and (positive? (string-length s))
(eqv? #\@ (string-ref s 0)))
;; Avoid ambiguity by adding a space
(out " "))
(out s)]
[else
(wr (read-macro-body expr car cdr) depth qd)]))
(wr-lst expr #t depth pair? car cdr open close qd)))
(define (wr-lst l check? depth pair? car cdr open close qd)

View File

@ -3908,6 +3908,25 @@ print_pair(Scheme_Object *pair, int notdisplay, int compact,
&& !first_unquoted
&& is_special_reader_form(pp, notdisplay, pair)) {
print_special_reader_form(SCHEME_CAR(pair), pp, notdisplay);
/* Corner case: if we just printed "#," or ",", make sure we don't
next print a symbol that starts "@". For example, ","
followed by the symbol whose string is "@d" should not print
as ",@d". */
if ((SAME_OBJ(SCHEME_CAR(pair), unquote_symbol)
|| SAME_OBJ(SCHEME_CAR(pair), unsyntax_symbol))
&& (SCHEME_SYMBOLP(SCHEME_CADR(pair))
&& (SCHEME_SYM_VAL(SCHEME_CADR(pair))[0] == '@'))) {
/* Double-check that `@` will be the next character: */
const char *sv;
sv = scheme_symbol_name_and_size(SCHEME_CADR(pair), NULL,
((pp->can_read_pipe_quote
? SCHEME_SNF_PIPE_QUOTE
: SCHEME_SNF_NO_PIPE_QUOTE)));
if (sv[0] == '@') {
/* Avoid ambiguity: */
print_utf8_string(pp, " ", 0, 1);
}
}
(void)print(SCHEME_CADR(pair), notdisplay, compact, ht, mt, pp);
return;
} else if ((notdisplay == 3) && !first_unquoted) {