rewrite elisp macros in elisp
[bpt/guile.git] / test-suite / tests / elisp-compiler.test
CommitLineData
92a61010 1;;;; elisp-compiler.test --- Test the compiler for Elisp. -*- scheme -*-
d158fa62 2;;;;
92a61010 3;;;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
d158fa62
DK
4;;;; Daniel Kraft
5;;;;
6;;;; This library is free software; you can redistribute it and/or
7;;;; modify it under the terms of the GNU Lesser General Public
8;;;; License as published by the Free Software Foundation; either
9;;;; version 3 of the License, or (at your option) any later version.
10;;;;
11;;;; This library is distributed in the hope that it will be useful,
12;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14;;;; Lesser General Public License for more details.
15;;;;
16;;;; You should have received a copy of the GNU Lesser General Public
17;;;; License along with this library; if not, write to the Free Software
18;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20(define-module (test-elisp-compiler)
21 :use-module (test-suite lib)
22 :use-module (system base compile)
23 :use-module (language elisp runtime))
24
25
26; Macros to handle the compilation conveniently.
27
28(define-syntax compile-test
450cb504 29 (syntax-rules (pass-if pass-if-equal pass-if-exception)
d158fa62
DK
30 ((_ (pass-if test-name exp))
31 (pass-if test-name (compile 'exp #:from 'elisp #:to 'value)))
a0899974
DK
32 ((_ (pass-if test-name exp #:opts opts))
33 (pass-if test-name (compile 'exp #:from 'elisp #:to 'value #:opts opts)))
d158fa62
DK
34 ((_ (pass-if-equal test-name result exp))
35 (pass-if test-name (equal? result
36 (compile 'exp #:from 'elisp #:to 'value))))
37 ((_ (pass-if-exception test-name exc exp))
38 (pass-if-exception test-name exc
39 (compile 'exp #:from 'elisp #:to 'value)))))
40
41(define-syntax with-test-prefix/compile
42 (syntax-rules ()
43 ((_ section-name exp ...)
44 (with-test-prefix section-name (compile-test exp) ...))))
45
46
47; Test control structures.
48; ========================
49
50(with-test-prefix/compile "Sequencing"
51
52 (pass-if-equal "progn" 1
53 (progn (setq a 0)
54 (setq a (1+ a))
fb66a47a
DK
55 a))
56
57 (pass-if "prog1"
58 (progn (setq a 0)
59 (setq b (prog1 a (setq a (1+ a))))
60 (and (= a 1) (= b 0))))
61
62 (pass-if "prog2"
63 (progn (setq a 0)
64 (setq b (prog2 (setq a (1+ a))
65 (setq a (1+ a))
66 (setq a (1+ a))))
67 (and (= a 3) (= b 2)))))
d158fa62
DK
68
69(with-test-prefix/compile "Conditionals"
70
71 (pass-if-equal "succeeding if" 1
72 (if t 1 2))
7d1a9782
DK
73 (pass-if "failing if"
74 (and (= (if nil
75 1
76 (setq a 2) (setq a (1+ a)) a)
77 3)
78 (equal (if nil 1) nil)))
79
d158fa62
DK
80 (pass-if-equal "empty cond" nil-value
81 (cond))
82 (pass-if-equal "all failing cond" nil-value
83 (cond (nil) (nil)))
84 (pass-if-equal "only condition" 5
85 (cond (nil) (5)))
86 (pass-if-equal "succeeding cond value" 42
87 (cond (nil) (t 42) (t 0)))
88 (pass-if-equal "succeeding cond side-effect" 42
89 (progn (setq a 0)
90 (cond (nil) (t (setq a 42) 1) (t (setq a 0)))
91 a)))
92
93(with-test-prefix/compile "Combining Conditions"
94
95 (pass-if-equal "empty and" t-value (and))
96 (pass-if-equal "failing and" nil-value (and 1 2 nil 3))
97 (pass-if-equal "succeeding and" 3 (and 1 2 3))
98
99 (pass-if-equal "empty or" nil-value (or))
100 (pass-if-equal "failing or" nil-value (or nil nil nil))
b6b9d596
DK
101 (pass-if-equal "succeeding or" 1 (or nil 1 nil 2 nil 3))
102
103 (pass-if-equal "not true" nil-value (not 1))
104 (pass-if-equal "not false" t-value (not nil)))
d158fa62
DK
105
106(with-test-prefix/compile "Iteration"
107
108 (pass-if-equal "failing while" 0
109 (progn (setq a 0)
110 (while nil (setq a 1))
111 a))
112 (pass-if-equal "running while" 120
113 (progn (setq prod 1
114 i 1)
115 (while (<= i 5)
116 (setq prod (* i prod))
117 (setq i (1+ i)))
a338fa3d 118 prod)))
d158fa62 119
35b2e41d
DK
120(with-test-prefix/compile "Exceptions"
121
122 (pass-if "catch without exception"
123 (and (setq a 0)
124 (= (catch 'foobar
125 (setq a (1+ a))
126 (setq a (1+ a))
127 a)
128 2)
129 (= (catch (+ 1 2) a) 2)))
130
131 ; FIXME: Figure out how to do this...
132 ;(pass-if-exception "uncaught exception" 'elisp-exception
133 ; (throw 'abc 1))
134
135 (pass-if "catch and throw"
136 (and (setq mylist '(1 2))
137 (= (catch 'abc (throw 'abc 2) 1) 2)
33da12ee 138 (= (catch 'abc (catch 'def (throw 'abc (1+ 0)) 2) 3) 1)
35b2e41d 139 (= (catch 'abc (catch 'def (throw 'def 1) 2) 3) 3)
59e46065 140 (= (catch mylist (catch (list 1 2) (throw mylist 1) 2) 3) 1)))
33da12ee
DK
141
142 (pass-if "unwind-protect"
143 (progn (setq a 0 b 1 c 1)
144 (catch 'exc
145 (unwind-protect (progn (setq a 1)
146 (throw 'exc 0))
147 (setq a 0)
148 (setq b 0)))
149 (unwind-protect nil (setq c 0))
150 (and (= a 0) (= b 0) (= c 0)
151 (= (unwind-protect 42 1 2 3) 42)))))
35b2e41d 152
e96a9591
DK
153(with-test-prefix/compile "Eval"
154
155 (pass-if-equal "basic eval" 3
156 (progn (setq code '(+ 1 2))
157 (eval code)))
158
159 (pass-if "real dynamic code"
160 (and (setq a 1 b 1 c 1)
161 (defun set-code (var val)
162 (list 'setq var val))
163 (= a 1) (= b 1) (= c 1)
164 (eval (set-code 'a '(+ 2 3)))
165 (eval (set-code 'c 42))
166 (= a 5) (= b 1) (= c 42)))
167
168 ; Build code that recursively again and again calls eval. What we want is
169 ; something like:
170 ; (eval '(1+ (eval '(1+ (eval 1)))))
171 (pass-if "recursive eval"
172 (progn (setq depth 10 i depth)
173 (setq code '(eval 0))
174 (while (not (zerop i))
0dbfdeef 175 (setq code (#{`}# (eval (quote (1+ (#{,}# code))))))
e96a9591
DK
176 (setq i (1- i)))
177 (= (eval code) depth))))
178
d158fa62
DK
179
180; Test handling of variables.
181; ===========================
182
183(with-test-prefix/compile "Variable Setting/Referencing"
184
185 ; TODO: Check for variable-void error
186
187 (pass-if-equal "setq and reference" 6
570c12ac
DK
188 (progn (setq a 1 b 2 c 3)
189 (+ a b c)))
e96a9591
DK
190 (pass-if-equal "setq evaluation order" 1
191 (progn (setq a 0 b 0)
192 (setq a 1 b a)))
570c12ac 193 (pass-if-equal "setq value" 2
37099846
DK
194 (progn (setq a 1 b 2)))
195
196 (pass-if "set and symbol-value"
197 (progn (setq myvar 'a)
198 (and (= (set myvar 42) 42)
199 (= a 42)
200 (= (symbol-value myvar) 42))))
201 (pass-if "void variables"
202 (progn (setq a 1 b 2)
203 (and (eq (makunbound 'b) 'b)
204 (boundp 'a)
3f70b2dc 205 (not (boundp 'b))))))
d158fa62
DK
206
207(with-test-prefix/compile "Let and Let*"
208
209 (pass-if-equal "let without value" nil-value
210 (let (a (b 5)) a))
211 (pass-if-equal "basic let" 0
212 (progn (setq a 0)
213 (let ((a 1)
214 (b a))
215 b)))
fd40f371
DK
216
217 (pass-if "let*"
d158fa62 218 (progn (setq a 0)
fd40f371
DK
219 (and (let* ((a 1)
220 (b a))
221 (= b 1))
222 (let* (a b)
223 (setq a 1 b 2)
224 (and (= a 1) (= b 2)))
225 (= a 0)
226 (not (boundp 'b)))))
d158fa62
DK
227
228 (pass-if "local scope"
229 (progn (setq a 0)
230 (setq b (let (a)
231 (setq a 1)
232 a))
233 (and (= a 0)
234 (= b 1)))))
235
a6a5cf03
DK
236(with-test-prefix/compile "Lexical Scoping"
237
238 (pass-if "basic let semantics"
239 (and (setq a 1)
240 (lexical-let ((a 2) (b a))
241 (and (= a 2) (= b 1)))
242 (lexical-let* ((a 2) (b a))
243 (and (= a 2) (= b 2) (setq a 42) (= a 42)))
244 (= a 1)))
245
246 (pass-if "lexical scope with lexical-let's"
247 (and (setq a 1)
248 (defun dyna () a)
249 (lexical-let (a)
250 (setq a 2)
251 (and (= a 2) (= (dyna) 1)))
252 (= a 1)
253 (lexical-let* (a)
254 (setq a 2)
255 (and (= a 2) (= (dyna) 1)))
256 (= a 1)))
257
258 (pass-if "lexical scoping vs. symbol-value / set"
259 (and (setq a 1)
260 (lexical-let ((a 2))
261 (and (= a 2)
262 (= (symbol-value 'a) 1)
263 (set 'a 3)
264 (= a 2)
265 (= (symbol-value 'a) 3)))
266 (= a 3)))
267
268 (pass-if "let inside lexical-let"
269 (and (setq a 1 b 1)
270 (defun dynvals () (cons a b))
271 (lexical-let ((a 2))
272 (and (= a 2) (equal (dynvals) '(1 . 1))
273 (let ((a 3) (b a))
274 (and (= a 3) (= b 2)
275 (equal (dynvals) '(1 . 2))))
276 (let* ((a 4) (b a))
277 (and (= a 4) (= b 4)
278 (equal (dynvals) '(1 . 4))))
279 (= a 2)))
280 (= a 1)))
281
282 (pass-if "lambda args inside lexical-let"
283 (and (setq a 1)
284 (defun dyna () a)
285 (lexical-let ((a 2) (b 42))
286 (and (= a 2) (= (dyna) 1)
287 ((lambda (a) (and (= a 3) (= b 42) (= (dyna) 3))) 3)
dfbc6e9d
DK
288 ((lambda () (let ((a 3))
289 (and (= a 3) (= (dyna) 1)))))
a6a5cf03
DK
290 (= a 2) (= (dyna) 1)))
291 (= a 1)))
292
293 (pass-if "closures"
294 (and (defun make-counter ()
295 (lexical-let ((cnt 0))
296 (lambda ()
297 (setq cnt (1+ cnt)))))
298 (setq c1 (make-counter) c2 (make-counter))
ce305387
DK
299 (= (funcall c1) 1)
300 (= (funcall c1) 2)
301 (= (funcall c1) 3)
302 (= (funcall c2) 1)
303 (= (funcall c2) 2)
304 (= (funcall c1) 4)
c808c926
DK
305 (= (funcall c2) 3)))
306
307 (pass-if "always lexical option (all)"
308 (progn (setq a 0)
309 (defun dyna () a)
310 (let ((a 1))
311 (and (= a 1) (= (dyna) 0))))
312 #:opts '(#:always-lexical all))
313 (pass-if "always lexical option (list)"
314 (progn (setq a 0 b 0)
315 (defun dyna () a)
316 (defun dynb () b)
317 (let ((a 1)
318 (b 1))
319 (and (= a 1) (= (dyna) 0)
320 (= b 1) (= (dynb) 1))))
321 #:opts '(#:always-lexical (a)))
322 (pass-if "with-always-lexical"
323 (progn (setq a 0)
324 (defun dyna () a)
325 (with-always-lexical (a)
326 (let ((a 1))
dfbc6e9d
DK
327 (and (= a 1) (= (dyna) 0))))))
328
329 (pass-if "lexical lambda args"
330 (progn (setq a 1 b 1)
331 (defun dyna () a)
332 (defun dynb () b)
333 (with-always-lexical (a c)
334 ((lambda (a b &optional c)
335 (and (= a 3) (= (dyna) 1)
336 (= b 2) (= (dynb) 2)
337 (= c 1)))
338 3 2 1))))
339
340 ; Check if a lambda without dynamically bound arguments
341 ; is tail-optimized by doing a deep recursion that would otherwise overflow
342 ; the stack.
343 (pass-if "lexical lambda tail-recursion"
344 (with-always-lexical (i)
345 (setq to 1000000)
346 (defun iteration-1 (i)
347 (if (< i to)
348 (iteration-1 (1+ i))))
349 (iteration-1 0)
350 (setq x 0)
351 (defun iteration-2 ()
352 (if (< x to)
353 (setq x (1+ x))
354 (iteration-2)))
355 (iteration-2)
356 t)))
357
a6a5cf03 358
d158fa62
DK
359(with-test-prefix/compile "defconst and defvar"
360
361 (pass-if-equal "defconst without docstring" 3.141
362 (progn (setq pi 3)
363 (defconst pi 3.141)
364 pi))
365 (pass-if-equal "defconst value" 'pi
366 (defconst pi 3.141 "Pi"))
367
368 (pass-if-equal "defvar without value" 42
369 (progn (setq a 42)
370 (defvar a)
371 a))
372 (pass-if-equal "defvar on already defined variable" 42
373 (progn (setq a 42)
374 (defvar a 1 "Some docstring is also ok")
375 a))
d158fa62 376 (pass-if-equal "defvar on undefined variable" 1
37099846
DK
377 (progn (makunbound 'a)
378 (defvar a 1)
d158fa62
DK
379 a))
380 (pass-if-equal "defvar value" 'a
381 (defvar a)))
382
383
384; Functions and lambda expressions.
385; =================================
386
387(with-test-prefix/compile "Lambda Expressions"
388
389 (pass-if-equal "required arguments" 3
390 ((lambda (a b c) c) 1 2 3))
391
392 (pass-if-equal "optional argument" 3
393 ((function (lambda (a &optional b c) c)) 1 2 3))
394 (pass-if-equal "optional missing" nil-value
395 ((lambda (&optional a) a)))
396
397 (pass-if-equal "rest argument" '(3 4 5)
398 ((lambda (a b &rest c) c) 1 2 3 4 5))
399 (pass-if-equal "rest missing" nil-value
400 ((lambda (a b &rest c) c) 1 2)))
401
402(with-test-prefix/compile "Function Definitions"
403
404 (pass-if-equal "defun" 3
405 (progn (defun test (a b) (+ a b))
406 (test 1 2)))
407 (pass-if-equal "defun value" 'test
37099846
DK
408 (defun test (a b) (+ a b)))
409
410 (pass-if "fset and symbol-function"
411 (progn (setq myfunc 'x x 5)
412 (and (= (fset myfunc 42) 42)
413 (= (symbol-function myfunc) 42)
414 (= x 5))))
415 (pass-if "void function values"
416 (progn (setq a 1)
417 (defun test (a b) (+ a b))
418 (fmakunbound 'a)
419 (fset 'b 5)
420 (and (fboundp 'b) (fboundp 'test)
421 (not (fboundp 'a))
e8f18b3f
DK
422 (= a 1))))
423
424 (pass-if "flet and flet*"
425 (progn (defun foobar () 42)
426 (defun test () (foobar))
427 (and (= (test) 42)
428 (flet ((foobar (lambda () 0))
429 (myfoo (symbol-function 'foobar)))
430 (and (= (myfoo) 42)
c6920dc8 431 (= (test) 42)))
e8f18b3f
DK
432 (flet* ((foobar (lambda () 0))
433 (myfoo (symbol-function 'foobar)))
c6920dc8 434 (= (myfoo) 42))
e8f18b3f
DK
435 (flet (foobar)
436 (defun foobar () 0)
c6920dc8 437 (= (test) 42))
e8f18b3f 438 (= (test) 42)))))
d158fa62
DK
439
440(with-test-prefix/compile "Calling Functions"
441
442 (pass-if-equal "recursion" 120
443 (progn (defun factorial (n prod)
444 (if (zerop n)
445 prod
446 (factorial (1- n) (* prod n))))
447 (factorial 5 1)))
448
449 (pass-if "dynamic scoping"
450 (progn (setq a 0)
451 (defun foo ()
452 (setq a (1+ a))
453 a)
454 (defun bar (a)
455 (foo))
456 (and (= 43 (bar 42))
e96a9591
DK
457 (zerop a))))
458
459 (pass-if "funcall and apply argument handling"
460 (and (defun allid (&rest args) args)
461 (setq allid-var (symbol-function 'allid))
462 (equal (funcall allid-var 1 2 3) '(1 2 3))
463 (equal (funcall allid-var) nil)
464 (equal (funcall allid-var 1 2 '(3 4)) '(1 2 (3 4)))
465 (equal (funcall allid-var '()) '(()))
466 (equal (apply allid-var 1 2 '(3 4)) '(1 2 3 4))
467 (equal (apply allid-var '(1 2)) '(1 2))
468 (equal (apply allid-var '()) nil)))
469
470 (pass-if "raw functions with funcall"
471 (and (= (funcall '+ 1 2) 3)
472 (= (funcall (lambda (a b) (+ a b)) 1 2) 3)
473 (= (funcall '(lambda (a b) (+ a b)) 1 2) 3))))
b6b9d596
DK
474
475
9b5ff6a6
DK
476; Quoting and Backquotation.
477; ==========================
478
479(with-test-prefix/compile "Quotation"
480
481 (pass-if "quote"
482 (and (equal '42 42) (equal '"abc" "abc")
483 (equal '(1 2 (3 (4) x)) '(1 2 (3 (4) x)))
484 (not (equal '(1 2 (3 4 (x))) '(1 2 3 4 x)))
485 (equal '(1 2 . 3) '(1 2 . 3))))
486
487 (pass-if "simple backquote"
0dbfdeef
BT
488 (and (equal (#{`}# 42) 42)
489 (equal (#{`}# (1 (a))) '(1 (a)))
490 (equal (#{`}# (1 . 2)) '(1 . 2))))
9b5ff6a6
DK
491 (pass-if "unquote"
492 (progn (setq a 42 l '(18 12))
0dbfdeef
BT
493 (and (equal (#{`}# (#{,}# a)) 42)
494 (equal (#{`}# (1 a ((#{,}# l)) . (#{,}# a))) '(1 a ((18 12)) . 42)))))
9b5ff6a6
DK
495 (pass-if "unquote splicing"
496 (progn (setq l '(18 12) empty '())
0dbfdeef
BT
497 (and (equal (#{`}# (#{,@}# l)) '(18 12))
498 (equal (#{`}# (l 2 (3 (#{,@}# l)) ((#{,@}# l)) (#{,@}# l)))
9b5ff6a6 499 '(l 2 (3 18 12) (18 12) 18 12))
0dbfdeef 500 (equal (#{`}# (1 2 (#{,@}# empty) 3)) '(1 2 3))))))
9b5ff6a6
DK
501
502
503
74c009da
DK
504; Macros.
505; =======
506
507(with-test-prefix/compile "Macros"
508
509 (pass-if-equal "defmacro value" 'magic-number
510 (defmacro magic-number () 42))
511
512 (pass-if-equal "macro expansion" 1
513 (progn (defmacro take-first (a b) a)
514 (take-first 1 (/ 1 0)))))
515
516
b6b9d596
DK
517; Test the built-ins.
518; ===================
519
e905e490
DK
520(with-test-prefix/compile "Equivalence Predicates"
521
522 (pass-if "equal"
523 (and (equal 2 2) (not (equal 1 2))
524 (equal "abc" "abc") (not (equal "abc" "ABC"))
525 (equal 'abc 'abc) (not (equal 'abc 'def))
526 (equal '(1 2 (3 4) 5) '(1 2 (3 4) 5))
527 (not (equal '(1 2 3 4 5) '(1 2 (3 4) 5)))))
528
529 (pass-if "eq"
530 (progn (setq some-list '(1 2))
531 (setq some-string "abc")
532 (and (eq 2 2) (not (eq 1 2))
533 (eq 'abc 'abc) (not (eq 'abc 'def))
59e46065
BT
534 (eq some-string some-string) (not (eq some-string (string 97 98 99)))
535 (eq some-list some-list) (not (eq some-list (list 1 2)))))))
e905e490 536
b6b9d596
DK
537(with-test-prefix/compile "Number Built-Ins"
538
539 (pass-if "floatp"
540 (and (floatp 1.0) (not (floatp 1)) (not (floatp 'a))))
541 (pass-if "integerp"
542 (and (integerp 42) (integerp -2) (not (integerp 1.0))))
543 (pass-if "numberp"
544 (and (numberp 1.0) (numberp -2) (not (numberp 'a))))
545 (pass-if "wholenump"
546 (and (wholenump 0) (not (wholenump -2)) (not (wholenump 1.0))))
547 (pass-if "zerop"
548 (and (zerop 0) (zerop 0.0) (not (zerop 1))))
549
550 (pass-if "comparisons"
551 (and (= 1 1.0) (/= 0 1)
552 (< 1 2) (> 2 1) (>= 1 1) (<= 1 1)
553 (not (< 1 1)) (not (<= 2 1))))
554
555 (pass-if "max and min"
556 (and (= (max -5 2 4.0 1) 4.0) (= (min -5 2 4.0 1) -5)
557 (= (max 1) 1) (= (min 1) 1)))
558 (pass-if "abs"
559 (and (= (abs 1.0) 1.0) (= (abs -5) 5)))
560
561 (pass-if "float"
562 (and (= (float 1) 1) (= (float 5.5) 5.5)
563 (floatp (float 1))))
564
565 (pass-if-equal "basic arithmetic operators" -8.5
566 (+ (1+ 0) (1- 0) (- 5.5) (* 2 -2) (- 2 1)))
567 (pass-if "modulo"
568 (= (% 5 3) 2))
569
570 (pass-if "floating point rounding"
571 (and (= (ffloor 1.7) 1.0) (= (ffloor -1.2) -2.0) (= (ffloor 1.0) 1.0)
572 (= (fceiling 1.2) 2.0) (= (fceiling -1.7) -1.0) (= (fceiling 1.0) 1.0)
573 (= (ftruncate 1.6) 1.0) (= (ftruncate -1.7) -1.0)
574 (= (fround 1.2) 1.0) (= (fround 1.7) 2.0) (= (fround -1.7) -2.0))))
f614ca12
DK
575
576(with-test-prefix/compile "List Built-Ins"
577
16254e5a 578 (pass-if "consp and atom"
f614ca12
DK
579 (and (consp '(1 2 3)) (consp '(1 2 . 3)) (consp '(a . b))
580 (not (consp '())) (not (consp 1)) (not (consp "abc"))
16254e5a
BT
581 (atom 'a) (atom '()) (atom -1.5) (atom "abc")
582 (not (atom '(1 . 2))) (not (atom '(1)))))
f614ca12
DK
583 (pass-if "listp and nlistp"
584 (and (listp '(1 2 3)) (listp '(1)) (listp '()) (listp '(1 . 2))
585 (not (listp 'a)) (not (listp 42)) (nlistp 42)
586 (not (nlistp '())) (not (nlistp '(1 2 3))) (not (nlistp '(1 . 2)))))
587 (pass-if "null"
588 (and (null '()) (not (null 1)) (not (null '(1 2))) (not (null '(1 . 2)))))
589
590 (pass-if "car and cdr"
591 (and (equal (car '(1 2 3)) 1) (equal (cdr '(1 2 3)) '(2 3))
592 (equal (car '()) nil) (equal (cdr '()) nil)
593 (equal (car '(1 . 2)) 1) (equal (cdr '(1 . 2)) 2)
594 (null (cdr '(1)))))
595 (pass-if "car-safe and cdr-safe"
596 (and (equal (car-safe '(1 2)) 1) (equal (cdr-safe '(1 2)) '(2))
597 (equal (car-safe 5) nil) (equal (cdr-safe 5) nil)))
598
f614ca12
DK
599 (pass-if "nth and nthcdr"
600 (and (equal (nth -5 '(1 2 3)) 1) (equal (nth 3 '(1 2 3)) nil)
601 (equal (nth 0 '(1 2 3)) 1) (equal (nth 2 '(1 2 3)) 3)
602 (equal (nthcdr -5 '(1 2 3)) '(1 2 3))
603 (equal (nthcdr 4 '(1 2 3)) nil)
604 (equal (nthcdr 1 '(1 2 3)) '(2 3))
605 (equal (nthcdr 2 '(1 2 3)) '(3))))
606
c2c7c277
DK
607 (pass-if "length"
608 (and (= (length '()) 0)
609 (= (length '(1 2 3 4 5)) 5)
610 (= (length '(1 2 (3 4 (5)) 6)) 4)))
611
f614ca12
DK
612 (pass-if "cons, list and make-list"
613 (and (equal (cons 1 2) '(1 . 2)) (equal (cons 1 '(2 3)) '(1 2 3))
614 (equal (cons 1 '()) '(1))
615 (equal (list 'a) '(a)) (equal (list) '()) (equal (list 1 2) '(1 2))
616 (equal (make-list 3 42) '(42 42 42))
617 (equal (make-list 0 1) '())))
618 (pass-if "append"
619 (and (equal (append '(1 2) '(3 4) '(5)) '(1 2 3 4 5))
620 (equal (append '(1 2) 3) '(1 2 . 3))))
621 (pass-if "reverse"
622 (and (equal (reverse '(5 4 3 2 1)) '(1 2 3 4 5))
623 (equal (reverse '()) '())))
f614ca12
DK
624 (pass-if "setcar and setcdr"
625 (progn (setq pair '(1 . 2))
626 (setq copy pair)
627 (setq a (setcar copy 3))
628 (setq b (setcdr copy 4))
629 (and (= a 3) (= b 4)
630 (equal pair '(3 . 4))))))