comparison lisp/cl-extra.el @ 5475:248176c74e6b

Merge with trunk.
author Mats Lidell <matsl@xemacs.org>
date Sat, 23 Apr 2011 23:47:13 +0200
parents 0af042a0c116 aa78b0b0b289
children f2881cb841b4
comparison
equal deleted inserted replaced
5474:4dee0387b9de 5475:248176c74e6b
360 360
361 (defun random-state-p (object) 361 (defun random-state-p (object)
362 "Return t if OBJECT is a random-state object." 362 "Return t if OBJECT is a random-state object."
363 (and (vectorp object) (= (length object) 4) 363 (and (vectorp object) (= (length object) 4)
364 (eq (aref object 0) 'cl-random-state-tag))) 364 (eq (aref object 0) 'cl-random-state-tag)))
365
366
367 ;; Implementation limits.
368
369 (defun cl-finite-do (func a b)
370 (condition-case nil
371 (let ((res (funcall func a b))) ; check for IEEE infinity
372 (and (numberp res) (/= res (/ res 2)) res))
373 (arith-error nil)))
374
375 (defun cl-float-limits ()
376 (or most-positive-float (not (numberp '2e1))
377 (let ((x '2e0) y z)
378 ;; Find maximum exponent (first two loops are optimizations)
379 (while (cl-finite-do '* x x) (setq x (* x x)))
380 (while (cl-finite-do '* x (/ x 2)) (setq x (* x (/ x 2))))
381 (while (cl-finite-do '+ x x) (setq x (+ x x)))
382 (setq z x y (/ x 2))
383 ;; Now fill in 1's in the mantissa.
384 (while (and (cl-finite-do '+ x y) (/= (+ x y) x))
385 (setq x (+ x y) y (/ y 2)))
386 (setq most-positive-float x
387 most-negative-float (- x))
388 ;; Divide down until mantissa starts rounding.
389 (setq x (/ x z) y (/ 16 z) x (* x y))
390 (while (condition-case nil (and (= x (* (/ x 2) 2)) (> (/ y 2) 0))
391 (arith-error nil))
392 (setq x (/ x 2) y (/ y 2)))
393 (setq least-positive-normalized-float y
394 least-negative-normalized-float (- y))
395 ;; Divide down until value underflows to zero.
396 (setq x (/ 1 z) y x)
397 (while (condition-case nil (> (/ x 2) 0) (arith-error nil))
398 (setq x (/ x 2)))
399 (setq least-positive-float x
400 least-negative-float (- x))
401 (setq x '1e0)
402 (while (/= (+ '1e0 x) '1e0) (setq x (/ x 2)))
403 (setq float-epsilon (* x 2))
404 (setq x '1e0)
405 (while (/= (- '1e0 x) '1e0) (setq x (/ x 2)))
406 (setq float-negative-epsilon (* x 2))))
407 nil)
408
409 ;; XEmacs; call cl-float-limits at dump time.
410 (cl-float-limits)
411 365
412 ;;; Sequence functions. 366 ;;; Sequence functions.
413 367
414 ;; XEmacs; #'subseq is in C. 368 ;; XEmacs; #'subseq is in C.
415 369
689 ;; XEmacs addition; force cl-macs to be available from here on when 643 ;; XEmacs addition; force cl-macs to be available from here on when
690 ;; compiling files to be dumped. This is more reasonable than forcing other 644 ;; compiling files to be dumped. This is more reasonable than forcing other
691 ;; files to do the same, multiple times. 645 ;; files to do the same, multiple times.
692 (eval-when-compile (or (cl-compiling-file) (load "cl-macs"))) 646 (eval-when-compile (or (cl-compiling-file) (load "cl-macs")))
693 647
648 ;; Implementation limits.
649
650 ;; XEmacs; call cl-float-limits at dump time.
651 (labels
652 ((cl-finite-do (func a b)
653 (condition-case nil
654 (let ((res (funcall func a b))) ; check for IEEE infinity
655 (and (numberp res) (/= res (/ res 2)) res))
656 (arith-error nil)))
657 (cl-float-limits ()
658 (unless most-positive-float
659 (let ((x 2e0) y z)
660 ;; Find maximum exponent (first two loops are optimizations)
661 (while (cl-finite-do '* x x) (setq x (* x x)))
662 (while (cl-finite-do '* x (/ x 2)) (setq x (* x (/ x 2))))
663 (while (cl-finite-do '+ x x) (setq x (+ x x)))
664 (setq z x y (/ x 2))
665 ;; Now fill in 1's in the mantissa.
666 (while (and (cl-finite-do '+ x y) (/= (+ x y) x))
667 (setq x (+ x y) y (/ y 2)))
668 (setq most-positive-float x
669 most-negative-float (- x))
670 ;; Divide down until mantissa starts rounding.
671 (setq x (/ x z) y (/ 16 z) x (* x y))
672 (while (condition-case nil (and (= x (* (/ x 2) 2)) (> (/ y 2) 0))
673 (arith-error nil))
674 (setq x (/ x 2) y (/ y 2)))
675 (setq least-positive-normalized-float y
676 least-negative-normalized-float (- y))
677 ;; Divide down until value underflows to zero.
678 (setq x (/ 1 z) y x)
679 (while (condition-case nil (> (/ x 2) 0) (arith-error nil))
680 (setq x (/ x 2)))
681 (setq least-positive-float x
682 least-negative-float (- x))
683 (setq x 1e0)
684 (while (/= (+ 1e0 x) 1e0) (setq x (/ x 2)))
685 (setq float-epsilon (* x 2))
686 (setq x 1e0)
687 (while (/= (- 1e0 x) 1e0) (setq x (/ x 2)))
688 (setq float-negative-epsilon (* x 2))))))
689 (cl-float-limits))
690
691 ;; No type-checking here, we should add it.
692 (defalias 'char< '<)
693 (defalias 'char>= '>=)
694 (defalias 'char> '>)
695 (defalias 'char<= '<=)
696
697 ;;; Character functions.
698 (defun* digit-char-p (character &optional (radix 10))
699 "Return non-nil if CHARACTER represents a digit in base RADIX.
700
701 RADIX defaults to ten. The actual non-nil value returned is the integer
702 value of the character in base RADIX."
703 (check-type character character)
704 (check-type radix integer)
705 (if (<= radix 10)
706 (and (<= ?0 character (+ ?0 radix -1)) (- character ?0))
707 (or (and (<= ?0 character ?9) (- character ?0))
708 (and (<= ?a character (+ ?a (setq radix (- radix 11))))
709 (+ character (- 10 ?a)))
710 (and (<= ?A character (+ ?A radix))
711 (+ character (- 10 ?A))))))
712
713 (defun* digit-char (weight &optional (radix 10))
714 "Return a character representing the integer WEIGHT in base RADIX.
715
716 RADIX defaults to ten. If no such character exists, return nil."
717 (check-type weight integer)
718 (check-type radix integer)
719 (and (natnump weight) (< weight radix)
720 (if (< weight 10)
721 (int-char (+ ?0 weight))
722 (int-char (+ ?A (- weight 10))))))
723
724 (defun alpha-char-p (character)
725 "Return t if CHARACTER is alphabetic, in some alphabet.
726
727 Han characters are regarded as alphabetic."
728 (check-type character character)
729 (and (eql ?w (char-syntax character (standard-syntax-table)))
730 (not (<= ?0 character ?9))))
731
732 (defun graphic-char-p (character)
733 "Return t if CHARACTER is not a control character.
734
735 Control characters are those in the range ?\\x00 to ?\\x15 and ?\\x7f to
736 ?\\x9f, inclusive."
737 (check-type character character)
738 (not (or (<= ?\x00 character ?\x1f) (<= ?\x7f character ?\x9f))))
739
740 (defun standard-char-p (character)
741 "Return t if CHARACTER is one of Common Lisp's standard characters.
742
743 These are the non-control ASCII characters, plus the newline character."
744 (check-type character character)
745 (or (<= ?\x20 character ?\x7e) (eql character ?\n)))
746
747 (symbol-macrolet
748 ((names '((?\x08 . "Backspace") (?\x09 . "Tab") (?\x0a . "Newline")
749 (?\x0C . "Page") (?\x0d . "Return") (?\x20 . "Space")
750 (?\x7f . "Rubout"))))
751
752 (defun char-name (character)
753 "Return a string naming CHARACTER.
754
755 For the limited number of characters where the character name has been
756 specified by Common Lisp, this always returns the appropriate string
757 name. Otherwise, `char-name' requires that the Unicode database be
758 available; see `describe-char-unicode-data'."
759 (check-type character character)
760 (or (cdr (assq character names))
761 (let ((unicode-data
762 (assoc "Name" (describe-char-unicode-data character))))
763 (and unicode-data
764 (if (string-match "^<[^>]+>$" (cadr unicode-data))
765 (format "U%04X" (char-to-unicode character))
766 (replace-in-string (cadr unicode-data) " " "_" t))))))
767
768 (defun name-char (name)
769 "Return a character with name NAME, a string."
770 (or (car (rassoc* name names :test #'equalp))
771 (if (string-match "^[uU][0-9A-Fa-f]+$" name)
772 (unicode-to-char (string-to-number (subseq name 1) 16))
773 (with-current-buffer (get-buffer-create " *Unicode Data*")
774 (require 'descr-text)
775 (when (zerop (buffer-size))
776 ;; Don't use -literally in case of DOS line endings.
777 (insert-file-contents describe-char-unicodedata-file))
778 (goto-char (point-min))
779 (setq case-fold-search nil)
780 (and (re-search-forward (format #r"^\([0-9A-F]\{4,6\}\);%s;"
781 (upcase (replace-in-string
782 name "_" " " t))) nil t)
783 (unicode-to-char (string-to-number (match-string 1) 16))))))))
784
785 (defun upper-case-p (character)
786 "Return t if CHARACTER is majuscule in the standard case table."
787 (and (stringp character) (check-type character character))
788 (with-case-table (standard-case-table)
789 (not (eq character (downcase character)))))
790
791 (defun lower-case-p (character)
792 "Return t if CHARACTER is minuscule in the standard case table."
793 (and (stringp character) (check-type character character))
794 (with-case-table (standard-case-table)
795 (not (eq character (upcase character)))))
796
797 (defun both-case-p (character)
798 "Return t if CHARACTER has case information in the standard case table."
799 (and (stringp character) (check-type character character))
800 (with-case-table (standard-case-table)
801 (or (not (eq character (upcase character)))
802 (not (eq character (downcase character))))))
803
804 (defun char-upcase (character)
805 "If CHARACTER is lowercase, return its corresponding uppercase character.
806 Otherwise, return CHARACTER."
807 (and (stringp character) (check-type character character))
808 (with-case-table (standard-case-table) (upcase character)))
809
810 (defun char-downcase (character)
811 "If CHARACTER is uppercase, return its corresponding lowercase character.
812 Otherwise, return CHARACTER."
813 (and (stringp character) (check-type character character))
814 (with-case-table (standard-case-table) (downcase character)))
815
816 (defun integer-length (integer)
817 "Return the number of bits need to represent INTEGER in two's complement."
818 (ecase (signum integer)
819 (0 0)
820 (-1 (1- (length (format "%b" (- integer)))))
821 (1 (length (format "%b" integer)))))
822
694 (run-hooks 'cl-extra-load-hook) 823 (run-hooks 'cl-extra-load-hook)
695 824
696 ;; XEmacs addition 825 ;; XEmacs addition
697 (provide 'cl-extra) 826 (provide 'cl-extra)
698 827