diff options
Diffstat (limited to 'lisp/test/list.lsp')
-rw-r--r-- | lisp/test/list.lsp | 1895 |
1 files changed, 1895 insertions, 0 deletions
diff --git a/lisp/test/list.lsp b/lisp/test/list.lsp new file mode 100644 index 0000000..23f4496 --- /dev/null +++ b/lisp/test/list.lsp @@ -0,0 +1,1895 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/test/list.lsp,v 1.6 2002/12/06 03:25:29 paulo Exp $ +;; + +;; basic lisp function tests + +;; Most of the tests are just the examples from the +;; +;; Common Lisp HyperSpec (TM) +;; Copyright 1996-2001, Xanalys Inc. All rights reserved. +;; +;; Some tests are hand crafted, to test how the interpreter treats +;; uncommon arguments or special conditions + + +#| + MAJOR PROBLEMS: + + o NIL and T should be always treated as symbols, actually it is + legal to say (defun nil (...) ...) + o There aren't true uninterned symbols, there are only symbols that + did not yet establish the home package, but once one is created, an + interned symbol is always returned. +|# + +(defun compare-test (test expect function arguments + &aux result (error t) unused error-value) + (multiple-value-setq + (unused error-value) + (ignore-errors + (setq result (apply function arguments)) + (setq error nil) + ) + ) + (if error + (format t "ERROR: (~S~{ ~S~}) => ~S~%" function arguments error-value) + (or (funcall test result expect) + (format t "(~S~{ ~S~}) => should be ~S not ~S~%" + function arguments expect result + ) + ) + ) +) + +(defun compare-eval (test expect form + &aux result (error t) unused error-value) + (multiple-value-setq + (unused error-value) + (ignore-errors + (setq result (eval form)) + (setq error nil) + ) + ) + (if error + (format t "ERROR: ~S => ~S~%" form error-value) + (or (funcall test result expect) + (format t "~S => should be ~S not ~S~%" + form expect result + ) + ) + ) +) + +(defun error-test (function &rest arguments &aux result (error t)) + (ignore-errors + (setq result (apply function arguments)) + (setq error nil) + ) + (or error + (format t "ERROR: no error for (~S~{ ~S~}), result was ~S~%" + function arguments result) + ) +) + +(defun error-eval (form &aux result (error t)) + (ignore-errors + (setq result (eval form)) + (setq error nil) + ) + (or error + (format t "ERROR: no error for ~S, result was ~S~%" form result) + ) +) + +(defun eq-test (expect function &rest arguments) + (compare-test #'eq expect function arguments)) + +(defun eql-test (expect function &rest arguments) + (compare-test #'eql expect function arguments)) + +(defun equal-test (expect function &rest arguments) + (compare-test #'equal expect function arguments)) + +(defun equalp-test (expect function &rest arguments) + (compare-test #'equalp expect function arguments)) + + +(defun eq-eval (expect form) + (compare-eval #'eq expect form)) + +(defun eql-eval (expect form) + (compare-eval #'eql expect form)) + +(defun equal-eval (expect form) + (compare-eval #'equal expect form)) + +(defun equalp-eval (expect form) + (compare-eval #'equalp expect form)) + +;; clisp treats strings loaded from a file as constants +(defun xseq (sequence) + #+clisp (if *load-pathname* (copy-seq sequence) sequence) + #-clisp sequence +) + +;; apply - function +(equal-test '((+ 2 3) . 4) #'apply 'cons '((+ 2 3) 4)) +(eql-test -1 #'apply #'- '(1 2)) +(eql-test 7 #'apply #'max 3 5 '(2 7 3)) +(error-test #'apply #'+ 1) +(error-test #'apply #'+ 1 2) +(error-test #'apply #'+ 1 . 2) +(error-test #'apply #'+ 1 2 3) +(error-test #'apply #'+ 1 2 . 3) +(eql-test 6 #'apply #'+ 1 2 3 ()) + +;; eq - function +(eq-eval t '(let* ((a #\a) (b a)) (eq a b))) +(eq-test t #'eq 'a 'a) +(eq-test nil #'eq 'a 'b) +(eq-eval t '(eq #1=1 #1#)) +(eq-test nil #'eq "abc" "abc") +(setq a '('x #c(1 2) #\z)) +(eq-test nil #'eq a (copy-seq a)) + +;; eql - function +(eq-test t #'eql 1 1) +(eq-test t #'eql 1.3d0 1.3d0) +(eq-test nil #'eql 1 1d0) +(eq-test t #'eql #c(1 -5) #c(1 -5)) +(eq-test t #'eql 'a 'a) +(eq-test nil #'eql :a 'a) +(eq-test t #'eql #c(5d0 0) 5d0) +(eq-test nil #'eql #c(5d0 0d0) 5d0) +(eq-test nil #'eql "abc" "abc") +(equal-eval '(1 5/6 #p"test" #\#) '(setq a '(1 5/6 #p"test" #\#))) +(eq-test nil #'eql a (copy-seq a)) + +(setf + hash0 (make-hash-table) + hash1 (make-hash-table) + (gethash 1 hash0) 2 + (gethash 1 hash1) 2 + (gethash :foo hash0) :bar + (gethash :foo hash1) :bar +) +(defstruct test a b c) +(setq + struc0 (make-test :a 1 :b 2 :c #\c) + struc1 (make-test :a 1 :b 2 :c #\c) +) + +;; equal - function +(eq-test t #'equal "abc" "abc") +(eq-test t #'equal 1 1) +(eq-test t #'equal #c(1 2) #c(1 2)) +(eq-test nil #'equal #c(1 2) #c(1 2d0)) +(eq-test t #'equal #\A #\A) +(eq-test nil #'equal #\A #\a) +(eq-test nil #'equal "abc" "Abc") +(equal-eval '(1 2 3/5 #\a) '(setq a '(1 2 3/5 #\a))) +(eq-test t #'equal a (copy-seq a)) +(eq-test nil #'equal hash0 hash1) +(eq-test nil #'equal struc0 struc1) +(eq-test nil #'equal #(1 2 3 4) #(1 2 3 4)) + +;; equalp - function +(eq-test t #'equalp hash0 hash1) +(setf + (gethash 2 hash0) "FoObAr" + (gethash 2 hash1) "fOoBaR" +) +(eq-test t #'equalp hash0 hash1) +(setf + (gethash 3 hash0) 3 + (gethash 3d0 hash1) 3 +) +(eq-test nil #'equalp hash0 hash1) +(eq-test t #'equalp struc0 struc1) +(setf + (test-a struc0) #\a + (test-a struc1) #\A +) +(eq-test t #'equalp struc0 struc1) +(setf + (test-b struc0) 'test + (test-b struc1) :test +) +(eq-test nil #'equalp struc0 struc1) +(eq-test t #'equalp #c(1/2 1d0) #c(0.5d0 1)) +(eq-test t #'equalp 1 1d0) +(eq-test t #'equalp #(1 2 3 4) #(1 2 3 4)) +(eq-test t #'equalp #(1 #\a 3 4d0) #(1 #\A 3 4)) + +;; acons - function +(equal-test '((1 . "one")) #'acons 1 "one" nil) +(equal-test '((2 . "two") (1 . "one")) #'acons 2 "two" '((1 . "one"))) + +;; adjoin - function +(equal-test '(nil) #'adjoin nil nil) +(equal-test '(a) #'adjoin 'a nil) +(equal-test '(1 2 3) #'adjoin 1 '(1 2 3)) +(equal-test '(1 2 3) #'adjoin 2 '(1 2 3)) +(equal-test '((1) (1) (2) (3)) #'adjoin '(1) '((1) (2) (3))) +(equal-test '((1) (2) (3)) #'adjoin '(1) '((1) (2) (3)) :key #'car) +(error-test #'adjoin nil 1) + +;; alpha-char-p - function +(eq-test t #'alpha-char-p #\a) +(eq-test nil #'alpha-char-p #\5) +(error-test #'alpha-char-p 'a) + +;; alphanumericp - function +(eq-test t #'alphanumericp #\Z) +(eq-test t #'alphanumericp #\8) +(eq-test nil #'alphanumericp #\#) + +;; and - macro +(eql-eval 1 '(setq temp1 1 temp2 1 temp3 1)) +(eql-eval 2 '(and (incf temp1) (incf temp2) (incf temp3))) +(eq-eval t '(and (eql 2 temp1) (eql 2 temp2) (eql 2 temp3))) +(eql-eval 1 '(decf temp3)) +(eq-eval nil '(and (decf temp1) (decf temp2) (eq temp3 'nil) (decf temp3))) +(eq-eval t '(and (eql temp1 temp2) (eql temp2 temp3))) +(eq-eval t '(and)) +(equal-eval '(1 2 3) '(multiple-value-list (and (values 'a) (values 1 2 3)))) +(equal-eval nil '(and (values) t)) + +;; append - function +(equal-test '(a b c d e f g) #'append '(a b c) '(d e f) '() '(g)) +(equal-test '(a b c . d) #'append '(a b c) 'd) +(eq-test nil #'append) +(eql-test 'a #'append nil 'a) +(error-test #'append 1 2) + +;; assoc - function +(equal-test '(1 . "one") #'assoc 1 '((2 . "two") (1 . "one"))) +(equal-test '(2 . "two") #'assoc 2 '((1 . "one") (2 . "two"))) +(eq-test nil #'assoc 1 nil) +(equal-test '(2 . "two") #'assoc-if #'evenp '((1 . "one") (2 . "two"))) +(equal-test '(3 . "three") #'assoc-if-not #'(lambda(x) (< x 3)) + '((1 . "one") (2 . "two") (3 . "three"))) +(equal-test '("two" . 2) #'assoc #\o '(("one" . 1) ("two" . 2) ("three" . 3)) + :key #'(lambda (x) (char x 2))) +(equal-test '(a . b) #'assoc 'a '((x . a) (y . b) (a . b) (a . c))) + +;; atom - function +(eq-test t #'atom 1) +(eq-test t #'atom '()) +(eq-test nil #'atom '(1)) +(eq-test t #'atom 'a) + +;; block - special operator +(eq-eval nil '(block empty)) +(eql-eval 2 '(let ((x 1)) + (block stop (setq x 2) (return-from stop) (setq x 3)) x)) +(eql-eval 2 '(block twin (block twin (return-from twin 1)) 2)) + +;; both-case-p - function +(eq-test t #'both-case-p #\a) +(eq-test nil #'both-case-p #\1) + +;; boundp - function +(eql-eval 1 '(setq x 1)) +(eq-test t #'boundp 'x) +(makunbound 'x) +(eq-test nil #'boundp 'x) +(eq-eval nil '(let ((x 1)) (boundp 'x))) +(error-test #'boundp 1) + +;; butlast, nbutlast - function +(setq x '(1 2 3 4 5 6 7 8 9)) +(equal-test '(1 2 3 4 5 6 7 8) #'butlast x) +(equal-eval '(1 2 3 4 5 6 7 8 9) 'x) +(eq-eval nil '(nbutlast x 9)) +(equal-test '(1) #'nbutlast x 8) +(equal-eval '(1) 'x) +(eq-test nil #'butlast nil) +(eq-test nil #'nbutlast '()) +(error-test #'butlast 1 2) +(error-test #'butlast -1 '(1 2)) + +;; car, cdr, caar ... - function +(eql-test 1 #'car '(1 2)) +(eql-test 2 #'cdr '(1 . 2)) +(eql-test 1 #'caar '((1 2))) +(eql-test 2 #'cadr '(1 2)) +(eql-test 2 #'cdar '((1 . 2))) +(eql-test 3 #'cddr '(1 2 . 3)) +(eql-test 1 #'caaar '(((1 2)))) +(eql-test 2 #'caadr '(1 (2 3))) +(eql-test 2 #'cadar '((1 2) 2 3)) +(eql-test 3 #'caddr '(1 2 3 4)) +(eql-test 2 #'cdaar '(((1 . 2)) 3)) +(eql-test 3 #'cdadr '(1 (2 . 3) 4)) +(eql-test 3 #'cddar '((1 2 . 3) 3)) +(eql-test 4 #'cdddr '(1 2 3 . 4)) +(eql-test 1 #'caaaar '((((1 2))))) +(eql-test 2 #'caaadr '(1 ((2)))) +(eql-test 2 #'caadar '((1 (2)) 3)) +(eql-test 3 #'caaddr '(1 2 (3 4))) +(eql-test 2 #'cadaar '(((1 2)) 3)) +(eql-test 3 #'cadadr '(1 (2 3) 4)) +(eql-test 3 #'caddar '((1 2 3) 4)) +(eql-test 4 #'cadddr '(1 2 3 4 5)) +(eql-test 2 #'cdaaar '((((1 . 2))) 3)) +(eql-test 3 #'cdaadr '(1 ((2 . 3)) 4)) +(eql-test 3 #'cdadar '((1 (2 . 3)) 4)) +(eql-test 4 #'cdaddr '(1 2 (3 . 4) 5)) +(eql-test 3 #'cddaar '(((1 2 . 3)) 4)) +(eql-test 4 #'cddadr '(1 (2 3 . 4) 5)) +(eql-test 4 #'cdddar '((1 2 3 . 4) 5)) +(eql-test 5 #'cddddr '(1 2 3 4 . 5)) + +;; first ... tenth, rest - function +(eql-test 2 #'rest '(1 . 2)) +(eql-test 1 #'first '(1 2)) +(eql-test 2 #'second '(1 2 3)) +(eql-test 2 #'second '(1 2 3)) +(eql-test 3 #'third '(1 2 3 4)) +(eql-test 4 #'fourth '(1 2 3 4 5)) +(eql-test 5 #'fifth '(1 2 3 4 5 6)) +(eql-test 6 #'sixth '(1 2 3 4 5 6 7)) +(eql-test 7 #'seventh '(1 2 3 4 5 6 7 8)) +(eql-test 8 #'eighth '(1 2 3 4 5 6 7 8 9)) +(eql-test 9 #'ninth '(1 2 3 4 5 6 7 8 9 10)) +(eql-test 10 #'tenth '(1 2 3 4 5 6 7 8 9 10 11)) +(error-test #'car 1) +(error-test #'car #c(1 2)) +(error-test #'car #(1 2)) + +;; case - macro +(eql-eval t '(let ((a 1)) (case a ((4 5 6) nil) ((3 2 1) t) (otherwise :error)))) +(eql-eval t '(let ((a 1)) (case a ((3 2) nil) (1 t) (t :error)))) +(error-eval '(let ((a 1)) (case a (2 :error) (t nil) (otherwise t)))) +(error-eval '(let ((a 1)) (case a (2 :error) (otherwise t) (t nil)))) + +;; catch - special operator +(eql-eval 3 '(catch 'dummy-tag 1 2 (throw 'dummy-tag 3) 4)) +(eql-eval 4 '(catch 'dummy-tag 1 2 3 4)) +(eq-eval 'throw-back '(defun throw-back (tag) (throw tag t))) +(eq-eval t '(catch 'dummy-tag (throw-back 'dummy-tag) 2)) + +;; char - function +(eql-test #\a #'char "abc" 0) +(eql-test #\b #'char "abc" 1) +(error-test #'char "abc" 3) + +;; char-* - function +(eq-test nil #'alpha-char-p #\3) +(eq-test t #'alpha-char-p #\y) +(eql-test #\a #'char-downcase #\a) +(eql-test #\a #'char-downcase #\a) +(eql-test #\1 #'char-downcase #\1) +(error-test #'char-downcase 1) +(eql-test #\A #'char-upcase #\a) +(eql-test #\A #'char-upcase #\A) +(eql-test #\1 #'char-upcase #\1) +(error-test #'char-upcase 1) +(eq-test t #'lower-case-p #\a) +(eq-test nil #'lower-case-p #\A) +(eq-test t #'upper-case-p #\W) +(eq-test nil #'upper-case-p #\w) +(eq-test t #'both-case-p #\x) +(eq-test nil #'both-case-p #\%) +(eq-test t #'char= #\d #\d) +(eq-test t #'char-equal #\d #\d) +(eq-test nil #'char= #\A #\a) +(eq-test t #'char-equal #\A #\a) +(eq-test nil #'char= #\d #\x) +(eq-test nil #'char-equal #\d #\x) +(eq-test nil #'char= #\d #\D) +(eq-test t #'char-equal #\d #\D) +(eq-test nil #'char/= #\d #\d) +(eq-test nil #'char-not-equal #\d #\d) +(eq-test nil #'char/= #\d #\d) +(eq-test nil #'char-not-equal #\d #\d) +(eq-test t #'char/= #\d #\x) +(eq-test t #'char-not-equal #\d #\x) +(eq-test t #'char/= #\d #\D) +(eq-test nil #'char-not-equal #\d #\D) +(eq-test t #'char= #\d #\d #\d #\d) +(eq-test t #'char-equal #\d #\d #\d #\d) +(eq-test nil #'char= #\d #\D #\d #\d) +(eq-test t #'char-equal #\d #\D #\d #\d) +(eq-test nil #'char/= #\d #\d #\d #\d) +(eq-test nil #'char-not-equal #\d #\d #\d #\d) +(eq-test nil #'char/= #\d #\d #\D #\d) +(eq-test nil #'char-not-equal #\d #\d #\D #\d) +(eq-test nil #'char= #\d #\d #\x #\d) +(eq-test nil #'char-equal #\d #\d #\x #\d) +(eq-test nil #'char/= #\d #\d #\x #\d) +(eq-test nil #'char-not-equal #\d #\d #\x #\d) +(eq-test nil #'char= #\d #\y #\x #\c) +(eq-test nil #'char-equal #\d #\y #\x #\c) +(eq-test t #'char/= #\d #\y #\x #\c) +(eq-test t #'char-not-equal #\d #\y #\x #\c) +(eq-test nil #'char= #\d #\c #\d) +(eq-test nil #'char-equal #\d #\c #\d) +(eq-test nil #'char/= #\d #\c #\d) +(eq-test nil #'char-not-equal #\d #\c #\d) +(eq-test t #'char< #\d #\x) +(eq-test t #'char-lessp #\d #\x) +(eq-test t #'char-lessp #\d #\X) +(eq-test t #'char-lessp #\D #\x) +(eq-test t #'char-lessp #\D #\X) +(eq-test t #'char<= #\d #\x) +(eq-test t #'char-not-greaterp #\d #\x) +(eq-test t #'char-not-greaterp #\d #\X) +(eq-test t #'char-not-greaterp #\D #\x) +(eq-test t #'char-not-greaterp #\D #\X) +(eq-test nil #'char< #\d #\d) +(eq-test nil #'char-lessp #\d #\d) +(eq-test nil #'char-lessp #\d #\D) +(eq-test nil #'char-lessp #\D #\d) +(eq-test nil #'char-lessp #\D #\D) +(eq-test t #'char<= #\d #\d) +(eq-test t #'char-not-greaterp #\d #\d) +(eq-test t #'char-not-greaterp #\d #\D) +(eq-test t #'char-not-greaterp #\D #\d) +(eq-test t #'char-not-greaterp #\D #\D) +(eq-test t #'char< #\a #\e #\y #\z) +(eq-test t #'char-lessp #\a #\e #\y #\z) +(eq-test t #'char-lessp #\a #\e #\y #\Z) +(eq-test t #'char-lessp #\a #\E #\y #\z) +(eq-test t #'char-lessp #\A #\e #\y #\Z) +(eq-test t #'char<= #\a #\e #\y #\z) +(eq-test t #'char-not-greaterp #\a #\e #\y #\z) +(eq-test t #'char-not-greaterp #\a #\e #\y #\Z) +(eq-test t #'char-not-greaterp #\A #\e #\y #\z) +(eq-test nil #'char< #\a #\e #\e #\y) +(eq-test nil #'char-lessp #\a #\e #\e #\y) +(eq-test nil #'char-lessp #\a #\e #\E #\y) +(eq-test nil #'char-lessp #\A #\e #\E #\y) +(eq-test t #'char<= #\a #\e #\e #\y) +(eq-test t #'char-not-greaterp #\a #\e #\e #\y) +(eq-test t #'char-not-greaterp #\a #\E #\e #\y) +(eq-test t #'char> #\e #\d) +(eq-test t #'char-greaterp #\e #\d) +(eq-test t #'char-greaterp #\e #\D) +(eq-test t #'char-greaterp #\E #\d) +(eq-test t #'char-greaterp #\E #\D) +(eq-test t #'char>= #\e #\d) +(eq-test t #'char-not-lessp #\e #\d) +(eq-test t #'char-not-lessp #\e #\D) +(eq-test t #'char-not-lessp #\E #\d) +(eq-test t #'char-not-lessp #\E #\D) +(eq-test t #'char> #\d #\c #\b #\a) +(eq-test t #'char-greaterp #\d #\c #\b #\a) +(eq-test t #'char-greaterp #\d #\c #\b #\A) +(eq-test t #'char-greaterp #\d #\c #\B #\a) +(eq-test t #'char-greaterp #\d #\C #\b #\a) +(eq-test t #'char-greaterp #\D #\C #\b #\a) +(eq-test t #'char>= #\d #\c #\b #\a) +(eq-test t #'char-not-lessp #\d #\c #\b #\a) +(eq-test t #'char-not-lessp #\d #\c #\b #\A) +(eq-test t #'char-not-lessp #\D #\c #\b #\a) +(eq-test t #'char-not-lessp #\d #\C #\B #\a) +(eq-test nil #'char> #\d #\d #\c #\a) +(eq-test nil #'char-greaterp #\d #\d #\c #\a) +(eq-test nil #'char-greaterp #\d #\d #\c #\A) +(eq-test nil #'char-greaterp #\d #\D #\c #\a) +(eq-test nil #'char-greaterp #\d #\D #\C #\a) +(eq-test t #'char>= #\d #\d #\c #\a) +(eq-test t #'char-not-lessp #\d #\d #\c #\a) +(eq-test t #'char-not-lessp #\d #\D #\c #\a) +(eq-test t #'char-not-lessp #\D #\d #\c #\a) +(eq-test t #'char-not-lessp #\D #\D #\c #\A) +(eq-test nil #'char> #\e #\d #\b #\c #\a) +(eq-test nil #'char-greaterp #\e #\d #\b #\c #\a) +(eq-test nil #'char-greaterp #\E #\d #\b #\c #\a) +(eq-test nil #'char-greaterp #\e #\D #\b #\c #\a) +(eq-test nil #'char-greaterp #\E #\d #\B #\c #\A) +(eq-test nil #'char>= #\e #\d #\b #\c #\a) +(eq-test nil #'char-not-lessp #\e #\d #\b #\c #\a) +(eq-test nil #'char-not-lessp #\e #\d #\b #\c #\A) +(eq-test nil #'char-not-lessp #\E #\d #\B #\c #\a) + +;; char-code - function +;; XXX assumes ASCII +(eql-test 49 #'char-code #\1) +(eql-test 90 #'char-code #\Z) +(eql-test 127 #'char-code #\Delete) +(eql-test 27 #'char-code #\Escape) +(eql-test 13 #'char-code #\Return) +(eql-test 0 #'char-code #\Null) +(eql-test 10 #'char-code #\Newline) +(error-test #'char-code 65) + +;; character - function +(eql-test #\a #'character #\a) +(eql-test #\a #'character "a") +(eql-test #\A #'character 'a) + +;; XXX assumes ASCII, and should be allowed to fail? +(eql-test #\A #'character 65) + +(error-test #'character 1/2) +(error-test #'character "abc") +(error-test #'character :test) +(eq-test #\T #'character t) +(error-test #'character nil) + +;; characterp - function +(eq-test t #'characterp #\a) +(eq-test nil #'characterp 1) +(eq-test nil #'characterp 1/2) +(eq-test nil #'characterp 'a) +(eq-test nil #'characterp '`a) + + + + +;; TODO coerce + + + + +;; cond - macro +(eql-eval 2 '(let ((a 1)) (cond ((= a 2) 1) ((= a 1) 2) ((= a 0) 1) (t nil)))) +(eql-eval nil '(let ((a 1)) (cond ((= a 2) 1) (t nil) ((= a 1) 2) ((= a 0) 1)))) + +;; consp - function (predicate) +(eq-test t #'consp '(1 2)) +(eq-test t #'consp '(1 . 2)) +(eq-test nil #'consp nil) +(eq-test nil #'consp 1) + +;; constantp - function (predicate) +(eq-test t #'constantp 1) +(eq-test t #'constantp #\x) +(eq-test t #'constantp :test) +(eq-test nil #'constantp 'test) +(eq-test t #'constantp ''1) +(eq-test t #'constantp '(quote 1)) +(eq-test t #'constantp "string") +(eq-test t #'constantp #c(1 2)) +(eq-test t #'constantp #(1 2)) +(eq-test nil #'constantp #p"test") +(eq-test nil #'constantp '(1 2)) +(eq-test nil #'constantp (make-hash-table)) +(eq-test nil #'constantp *package*) +(eq-test nil #'constantp *standard-input*) + +;; copy-list, copy-alist and copy-tree - function +(equal-test '(1 2) #'copy-list '(1 2)) +(equal-test '(1 . 2) #'copy-list '(1 . 2)) +(eq-test nil #'copy-list nil) +(error-test #'copy-list 1) +(equal-eval '(1 (2 3)) '(setq x '(1 (2 3)))) +(equal-eval x '(setq y (copy-list x))) +(equal-test '("one" (2 3)) #'rplaca x "one") +(eql-test 1 #'car y) +(equal-test '("two" 3) #'rplaca (cadr x) "two") +(eq-test (caadr x) #'caadr y) +(equal-eval '(1 (2 3) 4) '(setq a '(1 (2 3) 4) b (copy-list a))) +(eq-eval t '(eq (cadr a) (cadr b))) +(eq-eval t '(eq (car a) (car b))) +(setq a '(1 (2 3) 4) b (copy-alist a)) +(eq-eval nil '(eq (cadr a) (cadr b))) +(eq-eval t '(eq (car a) (car b))) +(eq-test nil #'copy-alist nil) +(eq-test nil #'copy-list nil) +(error-test #'copy-list 1) +(setq a '(1 (2 (3)))) +(setq as-list (copy-list a)) +(setq as-alist (copy-alist a)) +(setq as-tree (copy-tree a)) +(eq-eval t '(eq (cadadr a) (cadadr as-list))) +(eq-eval t '(eq (cadadr a) (cadadr as-alist))) +(eq-eval nil '(eq (cadadr a) (cadadr as-tree))) + +;; decf - macro +(setq n 2) +(eql-eval 1 '(decf n)) +(eql-eval 1 'n) +(setq n -2147483648) +(eql-eval -2147483649 '(decf n)) +(eql-eval -2147483649 'n) +(setq n 0) +(eql-eval -0.5d0 '(decf n 0.5d0)) +(eql-eval -0.5d0 'n) +(setq n 1) +(eql-eval 1/2 '(decf n 1/2)) +(eql-eval 1/2 'n) + +;; delete and remove - function +(setq a '(1 3 4 5 9) b a) +(equal-test '(1 3 5 9) #'remove 4 a) +(eq-eval t '(eq a b)) +(setq a (delete 4 a)) +(equal-eval '(1 3 5 9) 'a) +(setq a '(1 2 4 1 3 4 5) b a) +(equal-test '(1 2 1 3 5) #'remove 4 a) +(eq-eval t '(eq a b)) +(equal-test '(1 2 1 3 4 5) #'remove 4 a :count 1) +(eq-eval t '(eq a b)) +(equal-test '(1 2 4 1 3 5) #'remove 4 a :count 1 :from-end t) +(eq-eval t '(eq a b)) +(equal-test '(4 3 4 5) #'remove 3 a :test #'>) +(eq-eval t '(eq a b)) +(setq a (delete 4 '(1 2 4 1 3 4 5))) +(equal-eval '(1 2 1 3 5) 'a) +(setq a (delete 4 '(1 2 4 1 3 4 5) :count 1)) +(equal-eval '(1 2 1 3 4 5) 'a) +(setq a (delete 4 '(1 2 4 1 3 4 5) :count 1 :from-end t)) +(equal-eval '(1 2 4 1 3 5) 'a) +(equal-test "abc" #'delete-if #'digit-char-p "a1b2c3") +(equal-test "123" #'delete-if-not #'digit-char-p "a1b2c3") +(eq-test nil #'delete 1 nil) +(eq-test nil #'remove 1 nil) +(setq a '(1 2 3 4 :test 5 6 7 8) b a) +(equal-test '(1 2 :test 7 8) #'remove-if #'numberp a :start 2 :end 7) +(eq-eval t '(eq a b)) +(setq a (delete-if #'numberp a :start 2 :end 7)) +(equal-eval '(1 2 :test 7 8) 'a) + +;; digit-char - function +(eql-test #\0 #'digit-char 0) +(eql-test #\A #'digit-char 10 11) +(eq-test nil #'digit-char 10 10) +(eql-test 35 #'digit-char-p #\z 36) +(error-test #'digit-char #\a) +(error-test #'digit-char-p 1/2) + + + +;; TODO directory (known to have problems with parameters like "../*/../*/") + + + +;; elt - function +(eql-test #\a #'elt "xabc" 1) +(eql-test 3 #'elt '(0 1 2 3) 3) +(error-test #'elt nil 0) + +;; endp - function +(eql-test t #'endp nil) +(error-test #'endp t) +(eql-test nil #'endp '(1 . 2)) +(error-test #'endp #(1 2)) + +;; every - function +(eql-test t #'every 'not-used ()) +(eql-test t #'every #'characterp "abc") +(eql-test nil #'every #'< '(1 2 3) '(4 5 6) #(7 8 -1)) +(eql-test t #'every #'< '(1 2 3) '(4 5 6) #(7 8)) + +;; fboundp and fmakunbound - function +(eq-test t #'fboundp 'car) +(eq-eval 'test '(defun test ())) +(eq-test t #'fboundp 'test) +(eq-test 'test #'fmakunbound 'test) +(eq-test nil #'fboundp 'test) +(eq-eval 'test '(defmacro test (x) x)) +(eq-test t #'fboundp 'test) +(eq-test 'test #'fmakunbound 'test) + +;; fill - function +(setq x (list 1 2 3 4)) +(equal-test '((4 4 4 4) (4 4 4 4) (4 4 4 4) (4 4 4 4)) #'fill x '(4 4 4 4)) +(eq-eval t '(eq (car x) (cadr x))) +(equalp-test '#(a z z d e) #'fill '#(a b c d e) 'z :start 1 :end 3) +(equal-test "012ee" #'fill (xseq "01234") #\e :start 3) +(error-test #'fill 1 #\a) + +;; find - function +(eql-test #\Space #'find #\d "here are some letters that can be looked at" :test #'char>) +(eql-test 3 #'find-if #'oddp '(1 2 3 4 5) :end 3 :from-end t) +(eq-test nil #'find-if-not #'complexp '#(3.5 2 #C(1.0 0.0) #C(0.0 1.0)) :start 2) +(eq-test nil #'find 1 "abc") +(error-test #'find 1 #c(1 2)) + +;; find-symbol - function +(equal-eval '(nil nil) + '(multiple-value-list (find-symbol "NEVER-BEFORE-USED"))) +(equal-eval '(nil nil) + '(multiple-value-list (find-symbol "NEVER-BEFORE-USED"))) +(setq test (multiple-value-list (intern "NEVER-BEFORE-USED"))) +(equal-eval test '(read-from-string "(never-before-used nil)")) +(equal-eval '(never-before-used :internal) + '(multiple-value-list (intern "NEVER-BEFORE-USED"))) +(equal-eval '(never-before-used :internal) + '(multiple-value-list (find-symbol "NEVER-BEFORE-USED"))) +(equal-eval '(nil nil) + '(multiple-value-list (find-symbol "never-before-used"))) +(equal-eval '(car :inherited) + '(multiple-value-list (find-symbol "CAR" 'common-lisp-user))) +(equal-eval '(car :external) + '(multiple-value-list (find-symbol "CAR" 'common-lisp))) +;; XXX these will generate wrong results, NIL is not really a symbol +;; currently in the interpreter +(equal-eval '(nil :inherited) + '(multiple-value-list (find-symbol "NIL" 'common-lisp-user))) +(equal-eval '(nil :external) + '(multiple-value-list (find-symbol "NIL" 'common-lisp))) +(setq test (multiple-value-list + (find-symbol "NIL" (prog1 (make-package "JUST-TESTING" :use '()) + (intern "NIL" "JUST-TESTING"))))) +(equal-eval (read-from-string "(just-testing::nil :internal)") 'test) +(eq-eval t '(export 'just-testing::nil 'just-testing)) +(equal-eval '(just-testing:nil :external) + '(multiple-value-list (find-symbol "NIL" 'just-testing))) + +#+xedit (equal-eval '(nil nil) + '(multiple-value-list (find-symbol "NIL" "KEYWORD"))) +#| +;; optional result of previous form: +(equal-eval '(:nil :external) + '(multiple-value-list (find-symbol "NIL" "KEYWORD"))) +|# + + + +;; funcall - function +(eql-test 6 #'funcall #'+ 1 2 3) +(eql-test 1 #'funcall #'car '(1 2 3)) +(equal-test '(1 2 3) #'funcall #'list 1 2 3) + + + +;; TODO properly implement ``function'' + + + +;; functionp - function (predicate) +(eq-test nil #'functionp 'append) +(eq-test t #'functionp #'append) +(eq-test nil #'functionp '(lambda (x) (* x x))) +(eq-test t #'functionp #'(lambda (x) (* x x))) +(eq-test t #'functionp (symbol-function 'append)) +(eq-test nil #'functionp 1) +(eq-test nil #'functionp nil) + +;; gensym - function +(setq sym1 (gensym)) +(eq-test nil #'symbol-package sym1) +(setq sym1 (gensym 100)) +(setq sym2 (gensym 100)) +(eq-test nil #'eq sym1 sym2) +(eq-test nil #'equalp (gensym) (gensym)) + +;; get - accessor +(defun make-person (first-name last-name) + (let ((person (gensym "PERSON"))) + (setf (get person 'first-name) first-name) + (setf (get person 'last-name) last-name) + person)) +(eq-eval '*john* '(defvar *john* (make-person "John" "Dow"))) +(eq-eval '*sally* '(defvar *sally* (make-person "Sally" "Jones"))) +(equal-eval "John" '(get *john* 'first-name)) +(equal-eval "Jones" '(get *sally* 'last-name)) +(defun marry (man woman married-name) + (setf (get man 'wife) woman) + (setf (get woman 'husband) man) + (setf (get man 'last-name) married-name) + (setf (get woman 'last-name) married-name) + married-name) +(equal-eval "Dow-Jones" '(marry *john* *sally* "Dow-Jones")) +(equal-eval "Dow-Jones" '(get *john* 'last-name)) +(equal-eval "Sally" '(get (get *john* 'wife) 'first-name)) +(equal-eval `(wife ,*sally* last-name "Dow-Jones" first-name "John") + '(symbol-plist *john*)) +(eq-eval 'age + '(defmacro age (person &optional (default ''thirty-something)) + `(get ,person 'age ,default))) +(eq-eval 'thirty-something '(age *john*)) +(eql-eval 20 '(age *john* 20)) +(eql-eval 25 '(setf (age *john*) 25)) +(eql-eval 25 '(age *john*)) +(eql-eval 25 '(age *john* 20)) + +;; graphic-char-p - function +(eq-test t #'graphic-char-p #\a) +(eq-test t #'graphic-char-p #\Space) +(eq-test nil #'graphic-char-p #\Newline) +(eq-test nil #'graphic-char-p #\Tab) +(eq-test nil #'graphic-char-p #\Rubout) + +;; if - special operator +(eq-eval nil '(if nil t)) +(eq-eval nil '(if t nil t)) +(eq-eval nil '(if nil t nil)) +(eq-eval nil '(if nil t (if nil (if nil t) nil))) + +;; incf - macro +(setq n 1) +(eql-eval 2 '(incf n)) +(eql-eval 2 'n) +(setq n 2147483647) +(eql-eval 2147483648 '(incf n)) +(eql-eval 2147483648 'n) +(setq n 0) +(eql-eval 0.5d0 '(incf n 0.5d0)) +(eql-eval 0.5d0 'n) +(setq n 1) +(eql-eval 3/2 '(incf n 1/2)) +(eql-eval 3/2 'n) + +;; intersection - function +(setq list1 (list 1 1 2 3 4 'a 'b 'c "A" "B" "C" "d") + list2 (list 1 4 5 'b 'c 'd "a" "B" "c" "D")) +(equal-test '(1 1 4 b c) #'intersection list1 list2) +(equal-test '(1 1 4 b c "B") #'intersection list1 list2 :test 'equal) +(equal-test '(1 1 4 b c "A" "B" "C" "d") + #'intersection list1 list2 :test #'equalp) +(setq list1 (nintersection list1 list2)) +(equal-eval '(1 1 4 b c) 'list1) +(setq list1 (copy-list '((1 . 2) (2 . 3) (3 . 4) (4 . 5)))) +(setq list2 (copy-list '((1 . 3) (2 . 4) (3 . 6) (4 . 8)))) +(equal-test '((2 . 3) (3 . 4)) #'nintersection list1 list2 :key #'cdr) + +;; keywordp - function (predicate) +(eq-test t #'keywordp :test) +(eq-test nil #'keywordp 'test) +(eq-test nil #'keywordp '#:test) +(eq-test nil #'keywordp 1) +(eq-test nil #'keywordp #'keywordp) +(eq-test nil #'keywordp nil) + +;; last - function +(equal-test '(3) #'last '(1 2 3)) +(equal-test '(2 . 3) #'last '(1 2 . 3)) +(eq-test nil #'last nil) +(eql-test () #'last '(1 2 3) 0) +(setq a '(1 . 2)) +(eql-test 2 #'last a 0) +(eq-test a #'last a 1) +(eq-test a #'last a 2) +(eq-test t #'last t) +(equal-test #c(1 2) #'last #c(1 2)) +(equalp-test #(1 2 3) #'last #(1 2 3)) + +;; length - function +(eql-test 3 #'length "abc") +(eql-test 0 #'length nil) +(eql-test 1 #'length '(1 . 2)) +(eql-test 2 #'length #(1 2)) +(error-test #'length #c(1 2)) +(error-test #'length t) + +;; let - special operator +(eql-eval 2 '(setq a 1 b 2)) +(eql-eval 2 '(let ((a 2)) a)) +(eql-eval 1 'a) +(eql-eval 1 '(let ((a 3) (b a)) b)) +(eql-eval 2 'b) + +;; let* - special operator +(setq a 1 b 2) +(eql-eval 2 '(let* ((a 2)) a)) +(eql-eval 1 'a) +(eql-eval 3 '(let* ((a 3) (b a)) b)) +(eql-eval 2 'b) + +;; list - function +(equal-test '(1) #'list 1) +(equal-test '(3 4 a b 4) #'list 3 4 'a (car '(b . c)) (+ 6 -2)) +(eq-test nil #'list) + +;; list-length - function +(eql-test 4 #'list-length '(a b c d)) +(eql-test 3 #'list-length '(a (b c) d)) +(eql-test 0 #'list-length '()) +(eql-test 0 #'list-length nil) +(defun circular-list (&rest elements) + (let ((cycle (copy-list elements))) + (nconc cycle cycle))) +(eq-test nil #'list-length (circular-list 'a 'b)) +(eq-test nil #'list-length (circular-list 'a)) +(eql-test 0 #'list-length (circular-list)) + +;; list* - function +(eql-test 1 #'list* 1) +(equal-test '(a b c . d) #'list* 'a 'b 'c 'd) +(error-test #'list*) +(setq a '(1 2)) +(eq-test a #'list* a) + +;; listp - function (predicate) +(eq-test t #'listp nil) +(eq-test t #'listp '(1 . 2)) +(eq-test nil #'listp t) +(eq-test nil #'listp #'listp) +(eq-test nil #'listp #(1 2)) +(eq-test nil #'listp #c(1 2)) + +;; lower-case-p - function +(eq-test t #'lower-case-p #\a) +(eq-test nil #'lower-case-p #\1) +(eq-test nil #'lower-case-p #\Newline) +(error-test #'lower-case-p 1) + + + +;; TODO make-array (will be rewritten) + + + +;; make-list - function +(equal-test '(nil nil nil) #'make-list 3) +(equal-test '((1 2) (1 2)) #'make-list 2 :initial-element '(1 2)) +(eq-test nil #'make-list 0) +(eq-test nil #'make-list 0 :initial-element 1) + +;; make-package - function +(setq pack1 (make-package "PACKAGE-1" :nicknames '("PACK-1" "PACK1"))) +(setq pack2 (make-package "PACKAGE-2" :nicknames '("PACK-2" "PACK2") :use '("PACK1"))) +(equal-test (list pack2) #'package-used-by-list pack1) +(equal-test (list pack1) #'package-use-list pack2) +(eq-test pack1 #'symbol-package 'pack1::test) +(eq-test pack2 #'symbol-package 'pack2::test) + +;; make-string - function +(equal-test "55555" #'make-string 5 :initial-element #\5) +(equal-test "" #'make-string 0) +(error-test #'make-string 10 :initial-element t) +(error-test #'make-string 10 :initial-element nil) +(error-test #'make-string 10 :initial-element 1) +(eql-test 10 #'length (make-string 10)) + +;; make-symbol - function +(setq a "TEST") +;; This will fail +(eq-test nil #'eq (make-symbol a) (make-symbol a)) +(equal-test a #'symbol-name (make-symbol a)) +(setq temp-string "temp") +(setq temp-symbol (make-symbol temp-string)) +(equal-test temp-string #'symbol-name temp-symbol) +(equal-eval '(nil nil) '(multiple-value-list (find-symbol temp-string))) + +;; makunbound - function +(eq-eval 1 '(setf (symbol-value 'a) 1)) +(eq-test t #'boundp 'a) +(eql-eval 1 'a) +(eq-test 'a #'makunbound 'a) +(eq-test nil #'boundp 'a) +(error-test #'makunbound 1) + +;; mapc - function +(setq dummy nil) +(equal-test '(1 2 3 4) + #'mapc #'(lambda (&rest x) (setq dummy (append dummy x))) + '(1 2 3 4) + '(a b c d e) + '(x y z)) +(equal-eval '(1 a x 2 b y 3 c z) 'dummy) + +;; mapcan - function +(equal-test '(d 4 e 5) + #'mapcan #'(lambda (x y) (if (null x) nil (list x y))) + '(nil nil nil d e) + '(1 2 3 4 5 6)) +(equal-test '(1 3 4 5) + #'mapcan #'(lambda (x) (and (numberp x) (list x))) + '(a 1 b c 3 4 d 5)) + +;; mapcar - function +(equal-test '(1 2 3) #'mapcar #'car '((1 a) (2 b) (3 c))) +(equal-test '(3 4 2 5 6) #'mapcar #'abs '(3 -4 2 -5 -6)) +(equal-test '((a . 1) (b . 2) (c . 3)) #'mapcar #'cons '(a b c) '(1 2 3)) +(equal-test '((1 3 5)) #'mapcar #'list* '(1 2) '(3 4) '((5))) +(equal-test '((1 3 5) (2 4 6)) #'mapcar #'list* '(1 2) '(3 4) '((5) (6))) + +;; mapcon - function +(equal-test '(1 a 2 b (3) c) #'mapcon #'car '((1 a) (2 b) ((3) c))) +(equal-test '((1 2 3 4) (2 3 4) (3 4) (4)) #'mapcon #'list '(1 2 3 4)) + +;; mapl - function +(setq dummy nil) +(equal-test '(1 2 3 4) #'mapl #'(lambda (x) (push x dummy)) '(1 2 3 4)) +(equal-eval '((4) (3 4) (2 3 4) (1 2 3 4)) 'dummy) + +;; maplist - function +(equal-test '((1 2 3 4 1 2 1 2 3) (2 3 4 2 2 3)) + #'maplist #'append '(1 2 3 4) '(1 2) '(1 2 3)) +(equal-test '((foo a b c d) (foo b c d) (foo c d) (foo d)) + #'maplist #'(lambda (x) (cons 'foo x)) '(a b c d)) +(equal-test '(0 0 1 0 1 1 1) + #'maplist #'(lambda (x) (if (member (car x) (cdr x)) 0 1)) '(a b a c d b c)) + +;; member - function +(setq a '(1 2 3)) +(eq-test (cdr a) #'member 2 a) +(setq a '((1 . 2) (3 . 4))) +(eq-test (cdr a) #'member 2 a :test-not #'= :key #'cdr) +(eq-test nil #'member 'e '(a b c d)) +(eq-test nil #'member 1 nil) +(error-test #'member 2 '(1 . 2)) +(setq a '(a b nil c d)) +(eq-test (cddr a) #'member-if #'listp a) +(setq a '(a #\Space 5/3 foo)) +(eq-test (cddr a) #'member-if #'numberp a) +(setq a '(3 6 9 11 . 12)) +(eq-test (cdddr a) #'member-if-not #'zerop a :key #'(lambda (x) (mod x 3))) + +;; multiple-value-bind - macro +(equal-eval '(11 9) '(multiple-value-bind (f r) (floor 130 11) (list f r))) + +;; multiple-value-call - special operator +(equal-eval '(1 / 2 3 / / 2 0.5) + '(multiple-value-call #'list 1 '/ (values 2 3) '/ (values) '/ (floor 2.5))) +(eql-eval 10 '(multiple-value-call #'+ (floor 5 3) (floor 19 4))) + +;; multiple-value-list - macro +(equal-eval '(-1 1) '(multiple-value-list (floor -3 4))) +(eql-eval nil '(multiple-value-list (values))) +(equal-eval '(nil) '(multiple-value-list (values nil))) + +;; multiple-value-prog1 - special operator +(setq temp '(1 2 3)) +(equal-eval temp + '(multiple-value-list + (multiple-value-prog1 + (values-list temp) + (setq temp nil) + (values-list temp)))) + +;; multiple-value-setq - macro +(eql-eval 1 '(multiple-value-setq (quotient remainder) (truncate 3.5d0 2))) +(eql-eval 1 quotient) +(eql-eval 1.5d0 'remainder) +(eql-eval 1 '(multiple-value-setq (a b c) (values 1 2))) +(eql-eval 1 'a) +(eql-eval 2 'b) +(eq-eval nil 'c) +(eql-eval 4 '(multiple-value-setq (a b) (values 4 5 6))) +(eql-eval 4 'a) +(eql-eval 5 'b) +(setq a 1) +(eql-eval nil '(multiple-value-setq (a) (values))) +(eql-eval nil 'a) + +;; nconc - function +(eq-test nil #'nconc) +(setq x '(a b c)) +(setq y '(d e f)) +(equal-test '(a b c d e f) #'nconc x y) +(equal-eval '(a b c d e f) 'x) +(eq-test y #'cdddr x) +(equal-test '(1 . 2) #'nconc (list 1) 2) +(error-test #'nconc 1 2 3) +(equal-eval '(k l m) + '(setq foo (list 'a 'b 'c 'd 'e) + bar (list 'f 'g 'h 'i 'j) + baz (list 'k 'l 'm))) +(equal-test '(a b c d e f g h i j k l m) #'nconc foo bar baz) +(equal-eval '(a b c d e f g h i j k l m) 'foo) +(equal-eval (nthcdr 5 foo) 'bar) +(equal-eval (nthcdr 10 foo) 'baz) +(setq foo (list 'a 'b 'c 'd 'e) + bar (list 'f 'g 'h 'i 'j) + baz (list 'k 'l 'm)) +(equal-eval '(a b c d e f g h i j k l m) '(setq foo (nconc nil foo bar nil baz))) +(equal-eval '(a b c d e f g h i j k l m) 'foo) +(equal-eval (nthcdr 5 foo) 'bar) +(equal-eval (nthcdr 10 foo) 'baz) + +;; notany - function +(eql-test t #'notany #'> '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) +(eql-test t #'notany 'not-used ()) +(eql-test nil #'notany #'characterp #(1 2 3 4 5 #\6 7 8)) + +;; notevery - function +(eql-test nil #'notevery #'< '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) +(eql-test nil #'notevery 'not-used ()) +(eql-test t #'notevery #'numberp #(1 2 3 4 5 #\6 7 8)) + +;; nth - accessor (function) +(eql-test 'foo #'nth 0 '(foo bar baz)) +(eql-test 'bar #'nth 1 '(foo bar baz)) +(eq-test nil #'nth 3 '(foo bar baz)) +(error-test #'nth 0 #c(1 2)) +(error-test #'nth 0 #(1 2)) +(error-test #'nth 0 "test") + +;; nth-value - macro +(equal-eval 'a '(nth-value 0 (values 'a 'b))) +(equal-eval 'b '(nth-value 1 (values 'a 'b))) +(eq-eval nil '(nth-value 2 (values 'a 'b))) +(equal-eval '(3332987528 3332987528 t) + '(multiple-value-list + (let* ((x 83927472397238947423879243432432432) + (y 32423489732) + (a (nth-value 1 (floor x y))) + (b (mod x y))) + (values a b (= a b))))) + +;; nthcdr - function +(eq-test nil #'nthcdr 0 '()) +(eq-test nil #'nthcdr 3 '()) +(equal-test '(a b c) #'nthcdr 0 '(a b c)) +(equal-test '(c) #'nthcdr 2 '(a b c)) +(eq-test () #'nthcdr 4 '(a b c)) +(eql-test 1 #'nthcdr 1 '(0 . 1)) +(error-test #'nthcdr -1 '(1 2)) +(error-test #'nthcdr #\Null '(1 2)) +(error-test #'nthcdr 1 t) +(error-test #'nthcdr 1 #(1 2 3)) + +;; or - macro +(eq-eval nil '(or)) +(setq temp0 nil temp1 10 temp2 20 temp3 30) +(eql-eval 10 '(or temp0 temp1 (setq temp2 37))) +(eql-eval 20 'temp2) +(eql-eval 11 '(or (incf temp1) (incf temp2) (incf temp3))) +(eql-eval 11 'temp1) +(eql-eval 20 temp2) +(eql-eval 30 'temp3) +(eql-eval 11 '(or (values) temp1)) +(eql-eval 11 '(or (values temp1 temp2) temp3)) +(equal-eval '(11 20) '(multiple-value-list (or temp0 (values temp1 temp2)))) +(equal-eval '(20 30) + '(multiple-value-list (or (values temp0 temp1) (values temp2 temp3)))) + +;; packagep - function (predicate) +(eq-test t #'packagep *package*) +(eq-test nil #'packagep 10) +(eq-test t #'packagep (make-package "TEST-PACKAGE")) +(eq-test nil #'packagep 'keyword) +(eq-test t #'packagep (find-package 'keyword)) + +;; pairlis - function +#+xedit ;; order of result may vary +(progn + (equal-test '((one . 1) (two . 2) (three . 3) (four . 19)) + #'pairlis '(one two) '(1 2) '((three . 3) (four . 19))) + (setq keys '(1 2 3) + data '("one" "two" "three") + alist '((4 . "four"))) + (equal-test '((1 . "one") (2 . "two") (3 . "three")) + #'pairlis keys data) + (equal-test '((1 . "one") (2 . "two") (3 . "three") (4 . "four")) + #'pairlis keys data alist) + (equal-eval '(1 2 3) 'keys) + (equal-eval '("one" "two" "three") 'data) + (equal-eval '((4 . "four")) 'alist) + (eq-test nil #'pairlis 1 2) + (error-test #'pairlis '(1 2 3) '(4 5)) +) + +;; pop - macro +(setq stack '(a b c) test stack) +(eq-eval 'a '(pop stack)) +(eq-eval (cdr test) 'stack) +(setq llst '((1 2 3 4)) test (car llst)) +(eq-eval 1 '(pop (car llst))) +(eq-eval (cdr test) '(car llst)) +(error-eval '(pop 1)) +(error-eval '(pop nil)) +;; dotted list +(setq stack (cons 1 2)) +(eq-eval 1 '(pop stack)) +(error-eval '(pop stack)) +;; circular list +(setq stack '#1=(1 . #1#) *print-circle* t) +(eql-eval 1 '(pop stack)) +(eql-eval 1 '(pop stack)) +(eql-eval 1 '(pop (cdr stack))) + +;; position - function +(eql-test 4 #'position #\a "baobab" :from-end t) +(eql-test 2 #'position-if #'oddp '((1) (2) (3) (4)) :start 1 :key #'car) +(eq-test nil #'position 595 '()) +(eq-test 4 #'position-if-not #'integerp '(1 2 3 4 5.0)) +(eql-test 1 #'position (char-int #\1) "0123" :key #'char-int) + +;; prog - macro +(eq-eval nil '(prog () :error)) +(eq-eval 'ok + '(prog ((a 0)) + l1 (if (< a 10) (go l3) (go l2)) + (return 'failed) + l2 (return 'ok) + (return 'failed) + l3 (incf a) (go l1) + (return 'failed) + )) +(setq a 1) +(eq-eval '/= '(prog ((a 2) (b a)) (return (if (= a b) '= '/=)))) + +;; prog* - macro +(setq a 1) +(eq-eval nil '(prog* () :error)) +(eq-eval 'ok + '(prog* ((a 0) (b 0)) + l1 (if (< a 10) (go l3) (go l2)) + (return 'failed) + l2 (if (< b 10) (go l4) (return 'ok)) + (return 'failed) + l3 (incf a) (go l1) + (return 'failed) + l4 (incf b) (setq a 0) (go l1) + (return 'failed) + )) +(eq-eval '= '(prog* ((a 2) (b a)) (return (if (= a b) '= '/=)))) + +;; prog1 - macro +(setq temp 1) +(eql-eval 1 '(prog1 temp (incf temp) (eql-eval 2 'temp) temp)) +(eql-eval 2 'temp) +(eql-eval 2 '(prog1 temp (setq temp nil) (eql-eval nil 'temp) temp)) +(eq-eval nil 'temp) +(eql-eval 1 '(prog1 (values 1 2 3) 4)) +(setq temp (list 'a 'b 'c)) +(eq-eval 'a '(prog1 (car temp) (setf (car temp) 'alpha))) +(equal-eval '(alpha b c) 'temp) +(equal-eval '(1) + '(multiple-value-list (prog1 (values 1 2) (values 4 5)))) + +;; prog2 - macro +(setq temp 1) +(eql-eval 3 '(prog2 (incf temp) (incf temp) (incf temp))) +(eql-eval 4 'temp) +(eql-eval 2 '(prog2 1 (values 2 3 4) 5)) +(equal-eval '(3) + '(multiple-value-list (prog2 (values 1 2) (values 3 4) (values 5 6)))) + +;; progn - special operator +(eq-eval nil '(progn)) +(eql-eval 3 '(progn 1 2 3)) +(equal-eval '(1 2 3) '(multiple-value-list (progn (values 1 2 3)))) +(setq a 1) +(eq-eval 'here '(if a (progn (setq a nil) 'here) (progn (setq a t) 'there))) +(eq-eval nil 'a) + +;; progv - special operator +(makunbound '*x*) ;; make sure it is not bound +(setq *x* 1) +(eql-eval 2 '(progv '(*x*) '(2) *x*)) +(eql-eval 1 '*x*) +(equal-eval '(3 4) + '(let ((*x* 3)) (progv '(*x*) '(4) (list *x* (symbol-value '*x*))))) +(makunbound '*x*) +(defvar *x* 1) +(equal-eval '(4 4) + '(let ((*x* 3)) (progv '(*x*) '(4) (list *x* (symbol-value '*x*))))) +(equal-eval '(4 4) + '(multiple-value-list + (let ((*x* 3)) + (progv '(*x*) '(4) (values-list (list *x* (symbol-value '*x*))))))) + +;; push - macro +(setq llst '(nil)) +(equal-eval '(1) '(push 1 (car llst))) +(equal-eval '((1)) 'llst) +(equal-eval '(1 1) '(push 1 (car llst))) +(equal-eval '((1 1)) 'llst) +(setq x '(a (b c) d)) +(equal-eval '(5 B C) '(push 5 (cadr x))) +(equal-eval '(a (5 b c) d) 'x) + +;; pushnew - macro +(setq x '(a (b c) d)) +(equal-eval '(5 b c) '(pushnew 5 (cadr x))) +(equal-eval '(a (5 b c) d) 'x) +(equal-eval '(5 b c) '(pushnew 'b (cadr x))) +(equal-eval '(a (5 b c) d) 'x) +(setq lst '((1) (1 2) (1 2 3))) +(equal-eval '((2) (1) (1 2) (1 2 3)) '(pushnew '(2) lst)) +(equal-eval '((1) (2) (1) (1 2) (1 2 3)) '(pushnew '(1) lst)) +(equal-eval '((1) (2) (1) (1 2) (1 2 3)) '(pushnew '(1) lst :test 'equal)) +(equal-eval '((1) (2) (1) (1 2) (1 2 3)) '(pushnew '(1) lst :key #'car)) + +;; remove-duplicates - function +(equal-test "aBcD" #'remove-duplicates "aBcDAbCd" :test #'char-equal :from-end t) +(equal-test '(a c b d e) #'remove-duplicates '(a b c b d d e)) +(equal-test '(a b c d e) #'remove-duplicates '(a b c b d d e) :from-end t) +(equal-test '((bar #\%) (baz #\A)) + #'remove-duplicates '((foo #\a) (bar #\%) (baz #\A)) + :test #'char-equal :key #'cadr) +(equal-test '((foo #\a) (bar #\%)) + #'remove-duplicates '((foo #\a) (bar #\%) (baz #\A)) + :test #'char-equal :key #'cadr :from-end t) +(setq tester (list 0 1 2 3 4 5 6)) +(equal-test '(0 4 5 6) #'delete-duplicates tester :key #'oddp :start 1 :end 6) + +;; replace - function +(equal-test "abcd456hij" + #'replace (copy-seq "abcdefghij") "0123456789" :start1 4 :end1 7 :start2 4) +(setq lst (xseq "012345678")) +(equal-test "010123456" #'replace lst lst :start1 2 :start2 0) +(equal-eval "010123456" 'lst) + +;; rest - accessor +(equal-eval '(2) '(rest '(1 2))) +(eql-eval 2 '(rest '(1 . 2))) +(eq-eval nil '(rest '(1))) +(setq *cons* '(1 . 2)) +(equal-eval "two" '(setf (rest *cons*) "two")) +(equal-eval '(1 . "two") '*cons*) + +;; return - macro +(eq-eval nil '(block nil (return) 1)) +(eql-eval 1 '(block nil (return 1) 2)) +(equal-eval '(1 2) '(multiple-value-list (block nil (return (values 1 2)) 3))) +(eql-eval 1 '(block nil (block alpha (return 1) 2))) +(eql-eval 2 '(block alpha (block nil (return 1)) 2)) +(eql-eval 1 '(block nil (block nil (return 1) 2))) + +;; return-from - special operator +(eq-eval nil '(block alpha (return-from alpha) 1)) +(eql-eval 1 '(block alpha (return-from alpha 1) 2)) +(equal-eval '(1 2) + '(multiple-value-list (block alpha (return-from alpha (values 1 2)) 3))) +(eql-eval 2 + '(let ((a 0)) (dotimes (i 10) (incf a) (when (oddp i) (return))) a)) +(eq-eval 'temp '(defun temp (x) (if x (return-from temp ''dummy)) 44)) +(eql-eval 44 '(temp nil)) +(eq-eval 'dummy (temp t)) +(eql-eval 2 (block nil (unwind-protect (return-from nil 1) (return-from nil 2)))) +(error-eval '(funcall (block nil #'(lambda () (return-from nil))))) + +;; reverse - function +(setq str (xseq "abc") test str) +(equal-test "cba" #'reverse str) +(eq-eval test 'str) +(equal-eval "cba" '(setq test (nreverse str))) +(equal-eval "cba" 'test) +(setq l (list 1 2 3) test l) +(equal-eval '(3 2 1) '(setq test (nreverse l))) +(equal-eval '(3 2 1) 'test) + +;; rplac? - function +(eql-eval '*some-list* + '(defparameter *some-list* (list* 'one 'two 'three 'four))) +(equal-eval '(one two three . four) '*some-list*) +(equal-test '(uno two three . four) #'rplaca *some-list* 'uno) +(equal-eval '(uno two three . four) '*some-list*) +(equal-test '(three iv) #'rplacd (last *some-list*) (list 'iv)) +(equal-eval '(uno two three iv) '*some-list*) + +;; search - function +(eql-test 7 #'search "dog" "it's a dog's life") +(eql-test 2 #'search '(0 1) '(2 4 6 1 3 5) :key #'oddp) +(eql-test 8 #'search "foo" "foooobarfooooobarfo" :from-end t) +(eql-test 5 + #'search "123" + (mapcar #'(lambda (x) (+ x (char-code #\0))) + '(1 2 34 3 2 1 2 3 4 3 2 1)) :from-end t + :key #'(lambda (x) (if (integerp x) (code-char x) x))) +(eql-test 0 #'search "abc" "abcd" :from-end t) +(eql-test 3 #'search "bar" "foobar") + +;; set - function +(eql-eval 1 '(setf (symbol-value 'n) 1)) +(eql-test 2 #'set 'n 2) +(eql-test 2 #'symbol-value 'n) +(eql-eval 4 + '(let ((n 3)) + (setq n (+ n 1)) + (setf (symbol-value 'n) (* n 10)) + (set 'n (+ (symbol-value 'n) n)) + n)) +(eql-eval 44 'n) +(defvar *n* 2) +(eql-eval 80 + '(let ((*n* 3)) + (setq *n* (+ *n* 1)) + (setf (symbol-value '*n*) (* *n* 10)) + (set '*n* (+ (symbol-value '*n*) *n*)) + *n*)) +(eql-eval 2 '*n*) +(eq-eval '*even-count* '(defvar *even-count* 0)) +(eq-eval '*odd-count* '(defvar *odd-count* 0)) +(eql-eval 'tally-list + '(defun tally-list (list) + (dolist (element list) + (set (if (evenp element) '*even-count* '*odd-count*) + (+ element (if (evenp element) *even-count* *odd-count*)))))) +(eq-eval nil '(tally-list '(1 9 4 3 2 7))) +(eql-eval 6 '*even-count*) +(eql-eval 20 '*odd-count*) + +;; set-difference - function +(setq lst1 (list "A" "b" "C" "d") lst2 (list "a" "B" "C" "d")) +(equal-test '("A" "b" "C" "d") #'set-difference lst1 lst2) +(equal-test '("A" "b") #'set-difference lst1 lst2 :test 'equal) +(eq-test nil #'set-difference lst1 lst2 :test #'equalp) +(equal-test '("A" "b") #'nset-difference lst1 lst2 :test #'string=) +(setq lst1 '(("a" . "b") ("c" . "d") ("e" . "f")) + lst2 '(("c" . "a") ("e" . "b") ("d" . "a"))) +(equal-test '(("c" . "d") ("e" . "f")) + #'nset-difference lst1 lst2 :test #'string= :key #'cdr) +(equal-eval '(("c" . "a") ("e" . "b") ("d" . "a")) 'lst2) +(equal-test '("banana" "lemon" "rhubarb") + #'set-difference + '("strawberry" "chocolate" "banana" "lemon" "pistachio" "rhubarb") + '(#\c #\w) :test #'(lambda (s c) (find c s))) + +;; set-exclusive-or - function +(setq lst1 (list 1 "a" "b") lst2 (list 1 "A" "b")) +(equal-test '("a" "b" "A" "b") #'set-exclusive-or lst1 lst2) +(equal-test '("a" "A") #'set-exclusive-or lst1 lst2 :test #'equal) +(eq-test nil #'set-exclusive-or lst1 lst2 :test 'equalp) +(equal-test '("a" "b" "A" "b") #'nset-exclusive-or lst1 lst2) +(setq lst1 '(("a" . "b") ("c" . "d") ("e" . "f")) + lst2 '(("c" . "a") ("e" . "b") ("d" . "a"))) +(equal-test '(("c" . "d") ("e" . "f") ("c" . "a") ("d" . "a")) + #'nset-exclusive-or lst1 lst2 :test #'string= :key #'cdr) + +;; setf - macro +(setq x (cons 'a 'b) y (list 1 2 3)) +(equal-eval '(1 x 3) '(setf (car x) 'x (cadr y) (car x) (cdr x) y)) +(equal-eval '(x 1 x 3) 'x) +(equal-eval '(1 x 3) 'y) +(setq x (cons 'a 'b) y (list 1 2 3)) +(eq-eval nil '(psetf (car x) 'x (cadr y) (car x) (cdr x) y)) +(equal-eval '(x 1 a 3) 'x) +(equal-eval '(1 a 3) 'y) +(error-eval '(setf x)) +(error-eval '(psetf x)) + +;; setq - special form +(eql-eval 3 '(setq a 1 b 2 c 3)) +(eql-eval 1 'a) +(eql-eval 2 'b) +(eql-eval 3 'c) +(eql-eval 7 '(setq a (1+ b) b (1+ a) c (+ a b))) +(eql-eval 3 'a) +(eql-eval 4 'b) +(eql-eval 7 'c) +(eq-eval nil '(psetq a 1 b 2 c 3)) +(eql-eval 1 'a) +(eql-eval 2 'b) +(eql-eval 3 'c) +(equal-eval '(2 1) + '(multiple-value-list (let ((a 1) (b 2)) (psetq a b b a) (values a b)))) +(error-eval '(setq x)) +(error-eval '(setq x 1 y)) + +;; some - function +(eq-test t #'some #'= '(1 2 3 4 5) '(5 4 3 2 1)) + +;; sort - function +(setq tester (copy-seq "lkjashd")) +(equal-test "adhjkls" #'sort tester #'char-lessp) +(setq tester (list '(1 2 3) '(4 5 6) '(7 8 9))) +(equal-test '((7 8 9) (4 5 6) (1 2 3)) #'sort tester #'> :key #'car) +(setq tester (list 1 2 3 4 5 6 7 8 9 0)) +(equal-test '(1 3 5 7 9 2 4 6 8 0) + #'stable-sort tester #'(lambda (x y) (and (oddp x) (evenp y)))) +(equalp-test + #((("Kathy" "Chapman") "Editorial") + (("Dick" "Gabriel") "Objects") + (("Gregor" "Kiczales") "Objects") + (("Sandra" "Loosemore") "Compiler") + (("Larry" "Masinter") "Cleanup") + (("David" "Moon") "Objects") + (("Kent" "Pitman") "Conditions") + (("Dick" "Waters") "Iteration") + (("JonL" "White") "Iteration")) + #'sort (setq committee-data + (vector (list (list "JonL" "White") "Iteration") + (list (list "Dick" "Waters") "Iteration") + (list (list "Dick" "Gabriel") "Objects") + (list (list "Kent" "Pitman") "Conditions") + (list (list "Gregor" "Kiczales") "Objects") + (list (list "David" "Moon") "Objects") + (list (list "Kathy" "Chapman") "Editorial") + (list (list "Larry" "Masinter") "Cleanup") + (list (list "Sandra" "Loosemore") "Compiler"))) + #'string-lessp :key #'cadar) +(equalp-eval + #((("Larry" "Masinter") "Cleanup") + (("Sandra" "Loosemore") "Compiler") + (("Kent" "Pitman") "Conditions") + (("Kathy" "Chapman") "Editorial") + (("Dick" "Waters") "Iteration") + (("JonL" "White") "Iteration") + (("Dick" "Gabriel") "Objects") + (("Gregor" "Kiczales") "Objects") + (("David" "Moon") "Objects")) + '(setq committee-data + (stable-sort committee-data #'string-lessp :key #'cadr))) +(error-test #'sort #c(1 2)) + +;; string - function +(setq a "already a string") +(eq-test a #'string a) +(equal-test "ELM" #'string 'elm) +(equal-test "c" #'string #\c) + +;; string-* - function +(eq-test t #'string= "foo" "foo") +(eq-test nil #'string= "foo" "Foo") +(eq-test nil #'string= "foo" "bar") +(eq-test t #'string= "together" "frog" :start1 1 :end1 3 :start2 2) +(eq-test t #'string-equal "foo" "Foo") +(eq-test t #'string= "abcd" "01234abcd9012" :start2 5 :end2 9) +(eql-test 3 #'string< "aaaa" "aaab") +(eql-test 4 #'string>= "aaaaa" "aaaa") +(eql-test 5 #'string-not-greaterp "Abcde" "abcdE") +(eql-test 6 #'string-lessp "012AAAA789" "01aaab6" :start1 3 :end1 7 + :start2 2 :end2 6) +(eq-test nil #'string-not-equal "AAAA" "aaaA") +(error-test #'string= #(1 2 3) '(1 2 3)) +(eql-test 0 #'string< "abcd" "efg") +(eql-test 1 #'string< "abcd" "afg") +(eql-test 0 #'string/= "foo" "baar") +(eql-test nil #'string/= "foobar" "foobar") + +;; string-{upcase,downcase,capitalize} - function +(equal-test "ABCDE" #'string-upcase "abcde") +(equal-test "aBCDe" #'string-upcase "abcde" :start 1 :end 4) +(equal-test "aBCDe" #'nstring-upcase (xseq "abcde") :start 1 :end 4) +(equal-test "DR. LIVINGSTON, I PRESUME?" + #'string-upcase "Dr. Livingston, I presume?") +(equal-test "Dr. LIVINGSTON, I Presume?" + #'string-upcase "Dr. Livingston, I presume?" :start 4 :end 19) +(equal-test "Dr. LIVINGSTON, I Presume?" + #'nstring-upcase (xseq "Dr. Livingston, I presume?") :start 4 :end 19) +(equal-test "Dr. LiVINGston, I presume?" + #'string-upcase "Dr. Livingston, I presume?" :start 6 :end 10) +(equal-test "Dr. LiVINGston, I presume?" + #'nstring-upcase (xseq "Dr. Livingston, I presume?") :start 6 :end 10) +(equal-test "dr. livingston, i presume?" + #'string-downcase "Dr. Livingston, I presume?") +(equal-test "Dr. livingston, i Presume?" + #'string-downcase "Dr. Livingston, I Presume?" :start 1 :end 17) +(equal-test "Dr. livingston, i Presume?" + #'nstring-downcase (xseq "Dr. Livingston, I Presume?") :start 1 :end 17) +(equal-test "Elm 13c Arthur;Fig Don'T" + #'string-capitalize "elm 13c arthur;fig don't") +(equal-test "elm 13C Arthur;Fig Don't" + #'string-capitalize "elm 13c arthur;fig don't" :start 6 :end 21) +(equal-test "elm 13C Arthur;Fig Don't" + #'nstring-capitalize (xseq "elm 13c arthur;fig don't") :start 6 :end 21) +(equal-test " Hello " #'string-capitalize " hello ") +(equal-test " Hello " #'nstring-capitalize (xseq " hello ")) +(equal-test "Occluded Casements Forestall Inadvertent Defenestration" + #'string-capitalize "occlUDeD cASEmenTs FOreSTAll iNADVertent DEFenestraTION") +(equal-test "Don'T!" #'string-capitalize "DON'T!") +(equal-test "Pipe 13a, Foo16c" #'string-capitalize "pipe 13a, foo16c") +(setq str (copy-seq "0123ABCD890a")) +(equal-test "0123AbcD890a" #'nstring-downcase str :start 5 :end 7) +(equal-eval "0123AbcD890a" 'str) +(error-test #'nstring-capitalize 1) +(error-test #'string-capitalize "foobar" :start 4 :end 2) +(equal-test "foobar" #'string-capitalize "foobar" :start 0 :end 0) + +;; string-{,left-,right-}trim - function +(equal-test "kaaak" #'string-trim "abc" "abcaakaaakabcaaa") +#+xedit (equal-test "kaaak" #'nstring-trim "abc" "abcaakaaakabcaaa") +(equal-test "garbanzo beans" + #'string-trim '(#\Space #\Tab #\Newline) " garbanzo beans + ") +#+xedit (equal-test "garbanzo beans" + #'nstring-trim '(#\Space #\Tab #\Newline) " garbanzo beans + ") +(equal-test "three (silly) words" + #'string-trim " (*)" " ( *three (silly) words* ) ") +#+xedit (equal-test "three (silly) words" + #'nstring-trim " (*)" " ( *three (silly) words* ) ") +(equal-test "labcabcabc" #'string-left-trim "abc" "labcabcabc") +#+xedit (equal-test "labcabcabc" #'nstring-left-trim "abc" "labcabcabc") +(equal-test "three (silly) words* ) " + #'string-left-trim " (*)" " ( *three (silly) words* ) ") +#+xedit (equal-test "three (silly) words* ) " + #'nstring-left-trim " (*)" " ( *three (silly) words* ) ") +(equal-test " ( *three (silly) words" + #'string-right-trim " (*)" " ( *three (silly) words* ) ") +#+xedit (equal-test " ( *three (silly) words" + #'nstring-right-trim " (*)" " ( *three (silly) words* ) ") +(error-test #'string-trim 123 "123") +(error-test #'string-left-trim 123 "123") + +;; stringp - function (predicate) +(eq-test t #'stringp "abc") +(eq-test nil #'stringp #\a) +(eq-test nil #'stringp 1) +(eq-test nil #'stringp #(#\a #\b #\c)) + +;; subseq - accessor +(setq str (xseq "012345")) +(equal-test "2345" #'subseq str 2) +(equal-test "34" #'subseq str 3 5) +(equal-eval "abc" '(setf (subseq str 4) "abc")) +(equal-eval "0123ab" 'str) +(equal-eval "A" '(setf (subseq str 0 2) "A")) +(equal-eval "A123ab" 'str) + +;; subsetp - function +(setq cosmos '(1 "a" (1 2))) +(eq-test t #'subsetp '(1) cosmos) +(eq-test nil #'subsetp '((1 2)) cosmos) +(eq-test t #'subsetp '((1 2)) cosmos :test 'equal) +(eq-test t #'subsetp '(1 "A") cosmos :test #'equalp) +(eq-test nil #'subsetp '((1) (2)) '((1) (2))) +(eq-test t #'subsetp '((1) (2)) '((1) (2)) :key #'car) + +;; svref - function +;; XXX vectors will be reimplemented, just a test for the current implementation +(setq v (vector 1 2 'sirens)) +(eql-eval 1 '(svref v 0)) +(eql-eval 'sirens '(svref v 2)) +(eql-eval 'newcomer '(setf (svref v 1) 'newcomer)) +(equalp-eval #(1 newcomer sirens) 'v) + +;; symbol-name - function +(equal-test "TEMP" #'symbol-name 'temp) +(equal-test "START" #'symbol-name :start) +(error-test #'symbol-name 1) + +;; symbol-package - function +(eq-test (find-package "LISP") #'symbol-package 'car) +(eql-test *package* #'symbol-package 'bus) +(eq-test (find-package "KEYWORD") #'symbol-package :optional) +;; Gensyms are uninterned, so have no home package. +(eq-test nil #'symbol-package (gensym)) +(setq pk1 (make-package 'pk1)) +(intern "SAMPLE1" "PK1") +(eq-eval t '(export (find-symbol "SAMPLE1" "PK1") "PK1")) +(setq pk2 (make-package 'pk2 :use '(pk1))) +(equal-eval '(pk1:sample1 :inherited) + '(multiple-value-list (find-symbol "SAMPLE1" "PK2"))) +(eq-test pk1 #'symbol-package 'pk1::sample1) +(eq-test pk1 #'symbol-package 'pk2::sample1) +(eq-test pk1 #'symbol-package 'pk1::sample2) +(eq-test pk2 #'symbol-package 'pk2::sample2) +;; The next several forms create a scenario in which a symbol +;; is not really uninterned, but is "apparently uninterned", +;; and so SYMBOL-PACKAGE still returns NIL. +(setq s3 'pk1::sample3) +(eq-eval t '(import s3 'pk2)) +(eq-eval t '(unintern s3 'pk1)) ;; XXX unintern not yet implemented +(eq-test nil #'symbol-package s3) ;; fail due to unintern not implemented +(eq-test t #'eq s3 'pk2::sample3) + +;; symbol-plist - accessor +(setq sym (gensym)) +(eq-eval () '(symbol-plist sym)) +(eq-eval 'val1 '(setf (get sym 'prop1) 'val1)) +(equal-eval '(prop1 val1) '(symbol-plist sym)) +(eq-eval 'val2 '(setf (get sym 'prop2) 'val2)) +(equal-eval '(prop2 val2 prop1 val1) '(symbol-plist sym)) +(setq sym-plist (list 'prop3 'val3)) +(eq-eval sym-plist '(setf (symbol-plist sym) sym-plist)) +(eq-eval sym-plist '(symbol-plist sym)) + +;; symbol-value - accessor +(eql-eval 1 '(setf (symbol-value 'a) 1)) +(eql-eval 1 '(symbol-value 'a)) +;; SYMBOL-VALUE cannot see lexical variables. +(eql-eval 1 '(let ((a 2)) (symbol-value 'a))) +(eql-eval 1 '(let ((a 2)) (setq a 3) (symbol-value 'a))) + +#+xedit ;; incorrect... +(progn + ;; SYMBOL-VALUE can see dynamic variables. + ;; declare not yet implemented + (proclaim '(special a)) + (eql-eval 2 '(let ((a 2)) (symbol-value 'a))) + (eql-eval 1 'a) + (eql-eval 3 '(let ((a 2)) (setq a 3) (symbol-value 'a))) + (eql-eval 1 'a) + ;; declare not yet implement + (makunbound 'a) + (eql-eval 2 '(let ((a 2)) (setf (symbol-value 'a) 3) a)) + (eql-eval 3 'a) + (eql-eval 3 '(symbol-value 'a)) + ;; declare not yet implement + (makunbound 'a) + (equal-eval '(5 4) + '(multiple-value-list + (let ((a 4)) + + ;; declare not yet implemented + (defparameter a 3) + + (let ((b (symbol-value 'a))) + (setf (symbol-value 'a) 5) + (values a b))))) + (eql-eval 3 'a) +) +(eq-eval :any-keyword '(symbol-value :any-keyword)) +;; XXX these will fail +(eq-eval nil '(symbol-value 'nil)) +(eq-eval nil '(symbol-value '())) + +;; symbolp - function (predicate) +(eq-test t #'symbolp 'elephant) +(eq-test nil #'symbolp 12) +;; XXX these will fail +(eq-test t #'symbolp nil) +(eq-test t #'symbolp '()) +(eq-test t #'symbolp :test) +(eq-test nil #'symbolp "hello") + +;; remprop - function +(setq test (make-symbol "PSEUDO-PI")) +(eq-eval () '(symbol-plist test)) +(eq-eval t '(setf (get test 'constant) t)) +(eql-eval 3.14 '(setf (get test 'approximation) 3.14)) +(eql-eval 'noticeable '(setf (get test 'error-range) 'noticeable)) +(equal-eval '(error-range noticeable approximation 3.14 constant t) + '(symbol-plist test)) +(eq-eval nil '(setf (get test 'approximation) nil)) +(equal-eval '(error-range noticeable approximation nil constant t) + '(symbol-plist test)) +(eq-eval nil (get test 'approximation)) +(eq-test t #'remprop test 'approximation) +(eq-eval nil '(get test 'approximation)) +(equal-eval '(error-range noticeable constant t) '(symbol-plist test)) +(eq-test nil #'remprop test 'approximation) +(equal-eval '(error-range noticeable constant t) '(symbol-plist test)) +(eq-test t #'remprop test 'error-range) +(eql-eval 3 '(setf (get test 'approximation) 3)) +(equal-eval '(approximation 3 constant t) '(symbol-plist test)) + +;; throw - special operator +(equal-eval '(3 9) + '(multiple-value-list + (catch 'result + (setq i 0 j 0) + (loop (incf j 3) (incf i) + (if (= i 3) (throw 'result (values i j))))))) +(eql-eval 2 '(catch nil (unwind-protect (throw nil 1) (throw nil 2)))) + +;; XXX undefined consequences +(eql-eval 2 + '(catch 'a + (catch 'b + (unwind-protect (throw 'a 1) + (throw 'b 2))))) +(eq-eval :outer-catch + '(catch 'foo + (setq string (format nil "The inner catch returns ~s." + (catch 'foo + (unwind-protect (throw 'foo :first-throw) + (throw 'foo :second-throw))))) + :outer-catch)) +(equal-eval "The inner catch returns :SECOND-THROW." 'string) + +;; tree-equal - function +(setq tree1 '(1 (1 2)) + tree2 '(1 (1 2))) +(eq-test t #'tree-equal tree1 tree2) +(eq-test nil #'eql tree1 tree2) +(setq tree1 '('a ('b 'c)) + tree2 '('a ('b 'c))) +(eq-test t #'tree-equal tree1 tree2 :test 'eq) +(eq-test t #'tree-equal 1 1) +(eq-test nil #'tree-equal (list 1 2) (cons 1 2)) +(eq-test nil #'tree-equal 1 2) + +;; union - function +(equal-test '(b c f a d) #'union '(a b c) '(f a d)) +(equal-test '((y 6) (z 2) (x 4)) + #'union '((x 5) (y 6)) '((z 2) (x 4)) :key #'car) +(setq lst1 (list 1 2 '(1 2) "a" "b") + lst2 (list 2 3 '(2 3) "B" "C")) +(equal-test '(1 (1 2) "a" "b" 2 3 (2 3) "B" "C") #'nunion lst1 lst2) + +;; unless - macro +(eq-eval 'hello '(when t 'hello)) +(eq-eval nil '(unless t 'hello)) +(eq-eval nil (when nil 'hello)) +(eq-eval 'hello '(unless nil 'hello)) +(eq-eval nil (when t)) +(eql-eval nil '(unless nil)) +(setq test nil) +(equal-eval '(3 2 1) '(when t (push 1 test) (push 2 test) (push 3 test))) +(equal-eval '(3 2 1) 'test) +(setq test nil) +(eq-eval nil '(unless t (push 1 test) (push 2 test) (push 3 test))) +(eq-eval nil 'test) +(eq-eval nil '(when nil (push 1 test) (push 2 test) (push 3 test))) +(eq-eval nil 'test) +(equal-eval '(3 2 1) '(unless nil (push 1 test) (push 2 test) (push 3 test))) +(equal-eval '(3 2 1) 'test) +(equal-eval '((4) nil (5) nil 6 (6) 7 (7)) + '(let ((x 3)) + (list (when (oddp x) (incf x) (list x)) + (when (oddp x) (incf x) (list x)) + (unless (oddp x) (incf x) (list x)) + (unless (oddp x) (incf x) (list x)) + (if (oddp x) (incf x) (list x)) + (if (oddp x) (incf x) (list x)) + (if (not (oddp x)) (incf x) (list x)) + (if (not (oddp x)) (incf x) (list x))))) + +;; unwind-protect - special operator +(defun dummy-function (x) + (setq state 'running) + (unless (numberp x) (throw 'abort 'not-a-number)) + (setq state (1+ x))) +(eql-eval 2 '(catch 'abort (dummy-function 1))) +(eql-eval 2 'state) +(eq-eval 'not-a-number '(catch 'abort (dummy-function 'trash))) +(eq-eval 'running 'state) +(eq-eval 'not-a-number + '(catch 'abort (unwind-protect (dummy-function 'trash) + (setq state 'aborted)))) +(eq-eval 'aborted 'state) +(eql-eval 2 '(block nil (unwind-protect (return 1) (return 2)))) +;; XXX undefined consequences +(eql-eval 2 + '(block a + (block b + (unwind-protect (return-from a 1) + (return-from b 2))))) +(eql-eval 2 '(catch nil (unwind-protect (throw nil 1) (throw nil 2)))) +;; XXX undefined consequences +(eql-eval 2 + '(catch 'a (catch 'b (unwind-protect (throw 'a 1) (throw 'b 2))))) +(eq-eval ':outer-catch + '(catch 'foo + (setq string + (format nil "The inner catch returns ~s." + (catch 'foo + (unwind-protect (throw 'foo :first-throw) + (throw 'foo :second-throw))))) + :outer-catch)) +(equal-eval "The inner catch returns :SECOND-THROW." 'string) +(eql-eval 10 + '(catch 'a + (catch 'b + (unwind-protect (1+ (catch 'a (throw 'b 1))) + (throw 'a 10))))) +;; XXX undefined consequences +(eql-eval 4 + '(catch 'foo + (catch 'bar + (unwind-protect (throw 'foo 3) + (throw 'bar 4) + (print 'xxx))))) +(eql-eval 4 + '(catch 'bar + (catch 'foo + (unwind-protect (throw 'foo 3) + (throw 'bar 4) + (print 'xxx))))) +(eql-eval 5 + '(block nil + (let ((x 5)) + (unwind-protect (return) + (return x))))) + +;; upper-case-p - function +(eq-test t #'upper-case-p #\A) +(eq-test nil #'upper-case-p #\a) +(eq-test nil #'upper-case-p #\5) +(error-test #'upper-case-p 1) + +;; values - accessor +(eq-eval () '(multiple-value-list (values))) +(equal-eval '(1) '(multiple-value-list (values 1))) +(equal-eval '(1 2) '(multiple-value-list (values 1 2))) +(equal-eval '(1 2 3) '(multiple-value-list (values 1 2 3))) +(equal-eval '(1 4 5) '(multiple-value-list (values (values 1 2 3) 4 5))) + +;; values-list - function +(eq-eval nil '(multiple-value-list (values-list nil))) +(equal-eval '(1) '(multiple-value-list (values-list '(1)))) +(equal-eval '(1 2) '(multiple-value-list (values-list '(1 2)))) +(equal-eval '(1 2 3) '(multiple-value-list (values-list '(1 2 3)))) |