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

View File

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

View File

@ -298,6 +298,19 @@
#f)
(let-values
(((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
(((l2) (qq l level)))
(if (eq? l l2)

View File

@ -14,6 +14,8 @@
scheme/splicing))
@(define cvt (schemefont "CVT"))
@(define unquote-id (scheme unquote))
@(define unquote-splicing-id (scheme unquote-splicing))
@title[#:tag "syntax" #:style 'toc]{Syntactic Forms}
@ -1862,33 +1864,33 @@ expression).
@defform[(quasiquote datum)]{
The same as @scheme[(quote datum)] if @scheme[datum] does not include
@scheme[(unquote _expr)] or @scheme[(unquote-splicing _expr)]. An
@scheme[(unquote _expr)] expression escapes from the quote, however,
@scheme[(#,unquote-id _expr)] or @scheme[(#,unquote-splicing-id _expr)]. An
@scheme[(#,unquote-id _expr)] form escapes from the quote, however,
and the result of the @scheme[_expr] takes the place of the
@scheme[(unquote _expr)] form in the @scheme[quasiquote] result. An
@scheme[(unquote-splicing _expr)] similarly escapes, but the
@scheme[(#,unquote-id _expr)] form in the @scheme[quasiquote] result. An
@scheme[(#,unquote-splicing-id _expr)] similarly escapes, but the
@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
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
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
@scheme[append] accepts a non-list final argument). In a quoted
@tech{hash table}, an @scheme[(unquote _expr)] or
@scheme[(unquote-splicing _expr)] expression escapes only in the
@tech{hash table}, an @scheme[(#,unquote-id _expr)] or
@scheme[(#,unquote-splicing-id _expr)] expression escapes only in the
second element of an entry pair (i.e., the value), while entry keys
are always implicitly quoted. If @scheme[unquote] or
@scheme[unquote-splicing] appears within @scheme[quasiquote] in any
other way than as @scheme[(unquote _expr)] or
@scheme[(unquote-splicing _expr)], a syntax error is reported.
other way than as @scheme[(#,unquote-id _expr)] or
@scheme[(#,unquote-splicing-id _expr)], a syntax error is reported.
@mz-examples[
(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 (#,(scheme unquote-splicing) (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 (#,(scheme unquote-splicing) 1))) `(0 ,@1))
(eval:alts (#,(scheme quasiquote) (0 (#,unquote-id (+ 1 2)) 4)) `(0 ,(+ 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 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4))
(eval:alts (#,(scheme quasiquote) (0 (#,unquote-splicing-id 1))) `(0 ,@1))
]
A @scheme[quasiquote], @scheme[unquote], or @scheme[unquote-splicing]