mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
* module/language/tree-il/analyze.scm (make-analyzer): Expect an int for optimization level. * module/scripts/compile.scm (%options, show-warning-help): No more -Wnone / Wall; use -W0 or -W9 instead. * module/system/base/compile.scm (level-validator): Validate small int. (compute-analyzer, add-default-optimizations): Likewise. * test-suite/tests/optargs.test (without-compiler-warnings): * test-suite/tests/tree-il.test (call-with-warnings): Parameterize level to 0, not #f. * bootstrap/Makefile.am (GUILE_WARNINGS): Use -W0, not -Wnone.
334 lines
9.8 KiB
Scheme
334 lines
9.8 KiB
Scheme
;;;; optargs.test --- test suite for optional arg processing -*- scheme -*-
|
|
;;;; Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de> --- June 2001
|
|
;;;;
|
|
;;;; Copyright (C) 2001, 2006, 2009, 2010, 2013 Free Software Foundation, Inc.
|
|
;;;;
|
|
;;;; This library is free software; you can redistribute it and/or
|
|
;;;; modify it under the terms of the GNU Lesser General Public
|
|
;;;; License as published by the Free Software Foundation; either
|
|
;;;; version 3 of the License, or (at your option) any later version.
|
|
;;;;
|
|
;;;; This library is distributed in the hope that it will be useful,
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
;;;; Lesser General Public License for more details.
|
|
;;;;
|
|
;;;; You should have received a copy of the GNU Lesser General Public
|
|
;;;; License along with this library; if not, write to the Free Software
|
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
(define-module (test-suite test-optargs)
|
|
#:use-module (test-suite lib)
|
|
#:use-module (system base compile)
|
|
#:use-module (ice-9 optargs))
|
|
|
|
(define exception:invalid-keyword
|
|
'(keyword-argument-error . "Invalid keyword"))
|
|
|
|
(define exception:unrecognized-keyword
|
|
'(keyword-argument-error . "Unrecognized keyword"))
|
|
|
|
(define exception:extraneous-arguments
|
|
;; Message depends on whether we use the interpreter or VM, and on the
|
|
;; evenness of the number of extra arguments (!).
|
|
;'(keyword-argument-error . ".*")
|
|
'(#t . ".*"))
|
|
|
|
(with-test-prefix/c&e "optional argument processing"
|
|
(pass-if "local defines work with optional arguments"
|
|
(eval '(begin
|
|
(define* (test-1 #:optional (x 0))
|
|
(define d 1) ; local define
|
|
#t)
|
|
(false-if-exception (test-1)))
|
|
(interaction-environment))))
|
|
|
|
;;;
|
|
;;; let-keywords
|
|
;;;
|
|
|
|
(define-syntax-rule (without-compiler-warnings exp ...)
|
|
(parameterize ((default-warning-level 0)) exp ...))
|
|
|
|
(without-compiler-warnings
|
|
(with-test-prefix/c&e "let-keywords"
|
|
;; in guile 1.6.4 and earlier, an empty binding list only used `begin',
|
|
;; which caused apparently internal defines to "leak" out into the
|
|
;; encompasing environment
|
|
(pass-if-exception "empty bindings internal defines leaking out"
|
|
exception:unbound-var
|
|
(let ((rest '()))
|
|
(let-keywords rest #f ()
|
|
(define localvar #f)
|
|
#f)
|
|
localvar))
|
|
|
|
(pass-if "one key"
|
|
(let-keywords '(#:foo 123) #f (foo)
|
|
(= foo 123))))
|
|
|
|
|
|
(with-test-prefix/c&e "let-keywords*"
|
|
;; in guile 1.6.4 and earlier, an empty binding list only used `begin',
|
|
;; which caused apparently internal defines to "leak" out into the
|
|
;; encompasing environment
|
|
(pass-if-exception "empty bindings internal defines leaking out"
|
|
exception:unbound-var
|
|
(let ((rest '()))
|
|
(let-keywords* rest #f ()
|
|
(define localvar #f)
|
|
#f)
|
|
localvar))
|
|
|
|
(pass-if "one key"
|
|
(let-keywords* '(#:foo 123) #f (foo)
|
|
(= foo 123))))
|
|
|
|
(with-test-prefix/c&e "let-optional"
|
|
;; in guile 1.6.4 and earlier, an empty binding list only used `begin',
|
|
;; which caused apparently internal defines to "leak" out into the
|
|
;; encompasing environment
|
|
(pass-if-exception "empty bindings internal defines leaking out"
|
|
exception:unbound-var
|
|
(let ((rest '()))
|
|
(let-optional rest ()
|
|
(define localvar #f)
|
|
#f)
|
|
localvar))
|
|
|
|
(pass-if "one var"
|
|
(let ((rest '(123)))
|
|
(let-optional rest ((foo 999))
|
|
(= foo 123)))))
|
|
|
|
(with-test-prefix/c&e "let-optional*"
|
|
;; in guile 1.6.4 and earlier, an empty binding list only used `begin',
|
|
;; which caused apparently internal defines to "leak" out into the
|
|
;; encompasing environment
|
|
(pass-if-exception "empty bindings internal defines leaking out"
|
|
exception:unbound-var
|
|
(let ((rest '()))
|
|
(let-optional* rest ()
|
|
(define localvar #f)
|
|
#f)
|
|
localvar))
|
|
|
|
(pass-if "one var"
|
|
(let ((rest '(123)))
|
|
(let-optional* rest ((foo 999))
|
|
(= foo 123))))))
|
|
|
|
(define* (foo a b #:optional c (d 1) (e c) f #:key g (h a) (i r) #:rest r)
|
|
(list a b c d e f g h i r))
|
|
|
|
;; So we could use lots more tests here, but the fact that lambda* is in
|
|
;; the compiler, and the compiler compiles itself, using the evaluator
|
|
;; (when bootstrapping) and compiled code (when doing a partial rebuild)
|
|
;; makes me a bit complacent.
|
|
(without-compiler-warnings
|
|
(with-test-prefix/c&e "define*"
|
|
(pass-if "the whole enchilada"
|
|
(equal? (foo 1 2)
|
|
'(1 2 #f 1 #f #f #f 1 () ())))
|
|
|
|
(pass-if-exception "extraneous arguments"
|
|
exception:extraneous-arguments
|
|
(let ((f (lambda* (#:key x) x)))
|
|
(f 1 2 #:x 'x)))
|
|
|
|
(pass-if-equal "unrecognized keyword" '(#:y)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(let ((f (lambda* (#:key x) x)))
|
|
(f #:y 'not-recognized)))
|
|
(lambda (key proc fmt args data)
|
|
data)))
|
|
|
|
(pass-if-equal "missing argument" '("Keyword argument has no value" #:x)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(let ((f (lambda* (#:key x) x)))
|
|
(f #:x)))
|
|
(lambda (key proc fmt args data)
|
|
(cons fmt data))))
|
|
|
|
(pass-if-equal "invalid keyword" '(not-a-keyword)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(let ((f (lambda* (#:key x) x)))
|
|
(f 'not-a-keyword 'something)))
|
|
(lambda (key proc fmt args data)
|
|
data)))
|
|
|
|
(pass-if "rest given before keywords"
|
|
;; Passing the rest argument before the keyword arguments should not
|
|
;; prevent keyword argument binding.
|
|
(let ((f (lambda* (#:key x y z #:rest r) (list x y z r))))
|
|
(equal? (f 1 2 3 #:x 'x #:z 'z)
|
|
'(x #f z (1 2 3 #:x x #:z z)))))))
|
|
|
|
(with-test-prefix "scm_c_bind_keyword_arguments"
|
|
|
|
(pass-if-equal "unrecognized keyword" '(#:y)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(open-file "/dev/null" "r" #:y 'not-recognized))
|
|
(lambda (key proc fmt args data)
|
|
data)))
|
|
|
|
(pass-if-equal "missing argument"
|
|
'("Keyword argument has no value" #:encoding)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(open-file "/dev/null" "r" #:encoding))
|
|
(lambda (key proc fmt args data)
|
|
(cons fmt data))))
|
|
|
|
(pass-if-equal "invalid keyword" '(not-a-keyword)
|
|
(catch 'keyword-argument-error
|
|
(lambda ()
|
|
(open-file "/dev/null" "r" 'not-a-keyword 'something))
|
|
(lambda (key proc fmt args data)
|
|
data))))
|
|
|
|
(with-test-prefix/c&e "lambda* inits"
|
|
(pass-if "can bind lexicals within inits"
|
|
(begin
|
|
(define qux
|
|
(lambda* (#:optional a #:key (b (or a 13) #:a))
|
|
b))
|
|
#t))
|
|
(pass-if "testing qux"
|
|
(and (equal? (qux) 13)
|
|
(equal? (qux 1) 1)
|
|
(equal? (qux #:a 2) 2)))
|
|
(pass-if "nested lambda* with optional"
|
|
(begin
|
|
(define (foo x)
|
|
(define baz x)
|
|
(define* (bar #:optional (y baz))
|
|
(or (zero? y) (bar (1- y))))
|
|
(bar))
|
|
(foo 10)))
|
|
(pass-if "nested lambda* with key"
|
|
(begin
|
|
(define (foo x)
|
|
(define baz x)
|
|
(define* (bar #:key (y baz))
|
|
(or (zero? y) (bar #:y (1- y))))
|
|
(bar))
|
|
(foo 10))))
|
|
|
|
|
|
(with-test-prefix/c&e "defmacro*"
|
|
(pass-if "definition"
|
|
(begin
|
|
(defmacro* transmogrify (a #:optional (b 10))
|
|
`(,a ,b))
|
|
#t))
|
|
|
|
(pass-if "explicit arg"
|
|
(equal? (transmogrify quote 5)
|
|
5))
|
|
|
|
(pass-if "default arg"
|
|
(equal? (transmogrify quote)
|
|
10)))
|
|
|
|
(without-compiler-warnings
|
|
(with-test-prefix/c&e "case-lambda"
|
|
(pass-if-exception "no clauses, no args" exception:wrong-num-args
|
|
((case-lambda)))
|
|
|
|
(pass-if-exception "no clauses, args" exception:wrong-num-args
|
|
((case-lambda) 1))
|
|
|
|
(pass-if "docstring"
|
|
(equal? "docstring test"
|
|
(procedure-documentation
|
|
(case-lambda
|
|
"docstring test"
|
|
(() 0)
|
|
((x) 1)))))))
|
|
|
|
(without-compiler-warnings
|
|
(with-test-prefix/c&e "case-lambda*"
|
|
(pass-if-exception "no clauses, no args" exception:wrong-num-args
|
|
((case-lambda*)))
|
|
|
|
(pass-if-exception "no clauses, args" exception:wrong-num-args
|
|
((case-lambda*) 1))
|
|
|
|
(pass-if "docstring"
|
|
(equal? "docstring test"
|
|
(procedure-documentation
|
|
(case-lambda*
|
|
"docstring test"
|
|
(() 0)
|
|
((x) 1)))))
|
|
|
|
(pass-if "unambiguous"
|
|
((case-lambda*
|
|
((a b) #t)
|
|
((a) #f))
|
|
1 2))
|
|
|
|
(pass-if "unambiguous (reversed)"
|
|
((case-lambda*
|
|
((a) #f)
|
|
((a b) #t))
|
|
1 2))
|
|
|
|
(pass-if "optionals (order disambiguates)"
|
|
((case-lambda*
|
|
((a #:optional b) #t)
|
|
((a b) #f))
|
|
1 2))
|
|
|
|
(pass-if "optionals (order disambiguates (2))"
|
|
((case-lambda*
|
|
((a b) #t)
|
|
((a #:optional b) #f))
|
|
1 2))
|
|
|
|
(pass-if "optionals (one arg)"
|
|
((case-lambda*
|
|
((a b) #f)
|
|
((a #:optional b) #t))
|
|
1))
|
|
|
|
(pass-if "optionals (one arg (2))"
|
|
((case-lambda*
|
|
((a #:optional b) #t)
|
|
((a b) #f))
|
|
1))
|
|
|
|
(pass-if "keywords without keyword"
|
|
((case-lambda*
|
|
((a #:key c) #t)
|
|
((a b) #f))
|
|
1))
|
|
|
|
(pass-if "keywords with keyword"
|
|
((case-lambda*
|
|
((a #:key c) #t)
|
|
((a b) #f))
|
|
1 #:c 2))
|
|
|
|
(pass-if "keywords (too many positionals)"
|
|
((case-lambda*
|
|
((a #:key c) #f)
|
|
((a b) #t))
|
|
1 2))
|
|
|
|
(pass-if "keywords (order disambiguates)"
|
|
((case-lambda*
|
|
((a #:key c) #t)
|
|
((a b c) #f))
|
|
1 #:c 2))
|
|
|
|
(pass-if "keywords (order disambiguates (2))"
|
|
((case-lambda*
|
|
((a b c) #t)
|
|
((a #:key c) #f))
|
|
1 #:c 2))))
|