1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; The software is in the public domain and is provided with
5 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
8 (defpackage :sb-cltl2-tests
9 (:use
:sb-cltl2
:cl
:sb-rt
:sb-ext
:sb-kernel
:sb-int
))
11 (in-package :sb-cltl2-tests
)
15 (defmacro *x
*-value
()
16 (declare (special *x
*))
19 (deftest compiler-let
.1
21 (compiler-let ((*x
* :inner
))
22 (list *x
* (*x
*-value
))))
25 (defvar *expansions
* nil
)
26 (defmacro macroexpand-macro
(arg)
27 (push arg
*expansions
*)
30 (deftest macroexpand-all
.1
32 (macroexpand-all '(defmethod foo ((x fixnum
)) (1+ x
)))
36 (deftest macroexpand-all
.2
37 (let ((*expansions
* nil
))
38 (macroexpand-all '(list (macroexpand-macro 1)
39 (let (macroexpand-macro :no
)
40 (macroexpand-macro 2))))
41 (remove-duplicates (sort *expansions
* #'<)))
44 (deftest macroexpand-all
.3
45 (let ((*expansions
* nil
))
46 (compile nil
'(lambda ()
47 (macrolet ((foo (key &environment env
)
48 (macroexpand-all `(bar ,key
) env
)))
51 (push key
*expansions
*)
54 (remove-duplicates *expansions
*))
58 (multiple-value-bind (expansion macro-p
)
59 (macroexpand 'srlt env
)
60 (when macro-p
(eval expansion
))))
61 (defmacro testr
(&environment env
)
62 `',(getf (smv env
) nil
))
64 (deftest macroexpand-all
.4
65 (macroexpand-all '(symbol-macrolet ((srlt '(nil zool
))) (testr)))
66 (symbol-macrolet ((srlt '(nil zool
))) 'zool
))
69 (deftest macroexpand-all
.5
70 ;; The second use of (W) is expanded to X, the first is untouched.
71 ;; Use EQUALP explicitly because the RT tester's EQUALP-WITH-CASE
72 ;; is not quite EQUALP with regard to structures.
73 (equalp (macroexpand-all '(macrolet ((w () 'x
))
74 `(let ((y `(z ,(w) ,,(w)))) (g))))
75 '(macrolet ((w () 'x
)) `(let ((y `(z ,(w) ,,x
))) (g))))
78 (deftest macroexpand-all
.6
79 ;; The subform (AND Z) in (PROGN `(F ,(WHEN X Y) . `(,B ,,(AND Z))))
80 ;; is evaluable though unlikely to appear in real code. Unless F is a
81 ;; macro, this form when evaluated does not comprise a well-formed sexpr.
82 (equalp (macroexpand-all '(progn `(f ,(when x y
) .
`(,b
,,(and z
)))))
83 '(progn `(f ,(if x
(progn y
) nil
) .
`(,b
,,(the t z
)))))
87 (define-symbol-macro global-symbol-macro xxx
)
89 (deftest macroexpand-all
.7
90 (equalp (macroexpand-all 'global-symbol-macro
) 'xxx
)
92 (deftest macroexpand-all
.8
93 (symbol-macrolet ((global-symbol-macro yyy
))
94 (macrolet ((frob (&environment env form
)
95 `',(macroexpand-all form env
)))
96 (equalp (frob global-symbol-macro
) 'yyy
)))
98 (deftest macroexpand-all
.9
99 (let ((global-symbol-macro 3))
100 (macrolet ((frob (&environment env form
)
101 `',(macroexpand-all form env
)))
102 (equalp (frob global-symbol-macro
) 'global-symbol-macro
)))
104 (deftest macroexpand-all
.10
105 (macrolet ((frob (&environment env form
)
106 `',(macroexpand-all form env
)))
107 (equalp (frob (let ((anything 1)) global-symbol-macro
))
108 '(let ((anything 1)) xxx
)))
110 (deftest macroexpand-all
.11
111 (macrolet ((frob (&environment env form
)
112 `',(macroexpand-all form env
)))
113 (equalp (frob (let ((global-symbol-macro global-symbol-macro
))
114 global-symbol-macro
))
115 '(let ((global-symbol-macro xxx
)) global-symbol-macro
)))
117 (deftest macroexpand-all
.12
118 (macrolet ((frob (&environment env form
)
119 `',(macroexpand-all form env
)))
120 (equalp (frob (symbol-macrolet ((global-symbol-macro 3))
121 global-symbol-macro
))
122 '(symbol-macrolet ((global-symbol-macro 3)) 3)))
124 (deftest macroexpand-all
.13
125 (symbol-macrolet ((x y
))
126 (macrolet ((frob (&environment env form
)
127 `',(macroexpand-all form env
)))
128 (equalp (frob (+ x x
))
131 ;;;; DECLARATION-INFORMATION
133 (defmacro dinfo
(thing &environment env
)
134 `',(declaration-information thing env
))
137 `(macrolet ((frob (suffix answer
&optional declaration
)
138 `(deftest ,(intern (concatenate 'string
139 "DECLARATION-INFORMATION."
142 (locally (declare ,@(when declaration
144 (cadr (assoc ',',x
(dinfo optimize
))))
147 (frob ".0" 0 (optimize (,x
0)))
148 (frob ".1" 1 (optimize (,x
1)))
149 (frob ".2" 2 (optimize (,x
2)))
150 (frob ".3" 3 (optimize (,x
3)))
151 (frob ".IMPLICIT" 3 (optimize ,x
)))))
155 (def compilation-speed
)
159 (deftest declaration-information.restrict-compiler-policy
.1
160 (with-compilation-unit (:policy
'(optimize) :override t
)
161 (restrict-compiler-policy 'speed
3)
162 (eval '(cadr (assoc 'speed
(dinfo optimize
)))))
165 (deftest declaration-information.restrict-compiler-policy
.2
166 (with-compilation-unit (:policy
'(optimize) :override t
)
167 (restrict-compiler-policy 'speed
3)
168 (locally (declare (optimize (speed 2)))
169 (cadr (assoc 'speed
(dinfo optimize
)))))
172 (deftest declaration-information.restrict-compiler-policy
.3
173 (locally (declare (optimize (speed 2)))
174 (with-compilation-unit (:policy
'(optimize) :override t
)
175 (restrict-compiler-policy 'speed
3)
176 (cadr (assoc 'speed
(dinfo optimize
)))))
179 (deftest declaration-information.muffle-conditions.default
180 (dinfo sb-ext
:muffle-conditions
)
182 (deftest declaration-information.muffle-conditions
.1
183 (locally (declare (sb-ext:muffle-conditions warning
))
184 (dinfo sb-ext
:muffle-conditions
))
186 (deftest declaration-information.muffle-conditions
.2
187 (let ((junk (dinfo sb-ext
:muffle-conditions
)))
188 (declare (sb-ext:muffle-conditions warning
))
189 (locally (declare (sb-ext:unmuffle-conditions style-warning
))
190 (let ((dinfo (dinfo sb-ext
:muffle-conditions
)))
193 (and (subtypep dinfo
`(or (and warning
(not style-warning
))
194 (and ,junk
(not style-warning
))))
195 (subtypep '(and warning
(not style-warning
)) dinfo
)))))))
199 (declaim (declaration fubar
))
201 (deftest declaration-information.declaration
202 (if (member 'fubar
(declaration-information 'declaration
)) 'yay
)
205 ;;;; VARIABLE-INFORMATION
209 (defmacro var-info
(var &environment env
)
210 (list 'quote
(multiple-value-list (variable-information var env
))))
212 (deftest variable-info.global-special
/unbound
216 (deftest variable-info.global-special
/unbound
/extra-decl
217 (locally (declare (special *foo
*))
221 (deftest variable-info.global-special
/bound
226 (deftest variable-info.global-special
/bound
/extra-decl
228 (declare (special *foo
*))
232 (deftest variable-info.local-special
/unbound
233 (locally (declare (special x
))
237 (deftest variable-info.local-special
/bound
239 (declare (special x
))
243 (deftest variable-info.local-special
/shadowed
245 (declare (special x
))
252 (deftest variable-info.local-special
/shadows-lexical
255 (declare (special x
))
259 (deftest variable-info.lexical
264 (deftest variable-info.lexical.type
268 (:lexical t
((type . fixnum
))))
270 (deftest variable-info.lexical.type
.2
274 (locally (declare (fixnum x
))
275 (assert (plusp x
)))))
278 (deftest variable-info.lexical.type
.3
280 (locally (declare (fixnum x
))
282 (:lexical t
((type . fixnum
))))
284 (deftest variable-info.ignore
288 (:lexical t
((ignore . t
))))
290 (deftest variable-info.symbol-macro
/local
291 (symbol-macrolet ((x 8))
293 (:symbol-macro t nil
))
295 (define-symbol-macro my-symbol-macro t
)
297 (deftest variable-info.symbol-macro
/global
298 (var-info my-symbol-macro
)
299 (:symbol-macro nil nil
))
301 (deftest variable-info.undefined
302 (var-info #:undefined
)
305 (declaim (global this-is-global
))
306 (deftest global-variable
307 (var-info this-is-global
)
310 (defglobal this-is-global-too
42)
311 (deftest global-variable
.2
312 (var-info this-is-global-too
)
313 (:global nil
((always-bound . t
))))
315 (sb-alien:define-alien-variable
"errno" sb-alien
:int
)
316 (deftest alien-variable
320 ;;;; FUNCTION-INFORMATION
322 (defmacro fun-info
(var &environment env
)
323 (list 'quote
(multiple-value-list (function-information var env
))))
325 (defun my-global-fun (x) x
)
327 (deftest function-info.global
/no-ftype
328 (fun-info my-global-fun
)
331 (declaim (ftype (function (cons) (values t
&optional
)) my-global-fun-2
))
333 (defun my-global-fun-2 (x) x
)
335 (deftest function-info.global
/ftype
336 (fun-info my-global-fun-2
)
337 (:function nil
((ftype function
(cons) (values t
&optional
)))))
339 (defmacro my-macro
(x) x
)
341 (deftest function-info.macro
345 (deftest function-info.macrolet
346 (macrolet ((thingy () nil
))
350 (deftest function-info.special-form
352 (:special-form nil nil
))
354 (deftest function-info.notinline
/local
356 (declare (notinline x
))
359 (:function t
((inline . notinline
))))
361 (declaim (notinline my-notinline
))
362 (defun my-notinline (x) x
)
364 (deftest function-info.notinline
/global
365 (fun-info my-notinline
)
366 (:function nil
((inline . notinline
))))
368 (declaim (inline my-inline
))
369 (defun my-inline (x) x
)
371 (deftest function-info.inline
/global
373 (:function nil
((inline . inline
))))
375 (deftest function-information.known-inline
376 (locally (declare (inline identity
))
378 (:function nil
((inline . inline
)
379 (ftype function
(t) (values t
&optional
)))))
381 (deftest function-information.ftype
383 (declare (ftype (sfunction (integer) integer
) foo
))
387 ((ftype function
(integer) (values integer
&optional
)))))
389 ;;;;; AUGMENT-ENVIRONMENT
391 (defmacro ct
(form &environment env
)
392 (let ((toeval `(let ((lexenv (quote ,env
)))
394 `(quote ,(eval toeval
))))
397 (deftest augment-environment.variable1
398 (multiple-value-bind (kind local alist
)
399 (variable-information
401 (augment-environment nil
:variable
(list 'x
) :declare
'((type integer x
))))
402 (list kind local
(cdr (assoc 'type alist
))))
403 (:lexical t integer
))
407 (deftest augment-environment.variable2
408 (identity (variable-information '*foo
* (augment-environment nil
:variable
'(*foo
*))))
411 (deftest augment-environment.variable3
412 (identity (variable-information 'foo
(augment-environment nil
:variable
'(foo))))
415 (deftest augment-environment.variable.special1
416 (identity (variable-information 'x
(augment-environment nil
:variable
'(x) :declare
'((special x
)))))
419 (deftest augment-environment.variable.special12
420 (locally (declare (special x
))
422 (variable-information
424 (identity (augment-environment lexenv
:variable
'(x))))))
427 (deftest augment-environment.variable.special13
428 (let* ((e1 (augment-environment nil
:variable
'(x) :declare
'((special x
))))
429 (e2 (augment-environment e1
:variable
'(x))))
430 (identity (variable-information 'x e2
)))
433 (deftest augment-environment.variable.special.mask
434 (let* ((e1 (augment-environment nil
:variable
'(x) :declare
'((ignore x
))))
435 (e2 (augment-environment e1
:variable
'(x))))
437 (nth 2 (multiple-value-list
438 (variable-information 'x e2
)))))
441 (deftest augment-environment.variable.ignore
442 (variable-information
444 (augment-environment nil
446 :declare
'((ignore x
))))
451 (deftest augment-environment.function
452 (function-information
454 (augment-environment nil
456 :declare
'((ftype (sfunction (integer) integer
) foo
))))
459 ((ftype function
(integer) (values integer
&optional
))))
462 (deftest augment-environment.macro
463 (macroexpand '(mac feh
)
466 :macro
(list (list 'mac
#'(lambda (form benv
)
467 (declare (ignore env
))
468 `(quote ,form
,form
,form
))))))
469 (quote (mac feh
) (mac feh
) (mac feh
))
472 (deftest augment-environment.symbol-macro
476 :symbol-macro
(list (list 'sym
'(foo bar baz
)))))
480 (deftest augment-environment.macro2
481 (eval (macroexpand '(newcond
484 (augment-environment nil
:macro
(list (list 'newcond
(macro-function 'cond
))))))
488 (deftest augment-environment.nest
491 (let* ((e (augment-environment lexenv
:variable
'(y))))
493 (variable-information 'x e
)
494 (variable-information 'y e
)))))
497 (deftest augment-environment.nest2
498 (symbol-macrolet ((x "x"))
500 (let* ((e (augment-environment lexenv
:variable
'(y))))
503 (variable-information 'y e
)))))
506 (deftest augment-environment.symbol-macro-var
507 (let ((e (augment-environment
509 :symbol-macro
(list (list 'sym
'(foo bar baz
)))
511 (list (macroexpand 'sym e
)
512 (variable-information 'x e
)))
518 ;;;;; DEFINE-DECLARATION
520 (defmacro third-value
(form)
521 (sb-int::with-unique-names
(a b c
)
522 `(multiple-value-bind (,a
,b
,c
) ,form
523 (declare (ignore ,a
,b
))
526 (deftest define-declaration.declare
528 (define-declaration zaphod
(spec env
)
529 (declare (ignore env
))
530 (values :declare
(cons 'zaphod spec
)))
531 (locally (declare (zaphod beblebrox
))
532 (locally (declare (zaphod and ford
))
533 (ct (declaration-information 'zaphod lexenv
)))))
537 (deftest define-declaration.declare2
539 (define-declaration zaphod
(spec env
)
540 (declare (ignore env
))
541 (values :declare
(cons 'zaphod spec
)))
543 (declare (zaphod beblebrox
)
545 (ct (declaration-information 'zaphod lexenv
))))
548 (deftest define-declaration.variable
550 (define-declaration vogon
(spec env
)
551 (declare (ignore env
))
552 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
553 (locally (declare (vogon poetry
))
557 (variable-information
560 (vogon-key . vogon-value
))
563 (deftest define-declaration.variable.special
565 (define-declaration vogon
(spec env
)
566 (declare (ignore env
))
567 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
570 (declare (special x
))
574 (variable-information 'x lexenv
))))))
575 (vogon-key . vogon-value
))
577 (deftest define-declaration.variable.special2
579 (define-declaration vogon
(spec env
)
580 (declare (ignore env
))
581 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
583 (declare (special x
))
588 (variable-information 'x lexenv
))))))
589 (vogon-key . vogon-value
))
591 (deftest define-declaration.variable.mask
593 (define-declaration vogon
(spec env
)
594 (declare (ignore env
))
595 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
602 (third (multiple-value-list (variable-information 'x lexenv
))))))))
605 (deftest define-declaration.variable.macromask
607 (define-declaration vogon
(spec env
)
608 (declare (ignore env
))
609 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
612 (symbol-macrolet ((x 42))
616 (third (multiple-value-list (variable-information 'x lexenv
))))))))
619 (deftest define-declaration.variable.macromask2
621 (define-declaration vogon
(spec env
)
622 (declare (ignore env
))
623 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
624 (symbol-macrolet ((x 42))
631 (third (multiple-value-list (variable-information 'x lexenv
))))))
635 (third (multiple-value-list (variable-information 'x lexenv
))))))))
636 (nil (vogon-key . vogon-value
)))
638 (deftest define-declaration.variable.mask2
640 (define-declaration vogon-a
(spec env
)
641 (declare (ignore env
))
642 (values :variable
`((,(cadr spec
) vogon-key a
))))
643 (define-declaration vogon-b
(spec env
)
644 (declare (ignore env
))
645 (values :variable
`((,(cadr spec
) vogon-key b
))))
647 (declare (vogon-a x
))
649 (declare (vogon-b x
)))
653 (third (multiple-value-list (variable-information 'x lexenv
)))))))
656 (deftest define-declaration.variable.specialmask
658 (define-declaration vogon
(spec env
)
659 (declare (ignore env
))
660 (values :variable
`((,(cadr spec
) vogon-key vogon-value
))))
662 (declare (vogon *foo
*))
667 (third (multiple-value-list (variable-information '*foo
* lexenv
))))))))
668 (vogon-key . vogon-value
))
672 (deftest define-declaration.function
674 (define-declaration sad
(spec env
)
675 (declare (ignore env
))
676 (values :function
`((,(cadr spec
) emotional-state sad
))))
677 (locally (declare (zaphod beblebrox
))
678 (locally (declare (sad robot
))
680 (assoc 'emotional-state
681 (third-value (function-information
684 (emotional-state . sad
))
686 (deftest define-declaration.function.lexical
688 (define-declaration sad
(spec env
)
689 (declare (ignore env
))
690 (values :function
`((,(cadr spec
) emotional-state sad
))))
692 (locally (declare (sad robot
))
694 (assoc 'emotional-state
695 (third-value (function-information
698 (emotional-state . sad
))
701 (deftest define-declaration.function.lexical2
703 (define-declaration sad
(spec env
)
704 (declare (ignore env
))
705 (values :function
`((,(cadr spec
) emotional-state sad
))))
706 (labels ((robot nil
))
707 (declare (sad robot
))
709 (assoc 'emotional-state
710 (third-value (function-information
713 (emotional-state . sad
))
715 (deftest define-declaration.function.mask
717 (define-declaration sad
(spec env
)
718 (declare (ignore env
))
719 (values :function
`((,(cadr spec
) emotional-state sad
))))
720 (labels ((robot nil
))
721 (declare (sad robot
))
722 (labels ((robot nil
))
724 (assoc 'emotional-state
725 (third-value (function-information
731 (deftest define-declaration.function.mask2
733 (define-declaration sad
(spec env
)
734 (declare (ignore env
))
735 (values :function
`((,(cadr spec
) emotional-state sad
))))
737 (declare (sad robot
))
738 (labels ((robot nil
))
740 (assoc 'emotional-state
741 (third-value (function-information
746 (deftest define-declaration.function2
748 (define-declaration happy
(spec env
)
749 (declare (ignore env
))
750 (values :function
`((,(cadr spec
) emotional-state happy
))))
751 (locally (declare (zaphod beblebrox
))
752 (locally (declare (sad robot
))
753 (locally (declare (happy robot
))
755 (assoc 'emotional-state
756 (third-value (function-information
759 (emotional-state . happy
))
761 (deftest macroexpand-all.special-binding
762 (let ((form '(macrolet ((v (x &environment env
)
763 (sb-cltl2:variable-information x env
)))
766 (declare (special x
))
769 (eval (sb-cltl2:macroexpand-all form
))))
770 ((:special
:special
) (:special
:special
)))
772 (deftest macroexpand-all.symbol-macro-shadowed
773 (let ((form '(macrolet ((v (x &environment env
)
774 (macroexpand x env
)))
775 (symbol-macrolet ((x :bad
))
780 (eval (sb-cltl2:macroexpand-all form
))))