allow #:body without #:keys
svn: r4431 original commit: 821135354b2fec54ed11054e917c150abb7a472c
This commit is contained in:
commit
eaa4136d7d
|
@ -225,7 +225,7 @@
|
||||||
[(memq k mode-keywords)
|
[(memq k mode-keywords)
|
||||||
(cond
|
(cond
|
||||||
#; ;(*)
|
#; ;(*)
|
||||||
;; don't throw an error here, it still fine if used with
|
;; don't throw an error here, it is still fine if used with
|
||||||
;; #:allow-other-keys (explicit or implicit), also below
|
;; #:allow-other-keys (explicit or implicit), also below
|
||||||
[(and (null? keys) (null? flags))
|
[(and (null? keys) (null? flags))
|
||||||
(serror k-stx "cannot use without #:key/#:flag arguments")]
|
(serror k-stx "cannot use without #:key/#:flag arguments")]
|
||||||
|
@ -420,24 +420,31 @@
|
||||||
#'(begin flag-tweaks keys-body)))))
|
#'(begin flag-tweaks keys-body)))))
|
||||||
;; ------------------------------------------------------------------------
|
;; ------------------------------------------------------------------------
|
||||||
;; more sanity tests (see commented code above -- search for "(*)")
|
;; more sanity tests (see commented code above -- search for "(*)")
|
||||||
(let ([r (or all-keys other-keys other-keys+body body rest)])
|
(when (null? keys)
|
||||||
(when (and (not allow-other-keys?) (null? keys))
|
(let ([r (or all-keys other-keys other-keys+body body rest)])
|
||||||
(when r
|
(if allow-other-keys?
|
||||||
(serror r "cannot use without #:key, #:flag, or #:allow-other-keys"))
|
;; allow-other-keys?
|
||||||
(when allow-duplicate-keys?
|
(unless r
|
||||||
(serror #f (string-append "cannot allow duplicate keys without"
|
(serror #f "cannout allow other keys ~a"
|
||||||
" #:key, #:flag, or #:allow-other-keys"))))
|
"without using them in some way"))
|
||||||
(when (and allow-other-keys? (null? keys) (not r))
|
;; (not allow-other-keys?)
|
||||||
(serror #f "cannout allow other keys without using them in some way")))
|
(begin
|
||||||
|
;; can use #:body with no keys to forbid all keywords
|
||||||
|
(when (and r (not (eq? r body)))
|
||||||
|
(serror r "cannot use without #:key, #:flag, or ~a"
|
||||||
|
"#:allow-other-keys"))
|
||||||
|
(when allow-duplicate-keys?
|
||||||
|
(serror #f "cannot allow duplicate keys without ~a"
|
||||||
|
"#:key, #:flag, or #:allow-other-keys"))))))
|
||||||
;; ------------------------------------------------------------------------
|
;; ------------------------------------------------------------------------
|
||||||
;; body generation starts here
|
;; body generation starts here
|
||||||
(cond
|
(cond
|
||||||
;; no optionals or keys (or other-keys) => plain lambda
|
;; no optionals or keys (or body or other-keys) => plain lambda
|
||||||
[(and (null? opts) (null? keys) (not allow-other-keys?))
|
[(and (null? opts) (null? keys) (not (or body allow-other-keys?)))
|
||||||
(with-syntax ([vars (append! vars (or rest '()))] [expr expr])
|
(with-syntax ([vars (append! vars (or rest '()))] [expr expr])
|
||||||
(syntax/loc stx (lambda vars expr)))]
|
(syntax/loc stx (lambda vars expr)))]
|
||||||
;; no keys => make a case-lambda for optionals
|
;; no keys => make a case-lambda for optionals
|
||||||
[(and (null? keys) (not allow-other-keys?))
|
[(and (null? keys) (not (or body allow-other-keys?)))
|
||||||
(let ([clauses (make-opt-clauses expr (or rest '()))])
|
(let ([clauses (make-opt-clauses expr (or rest '()))])
|
||||||
(with-syntax ([name name] [clauses clauses])
|
(with-syntax ([name name] [clauses clauses])
|
||||||
(syntax/loc stx (letrec ([name (case-lambda . clauses)]) name))))]
|
(syntax/loc stx (letrec ([name (case-lambda . clauses)]) name))))]
|
||||||
|
|
|
@ -313,6 +313,14 @@
|
||||||
#:x 1 #:z))
|
#:x 1 #:z))
|
||||||
(t '(#:z) <= ((lambda/kw (#:key x #:allow-anything #:body r) r) #:x 1 #:z))
|
(t '(#:z) <= ((lambda/kw (#:key x #:allow-anything #:body r) r) #:x 1 #:z))
|
||||||
|
|
||||||
|
;; #:body without #:keys forbids all keys
|
||||||
|
(let ([f1 (lambda/kw (#:body b) b)]
|
||||||
|
[f2 (lambda/kw (x #:body b) (cons x b))])
|
||||||
|
(t (f1 1 2) => '(1 2)
|
||||||
|
(f2 1 2) => '(1 2)
|
||||||
|
(f1 #:foo 1 1 2) => :rt-err:
|
||||||
|
(f2 1 #:foo 1 2) => :rt-err:))
|
||||||
|
|
||||||
;; make sure that internal definitions work
|
;; make sure that internal definitions work
|
||||||
(let ([f (lambda/kw (#:key x) (define xx x) xx)])
|
(let ([f (lambda/kw (#:key x) (define xx x) xx)])
|
||||||
(t #f <= (f)
|
(t #f <= (f)
|
||||||
|
@ -349,7 +357,7 @@
|
||||||
:st-err: <= (lambda/kw (x #:rest r1 #:rest r2) 1)
|
:st-err: <= (lambda/kw (x #:rest r1 #:rest r2) 1)
|
||||||
:st-err: <= (lambda/kw (x #:rest) 1)
|
:st-err: <= (lambda/kw (x #:rest) 1)
|
||||||
:st-err: <= (lambda/kw (x #:rest r1 r2) 1)
|
:st-err: <= (lambda/kw (x #:rest r1 r2) 1)
|
||||||
:st-err: <= (lambda/kw (x #:body b) 1)
|
;; :st-err: <= (lambda/kw (x #:body b) 1) ; valid!
|
||||||
:st-err: <= (lambda/kw (x x) 1)
|
:st-err: <= (lambda/kw (x x) 1)
|
||||||
:st-err: <= (lambda/kw (x #:optional [x 1]) 1)
|
:st-err: <= (lambda/kw (x #:optional [x 1]) 1)
|
||||||
:st-err: <= (lambda/kw (x #:key [x 1]) 1)
|
:st-err: <= (lambda/kw (x #:key [x 1]) 1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user