qq fixes, so that (quasiquote #(unquote lst)) is a syntax error

svn: r13517
This commit is contained in:
Matthew Flatt 2009-02-11 15:01:04 +00:00
parent cbe2f3c347
commit 7b11c290f5
4 changed files with 40 additions and 19 deletions

View File

@ -199,7 +199,7 @@
[unquote [unquote
(zero? depth) (zero? depth)
(raise-syntax-error (raise-syntax-error
#f 'unquote
"invalid context within quasiquote" "invalid context within quasiquote"
stx stx
form)] form)]
@ -212,7 +212,7 @@
[unquote-splicing [unquote-splicing
(zero? depth) (zero? depth)
(raise-syntax-error (raise-syntax-error
#f 'unquote-splicing
"invalid context within quasiquote" "invalid context within quasiquote"
stx stx
form)] form)]
@ -220,6 +220,12 @@
#`(mcons 'quasiquote #,(loop #'e (add1 depth)))] #`(mcons 'quasiquote #,(loop #'e (add1 depth)))]
[(a . b) [(a . b)
#`(mcons #,(loop #'a depth) #,(loop #'b depth))] #`(mcons #,(loop #'a depth) #,(loop #'b depth))]
[#(unquote a ...)
(raise-syntax-error
'unquote
"invalid context within quasiquote"
stx
form)]
[#(a ...) [#(a ...)
#`(mlist->vector #,(loop (syntax->list #'(a ...)) depth))] #`(mlist->vector #,(loop (syntax->list #'(a ...)) depth))]
[other #'(r5rs:quote other)])) [other #'(r5rs:quote other)]))

View File

@ -512,8 +512,8 @@ several known ways:
(pair? #f "r6rs-Z-H-14.html" "node_idx_608") (pair? #f "r6rs-Z-H-14.html" "node_idx_608")
(positive? #f "r6rs-Z-H-14.html" "node_idx_476") (positive? #f "r6rs-Z-H-14.html" "node_idx_476")
(procedure? #f "r6rs-Z-H-14.html" "node_idx_342") (procedure? #f "r6rs-Z-H-14.html" "node_idx_342")
(quasiquote #f "r6rs-Z-H-14.html" "node_idx_768") (quasiquote #t "r6rs-Z-H-14.html" "node_idx_768")
(quote #f "r6rs-Z-H-14.html" "node_idx_362") (quote #t "r6rs-Z-H-14.html" "node_idx_362")
(rational-valued? #f "r6rs-Z-H-14.html" "node_idx_452") (rational-valued? #f "r6rs-Z-H-14.html" "node_idx_452")
(rational? #f "r6rs-Z-H-14.html" "node_idx_446") (rational? #f "r6rs-Z-H-14.html" "node_idx_446")
(rationalize #f "r6rs-Z-H-14.html" "node_idx_536") (rationalize #f "r6rs-Z-H-14.html" "node_idx_536")
@ -546,8 +546,8 @@ several known ways:
(symbol? #f "r6rs-Z-H-14.html" "node_idx_646") (symbol? #f "r6rs-Z-H-14.html" "node_idx_646")
(tan #f "r6rs-Z-H-14.html" "node_idx_550") (tan #f "r6rs-Z-H-14.html" "node_idx_550")
(truncate #f "r6rs-Z-H-14.html" "node_idx_532") (truncate #f "r6rs-Z-H-14.html" "node_idx_532")
(unquote #f "r6rs-Z-H-14.html" "node_idx_770") (unquote #t "r6rs-Z-H-14.html" "node_idx_770")
(unquote-splicing #f "r6rs-Z-H-14.html" "node_idx_772") (unquote-splicing #t "r6rs-Z-H-14.html" "node_idx_772")
(values #f "r6rs-Z-H-14.html" "node_idx_760") (values #f "r6rs-Z-H-14.html" "node_idx_760")
(vector #f "r6rs-Z-H-14.html" "node_idx_728") (vector #f "r6rs-Z-H-14.html" "node_idx_728")
(vector->list #f "r6rs-Z-H-14.html" "node_idx_736") (vector->list #f "r6rs-Z-H-14.html" "node_idx_736")

View File

@ -298,6 +298,19 @@
#f) #f)
(let-values (let-values
(((l) (vector->list (syntax-e x)))) (((l) (vector->list (syntax-e x))))
;; special case: disallow #(unquote <e>)
(if (stx-pair? l)
(let-values ([(first) (stx-car l)])
(if (identifier? first)
(if (free-identifier=? first unquote-stx)
(raise-syntax-error
'unquote
"invalid context within quasiquote"
in-form
first)
(void))
(void)))
(void))
(let-values (let-values
(((l2) (qq l level))) (((l2) (qq l level)))
(if (eq? l l2) (if (eq? l l2)

View File

@ -14,6 +14,8 @@
scheme/splicing)) scheme/splicing))
@(define cvt (schemefont "CVT")) @(define cvt (schemefont "CVT"))
@(define unquote-id (scheme unquote))
@(define unquote-splicing-id (scheme unquote-splicing))
@title[#:tag "syntax" #:style 'toc]{Syntactic Forms} @title[#:tag "syntax" #:style 'toc]{Syntactic Forms}
@ -1862,33 +1864,33 @@ expression).
@defform[(quasiquote datum)]{ @defform[(quasiquote datum)]{
The same as @scheme[(quote datum)] if @scheme[datum] does not include The same as @scheme[(quote datum)] if @scheme[datum] does not include
@scheme[(unquote _expr)] or @scheme[(unquote-splicing _expr)]. An @scheme[(#,unquote-id _expr)] or @scheme[(#,unquote-splicing-id _expr)]. An
@scheme[(unquote _expr)] expression escapes from the quote, however, @scheme[(#,unquote-id _expr)] form escapes from the quote, however,
and the result of the @scheme[_expr] takes the place of the and the result of the @scheme[_expr] takes the place of the
@scheme[(unquote _expr)] form in the @scheme[quasiquote] result. An @scheme[(#,unquote-id _expr)] form in the @scheme[quasiquote] result. An
@scheme[(unquote-splicing _expr)] similarly escapes, but the @scheme[(#,unquote-splicing-id _expr)] similarly escapes, but the
@scheme[_expr] must produce a list, and its elements are spliced as @scheme[_expr] must produce a list, and its elements are spliced as
multiple values place of the @scheme[(unquote-splicing _expr)], which multiple values place of the @scheme[(#,unquote-splicing-id _expr)], which
must appear as the @scheme[car] or a quoted pair, as an element of a must appear as the @scheme[car] or a quoted pair, as an element of a
quoted vector, or as an element of a quoted @tech{prefab} structure; quoted vector, or as an element of a quoted @tech{prefab} structure;
in the case of a pair, if the @scheme[cdr] of the relevant quoted pair in the case of a pair, if the @scheme[cdr] of the relevant quoted pair
is empty, then @scheme[_expr] need not produce a list, and its result is empty, then @scheme[_expr] need not produce a list, and its result
is used directly in place of the quoted pair (in the same way that is used directly in place of the quoted pair (in the same way that
@scheme[append] accepts a non-list final argument). In a quoted @scheme[append] accepts a non-list final argument). In a quoted
@tech{hash table}, an @scheme[(unquote _expr)] or @tech{hash table}, an @scheme[(#,unquote-id _expr)] or
@scheme[(unquote-splicing _expr)] expression escapes only in the @scheme[(#,unquote-splicing-id _expr)] expression escapes only in the
second element of an entry pair (i.e., the value), while entry keys second element of an entry pair (i.e., the value), while entry keys
are always implicitly quoted. If @scheme[unquote] or are always implicitly quoted. If @scheme[unquote] or
@scheme[unquote-splicing] appears within @scheme[quasiquote] in any @scheme[unquote-splicing] appears within @scheme[quasiquote] in any
other way than as @scheme[(unquote _expr)] or other way than as @scheme[(#,unquote-id _expr)] or
@scheme[(unquote-splicing _expr)], a syntax error is reported. @scheme[(#,unquote-splicing-id _expr)], a syntax error is reported.
@mz-examples[ @mz-examples[
(eval:alts (#,(scheme quasiquote) (0 1 2)) `(0 1 2)) (eval:alts (#,(scheme quasiquote) (0 1 2)) `(0 1 2))
(eval:alts (#,(scheme quasiquote) (0 (#,(scheme unquote) (+ 1 2)) 4)) `(0 ,(+ 1 2) 4)) (eval:alts (#,(scheme quasiquote) (0 (#,unquote-id (+ 1 2)) 4)) `(0 ,(+ 1 2) 4))
(eval:alts (#,(scheme quasiquote) (0 (#,(scheme unquote-splicing) (list 1 2)) 4)) `(0 ,@(list 1 2) 4)) (eval:alts (#,(scheme quasiquote) (0 (#,unquote-splicing-id (list 1 2)) 4)) `(0 ,@(list 1 2) 4))
(eval:alts (#,(scheme quasiquote) (0 (#,(scheme unquote-splicing) 1) 4)) `(0 ,@1 4)) (eval:alts (#,(scheme quasiquote) (0 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4))
(eval:alts (#,(scheme quasiquote) (0 (#,(scheme unquote-splicing) 1))) `(0 ,@1)) (eval:alts (#,(scheme quasiquote) (0 (#,unquote-splicing-id 1))) `(0 ,@1))
] ]
A @scheme[quasiquote], @scheme[unquote], or @scheme[unquote-splicing] A @scheme[quasiquote], @scheme[unquote], or @scheme[unquote-splicing]