dotimes.lsp 4.03 KB
Newer Older
pfdietz's avatar
pfdietz committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
;-*- Mode:     Lisp -*-
;;;; Author:   Paul Dietz
;;;; Created:  Sat Jan  8 07:27:15 2005
;;;; Contains: Tests of DOTIMES

(in-package :cl-test)


(deftest dotimes.1
  (dotimes (i 10))
  nil)

(deftest dotimes.2
  (dotimes (i 10 'a))
  a)

(deftest dotimes.3
  (dotimes (i 10 (values))))

(deftest dotimes.3a
  (dotimes (i 10 (values 'a 'b 'c)))
  a b c)

(deftest dotimes.4
  (let ((x nil))
    (dotimes (i 5 x) (push i x)))
  (4 3 2 1 0))

(deftest dotimes.5
  (let ((x nil))
    (dotimes (i 0 x) (push i x)))
  nil)

(deftest dotimes.6
  (block done
    (dotimes (i -1 'good)
      (return-from done 'bad)))
  good)

(deftest dotimes.7
  (block done
    (dotimes (i (1- most-negative-fixnum) 'good)
      (return-from done 'bad)))
  good)

;;; Implicit nil block has the right scope
(deftest dotimes.8
  (block nil
    (dotimes (i (return 1)))
    2)
  2)

(deftest dotimes.9
  (block nil
    (dotimes (i 10 (return 1)))
    2)
  2)

(deftest dotimes.10
  (block nil
    (dotimes (i 10) (return 1))
    2)
  2)

(deftest dotimes.11
  (let ((x nil))
    (dotimes (i 10)
      (push i x)
      (when (= i 5) (return x))))
  (5 4 3 2 1 0))

;;; Check there's an implicit tagbody
(deftest dotimes.12
  (let ((even nil)
sds's avatar
sds committed
75
        (odd nil))
pfdietz's avatar
pfdietz committed
76
    (dotimes (i 8 (values (reverse even)
sds's avatar
sds committed
77
                          (reverse odd)))
pfdietz's avatar
pfdietz committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
      (when (evenp i) (go even))
      (push i odd)
      (go done)
      even
      (push i even)
      done))
  (0 2 4 6)
  (1 3 5 7))

;;; Check that at the time the result form is evaluated,
;;; the index variable is set to the number of times the loop
;;; was executed.

(deftest dotimes.13
  (let ((i 100))
    (dotimes (i 10 i)))
  10)

(deftest dotimes.14
  (let ((i 100))
    (dotimes (i 0 i)))
  0)

(deftest dotimes.15
  (let ((i 100))
    (dotimes (i -1 i)))
  0)

;;; Check that the variable is not bound in the count form
(deftest dotimes.16
  (let ((i nil))
    (values
     i
     (dotimes (i (progn (setf i 'a) 10) i))
     i))
  nil 10 a)

;;; Check special variable decls
(deftest dotimes.17
  (let ((i 0) (y nil))
    (declare (special i))
    (flet ((%f () i))
      (dotimes (i 4)
sds's avatar
sds committed
121
        (push (%f) y)))
pfdietz's avatar
pfdietz committed
122 123 124
    y)
  (0 0 0 0))

125 126 127 128 129
(deftest dotimes.17a
  (let ((i 0) (y nil) (bound 4))
    (declare (special i))
    (flet ((%f () i))
      (dotimes (i bound)
sds's avatar
sds committed
130
        (push (%f) y)))
131 132 133
    y)
  (0 0 0 0))

pfdietz's avatar
pfdietz committed
134 135 136 137 138
(deftest dotimes.18
  (let ((i 0) (y nil))
    (declare (special i))
    (flet ((%f () i))
      (dotimes (i 4)
sds's avatar
sds committed
139 140
        (declare (special i))
        (push (%f) y)))
pfdietz's avatar
pfdietz committed
141 142 143
    y)
  (3 2 1 0))

144 145 146 147 148
(deftest dotimes.18a
  (let ((i 0) (y nil) (bound 4))
    (declare (special i))
    (flet ((%f () i))
      (dotimes (i bound)
sds's avatar
sds committed
149 150
        (declare (special i))
        (push (%f) y)))
151 152 153
    y)
  (3 2 1 0))

pfdietz's avatar
pfdietz committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
(deftest dotimes.19
  (dotimes (i 100 i))
  100)

(deftest dotimes.20
  (dotimes (i -100 i))
  0)

(deftest dotimes.21
  (let ((x 0))
    (dotimes (i (1- most-negative-fixnum) (values i x))
      (declare (type fixnum i))
      (incf x)))
  0 0)

169 170 171 172 173 174 175
;;; Scope of free declarations

(deftest dotimes.22
  (block done
    (let ((x :bad))
      (declare (special x))
      (let ((x :good))
sds's avatar
sds committed
176 177
        (dotimes (i (return-from done x))
          (declare (special x))))))
178 179 180 181 182 183 184
  :good)

(deftest dotimes.23
  (let ((x :good))
    (declare (special x))
    (let ((x :bad))
      (dotimes (i 10 x)
sds's avatar
sds committed
185
        (declare (special x)))))
186 187
  :good)

188 189 190 191 192
(deftest dotimes.23a
  (let ((x :good) (bound 10))
    (declare (special x))
    (let ((x :bad))
      (dotimes (i bound x)
sds's avatar
sds committed
193
        (declare (special x)))))
194 195 196 197 198 199 200 201 202 203
  :good)

(deftest dotimes.24
  (let ((bound 4) (j 0))
    (values
     (dotimes (i bound)
       (incf j) (decf bound))
     bound j))
  nil 0 4)

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
;;; Test that explicit calls to macroexpand in subforms
;;; are done in the correct environment

(deftest dotimes.25
  (macrolet
   ((%m (z) z))
   (let (result)
     (dotimes (i (expand-in-current-env (%m 4)) result)
       (push i result))))
  (3 2 1 0))

(deftest dotimes.26
  (macrolet
   ((%m (z) z))
   (let (result)
     (dotimes (i 4 (expand-in-current-env (%m result)))
       (push i result))))
  (3 2 1 0))

pfdietz's avatar
pfdietz committed
223 224
(def-macro-test dotimes.error.1
  (dotimes (i 10)))