# HG changeset patch # User Ben Wing # Date 1264574279 21600 # Node ID c27efc9acb5a1db58c69b0bcc6f5ff8ffe0a6f14 # Parent a47abe9c47f28f7159e2f31f89b149f27d4fdff6# Parent 1e9078742fa76495611106450c7bc1270e5b6455 merge diff -r a47abe9c47f2 -r c27efc9acb5a lisp/ChangeLog --- a/lisp/ChangeLog Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/ChangeLog Wed Jan 27 00:37:59 2010 -0600 @@ -5,6 +5,44 @@ * mule/cyrillic.el (koi8-c): Correct the mapping here, #x8C is actually ?\u04D9. Add a case mapping for it. +2010-01-24 Aidan Kehoe + + Correct the semantics of #'member*, #'eql, #'assoc* in the + presence of bignums; change the integerp byte code to fixnump + semantics. + + * bytecomp.el (fixnump, integerp, byte-compile-integerp): + Change the integerp byte code to fixnump; add a byte-compile + method to integerp using fixnump and numberp and avoiding a + funcall most of the time, since in the non-core contexts where + integerp is used, it's mostly distinguishing between fixnums and + things that are not numbers at all. + * byte-optimize.el (side-effect-free-fns, byte-after-unbind-ops) + (byte-compile-side-effect-and-error-free-ops): + Replace the integerp bytecode with fixnump; add fixnump to the + side-effect-free-fns. Add the other extended number type + predicates to the list in passing. + + * obsolete.el (floatp-safe): Mark this as obsolete. + + * cl.el (eql): Go into more detail in the docstring here. Don't + bother checking whether both arguments are numbers; one is enough, + #'equal will fail correctly if they have distinct types. + (subst): Replace a call to #'integerp (deciding whether to use + #'memq or not) with one to #'fixnump. + Delete most-positive-fixnum, most-negative-fixnum from this file; + they're now always in C, so they can't be modified from Lisp. + * cl-seq.el (member*, assoc*, rassoc*): + Correct these functions in the presence of bignums. + * cl-macs.el (cl-make-type-test): The type test for a fixnum is + now fixnump. Ditch floatp-safe, use floatp instead. + (eql): Correct this compiler macro in the presence of bignums. + (assoc*): Correct this compiler macro in the presence of bignums. + + * simple.el (undo): + Change #'integerp to #'fixnump here, since we use #'delq with the + same value as ELT a few lines down. + 2010-01-20 Aidan Kehoe * simple.el (handle-pre-motion-command-current-command-is-motion): diff -r a47abe9c47f2 -r c27efc9acb5a lisp/byte-optimize.el --- a/lisp/byte-optimize.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/byte-optimize.el Wed Jan 27 00:37:59 2010 -0600 @@ -1209,12 +1209,12 @@ (let ((side-effect-free-fns '(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan assoc assq - boundp buffer-file-name buffer-local-variables buffer-modified-p - buffer-substring + bigfloat-get-precision boundp buffer-file-name buffer-local-variables + buffer-modified-p buffer-substring capitalize car-less-than-car car cdr ceiling concat ;; coordinates-in-window-p not in XEmacs copy-marker cos count-lines - default-boundp default-value documentation downcase + default-boundp default-value denominator documentation downcase elt exp expt fboundp featurep file-directory-p file-exists-p file-locked-p file-name-absolute-p file-newer-than-file-p file-readable-p file-symlink-p file-writable-p @@ -1233,7 +1233,7 @@ int-to-string length log log10 logand logb logior lognot logxor lsh marker-buffer max member memq min mod - next-window nth nthcdr number-to-string + next-window nth nthcdr number-to-string numerator parse-colon-path plist-get previous-window radians-to-degrees rassq regexp-quote reverse round sin sqrt string< string= string-equal string-lessp string-to-char @@ -1252,7 +1252,8 @@ )) (side-effect-and-error-free-fns '(arrayp atom - bobp bolp buffer-end buffer-list buffer-size buffer-string bufferp + bigfloatp bignump bobp bolp buffer-end buffer-list buffer-size + buffer-string bufferp car-safe case-table-p cdr-safe char-or-string-p char-table-p characterp commandp cons consolep console-live-p consp @@ -1260,7 +1261,7 @@ ;; XEmacs: extent functions, frame-live-p, various other stuff devicep device-live-p dot dot-marker eobp eolp eq eql equal eventp extentp - extent-live-p floatp framep frame-live-p + extent-live-p fixnump floatingp floatp framep frame-live-p get-largest-window get-lru-window hash-table-p identity ignore integerp integer-or-marker-p interactive-p @@ -1271,14 +1272,14 @@ natnump nlistp not null number-or-marker-p numberp one-window-p ;; overlayp not in XEmacs point point-marker point-min point-max processp - range-table-p + rationalp ratiop range-table-p realp selected-window sequencep stringp subrp symbolp syntax-table-p user-full-name user-login-name user-original-login-name user-real-login-name user-real-uid user-uid vector vectorp window-configuration-p window-live-p windowp ;; Functions defined by cl - eql floatp-safe list* subst acons equalp random-state-p + eql list* subst acons equalp random-state-p copy-tree sublis ))) (dolist (fn side-effect-free-fns) @@ -1456,7 +1457,7 @@ (defconst byte-after-unbind-ops '(byte-constant byte-dup - byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp + byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-fixnump byte-eq byte-not byte-cons byte-list1 byte-list2 ; byte-list3 byte-list4 byte-interactive-p) @@ -1469,7 +1470,7 @@ (defconst byte-compile-side-effect-and-error-free-ops '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp - byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe + byte-fixnump byte-numberp byte-eq byte-equal byte-not byte-car-safe byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max byte-point-min byte-following-char byte-preceding-char byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp diff -r a47abe9c47f2 -r c27efc9acb5a lisp/bytecomp.el --- a/lisp/bytecomp.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/bytecomp.el Wed Jan 27 00:37:59 2010 -0600 @@ -734,7 +734,7 @@ (byte-defop 165 -1 byte-quo) (byte-defop 166 -1 byte-rem) (byte-defop 167 0 byte-numberp) -(byte-defop 168 0 byte-integerp) +(byte-defop 168 0 byte-fixnump) ;; unused: 169 @@ -3101,7 +3101,7 @@ (byte-defop-compiler car-safe 1) (byte-defop-compiler cdr-safe 1) (byte-defop-compiler numberp 1) -(byte-defop-compiler integerp 1) +(byte-defop-compiler fixnump 1) (byte-defop-compiler skip-chars-forward 1-2+1) (byte-defop-compiler skip-chars-backward 1-2+1) (byte-defop-compiler (eql byte-eq) 2) @@ -3817,6 +3817,8 @@ (byte-defop-compiler-1 let) (byte-defop-compiler-1 let*) +(byte-defop-compiler-1 integerp) + (defun byte-compile-progn (form) (byte-compile-body-do-effect (cdr form))) @@ -3999,6 +4001,55 @@ (byte-compile-warn-about-unused-variables)) (byte-compile-out 'byte-unbind (length (car (cdr form)))))) +;; We've renamed the integerp bytecode to fixnump, and changed its semantics +;; accordingly. This means #'integerp itself can't be as fast as it used to +;; be, since it no longer has a bytecode to itself. As it happens, though, +;; most of the non-core calls to #'integerp are in contexts where it is +;; either going to receive a fixnum, or something non-numeric entirely; the +;; contexts where it needs to distinguish between an integer and a float are +;; very rare. So, we can have (integerp X) compile to: +;; +;; (or (fixnump X) (and (numberp X) (funcall #'integerp X))) +;; +;; without the multiple evaluation of X, and where #'fixnump and #'numberp +;; both have bytecodes. We ignore for-effect, because byte-optimize.el will +;; delete this call in its presence. +;; +;; This approach is byte-code compatible with 21.4 and with earlier 21.5 +;; (except that earlier 21.5 with bignum support will confuse Bfixnump and +;; Bintegerp; which it did in dealing with byte-compiled code from 21.4 +;; anyway). + +(defun byte-compile-integerp (form) + (if (/= 2 (length form)) + (byte-compile-subr-wrong-args form 1) + (let ((donetag (byte-compile-make-tag)) + (wintag (byte-compile-make-tag)) + (failtag (byte-compile-make-tag))) + (byte-compile-constant 'integerp) + (byte-compile-form (second form)) + (byte-compile-out 'byte-dup 0) + (byte-compile-out 'byte-fixnump 0) + (byte-compile-goto 'byte-goto-if-not-nil wintag) + (byte-compile-out 'byte-dup 0) + (byte-compile-out 'byte-numberp 0) + (byte-compile-goto 'byte-goto-if-nil failtag) + (byte-compile-out 'byte-call 1) + ;; At this point, the only thing from this function remaining on the + ;; stack is the return value of the called #'integerp, which reflects + ;; exactly what we want. Go directly to donetag, do not discard + ;; anything. + (byte-compile-goto 'byte-goto donetag) + (byte-compile-out-tag failtag) + (byte-compile-discard) + (byte-compile-discard) + (byte-compile-constant nil) + (byte-compile-goto 'byte-goto donetag) + (byte-compile-out-tag wintag) + (byte-compile-discard) + (byte-compile-discard) + (byte-compile-constant t) + (byte-compile-out-tag donetag)))) ;;(byte-defop-compiler-1 /= byte-compile-negated) (byte-defop-compiler-1 atom byte-compile-negated) diff -r a47abe9c47f2 -r c27efc9acb5a lisp/cl-macs.el --- a/lisp/cl-macs.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/cl-macs.el Wed Jan 27 00:37:59 2010 -0600 @@ -3026,9 +3026,9 @@ (cl-make-type-test val (funcall (get type 'cl-deftype-handler)))) ((memq type '(nil t)) type) ((eq type 'null) `(null ,val)) - ((eq type 'float) `(floatp-safe ,val)) + ((eq type 'float) `(floatp ,val)) ((eq type 'real) `(numberp ,val)) - ((eq type 'fixnum) `(integerp ,val)) + ((eq type 'fixnum) `(fixnump ,val)) ;; XEmacs change: we do not have char-valid-p ((memq type '(character string-char)) `(characterp ,val)) (t @@ -3205,12 +3205,12 @@ (define-compiler-macro eql (&whole form a b) (cond ((eq (cl-const-expr-p a) t) (let ((val (cl-const-expr-val a))) - (if (and (numberp val) (not (integerp val))) + (if (and (numberp val) (not (fixnump val))) (list 'equal a b) (list 'eq a b)))) ((eq (cl-const-expr-p b) t) (let ((val (cl-const-expr-val b))) - (if (and (numberp val) (not (integerp val))) + (if (and (numberp val) (not (fixnump val))) (list 'equal a b) (list 'eq a b)))) ((cl-simple-expr-p a 5) @@ -3226,20 +3226,25 @@ (define-compiler-macro member* (&whole form a list &rest keys) (let ((test (and (= (length keys) 2) (eq (car keys) :test) - (cl-const-expr-val (nth 1 keys))))) + (cl-const-expr-val (nth 1 keys)))) + a-val) (cond ((eq test 'eq) (list 'memq a list)) ((eq test 'equal) (list 'member a list)) ((or (null keys) (eq test 'eql)) (if (eq (cl-const-expr-p a) t) - (list (if (floatp-safe (cl-const-expr-val a)) 'member 'memq) + (list (if (and (numberp (setq a-val (cl-const-expr-val a))) + (not (fixnump a-val))) + 'member + 'memq) a list) (if (eq (cl-const-expr-p list) t) (let ((p (cl-const-expr-val list)) (mb nil) (mq nil)) (if (not (cdr p)) (and p (list 'eql a (list 'quote (car p)))) (while p - (if (floatp-safe (car p)) (setq mb t) - (or (integerp (car p)) (symbolp (car p)) (setq mq t))) + (if (and (numberp (car p)) (not (fixnump (car p)))) + (setq mb t) + (or (fixnump (car p)) (symbolp (car p)) (setq mq t))) (setq p (cdr p))) (if (not mb) (list 'memq a list) (if (not mq) (list 'member a list) form)))) @@ -3248,11 +3253,13 @@ (define-compiler-macro assoc* (&whole form a list &rest keys) (let ((test (and (= (length keys) 2) (eq (car keys) :test) - (cl-const-expr-val (nth 1 keys))))) + (cl-const-expr-val (nth 1 keys)))) + a-val) (cond ((eq test 'eq) (list 'assq a list)) ((eq test 'equal) (list 'assoc a list)) ((and (eq (cl-const-expr-p a) t) (or (null keys) (eq test 'eql))) - (if (floatp-safe (cl-const-expr-val a)) + (if (and (numberp (setq a-val (cl-const-expr-val a))) + (not (fixnump a-val))) (list 'assoc a list) (list 'assq a list))) (t form)))) @@ -3511,7 +3518,7 @@ (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr))) ;;; Things that are inline. -(proclaim '(inline floatp-safe acons map concatenate notany notevery +(proclaim '(inline acons map concatenate notany notevery ;; XEmacs omission: gethash is builtin cl-set-elt revappend nreconc)) @@ -3523,7 +3530,7 @@ ;;; Things that are side-effect-and-error-free. Moved to byte-optimize.el ;(mapcar (function (lambda (x) (put x 'side-effect-free 'error-free))) -; '(eql floatp-safe list* subst acons equalp random-state-p +; '(eql list* subst acons equalp random-state-p ; copy-tree sublis)) diff -r a47abe9c47f2 -r c27efc9acb5a lisp/cl-seq.el --- a/lisp/cl-seq.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/cl-seq.el Wed Jan 27 00:37:59 2010 -0600 @@ -664,7 +664,7 @@ (while (and cl-list (not (cl-check-test cl-item (car cl-list)))) (setq cl-list (cdr cl-list))) cl-list) - (if (and (numberp cl-item) (not (integerp cl-item))) + (if (and (numberp cl-item) (not (fixnump cl-item))) (member cl-item cl-list) (memq cl-item cl-list)))) @@ -697,7 +697,7 @@ (not (cl-check-test cl-item (car (car cl-alist)))))) (setq cl-alist (cdr cl-alist))) (and cl-alist (car cl-alist))) - (if (and (numberp cl-item) (not (integerp cl-item))) + (if (and (numberp cl-item) (not (fixnump cl-item))) (assoc cl-item cl-alist) (assq cl-item cl-alist)))) @@ -714,7 +714,7 @@ (defun rassoc* (cl-item cl-alist &rest cl-keys) "Find the first item whose cdr matches ITEM in LIST. Keywords supported: :test :test-not :key" - (if (or cl-keys (numberp cl-item)) + (if (or cl-keys (and (numberp cl-item) (not (fixnump cl-item)))) (cl-parsing-keywords (:test :test-not :key :if :if-not) () (while (and cl-alist (or (not (consp (car cl-alist))) diff -r a47abe9c47f2 -r c27efc9acb5a lisp/cl.el --- a/lisp/cl.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/cl.el Wed Jan 27 00:37:59 2010 -0600 @@ -123,10 +123,17 @@ ;;; Predicates. (defun eql (a b) ; See compiler macro in cl-macs.el - "Return t if the two args are the same Lisp object. -Floating-point numbers of equal value are `eql', but they may not be `eq'." - (or (eq a b) - (and (numberp a) (numberp b) (equal a b)))) + "Return t if the arguments are the same Lisp object, or numerically equal. + +They must be of the same type; the difference between `eq' and `eql' is most +relevant when it comes to the non-fixnum number types. In this +implementation, fixnums of the same numeric value are always `eq', but this +is not true for other numeric types, among them floats, bignums and ratios, +if available. + +See also `=' (which doesn't require that its arguments be of the same type, +but only accepts numeric arguments, characters and markers) and `equal'." + (or (eq a b) (and (numberp a) (equal a b)))) ;;; Generalized variables. These macros are defined here so that they ;;; can safely be used in .emacs files. @@ -317,11 +324,7 @@ ;;; Numbers. -;; XEmacs change: use floatp, which is right even in the presence of ratios -;; and bigfloats -(defun floatp-safe (object) - "Return t if OBJECT is a floating point number." - (floatp object)) +;; XEmacs change: ditch floatp-safe. (defun plusp (number) "Return t if NUMBER is positive." @@ -344,15 +347,6 @@ (defvar *random-state* (vector 'cl-random-state-tag -1 30 (cl-random-time))) -;; XEmacs: These constants are defined in C when 'number-types is provided. -;; They are always defined in C on Emacs. Maybe we should, too. -(unless (featurep 'number-types) -;;; We use `eval' in case VALBITS differs from compile-time to load-time. - (defconst most-positive-fixnum (eval '(lsh -1 -1)) - "The integer closest in value to positive infinity.") - (defconst most-negative-fixnum (eval '(- -1 (lsh -1 -1))) - "The integer closest in value to negative infinity.")) - ;;; The following are set by code in cl-extra.el (defconst most-positive-float nil "The float closest in value to positive infinity.") @@ -616,7 +610,7 @@ "Substitute NEW for OLD everywhere in TREE (non-destructively). Return a copy of TREE with all elements `eql' to OLD replaced by NEW. Keywords supported: :test :test-not :key" - (if (or cl-keys (and (numberp cl-old) (not (integerp cl-old)))) + (if (or cl-keys (and (numberp cl-old) (not (fixnump cl-old)))) (apply 'sublis (list (cons cl-old cl-new)) cl-tree cl-keys) (cl-do-subst cl-new cl-old cl-tree))) diff -r a47abe9c47f2 -r c27efc9acb5a lisp/obsolete.el --- a/lisp/obsolete.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/obsolete.el Wed Jan 27 00:37:59 2010 -0600 @@ -275,6 +275,9 @@ ;; being called on the values of functions known to return keymaps, ;; or known to return vectors of events instead of strings... +;;; Yes there is; make compiler macros for aref, assq, nconc, checking that +;;; the car of the relevant argument is sane. + (make-obsolete-variable 'executing-macro 'executing-kbd-macro) (define-compatible-function-alias 'interactive-form diff -r a47abe9c47f2 -r c27efc9acb5a lisp/simple.el --- a/lisp/simple.el Tue Jan 26 18:08:47 2010 -0600 +++ b/lisp/simple.el Wed Jan 27 00:37:59 2010 -0600 @@ -957,7 +957,7 @@ (let ((tail buffer-undo-list) done) (while (and tail (not done) (not (null (car tail)))) - (if (integerp (car tail)) + (if (fixnump (car tail)) (progn (setq done t) (setq buffer-undo-list (delq (car tail) buffer-undo-list)))) diff -r a47abe9c47f2 -r c27efc9acb5a man/ChangeLog --- a/man/ChangeLog Tue Jan 26 18:08:47 2010 -0600 +++ b/man/ChangeLog Wed Jan 27 00:37:59 2010 -0600 @@ -1,3 +1,51 @@ +2010-01-23 Aidan Kehoe + + Generally: be careful to say fixnum, not integer, when talking + about fixed-precision integral types. I'm sure I've missed + instances, both here and in the docstrings, but this is a decent + start. + + * lispref/text.texi (Columns): + Document where only fixnums, not integers generally, are accepted. + (Registers): + Remove some ancient char-int confoundance here. + * lispref/strings.texi (Creating Strings, Creating Strings): + Be more exact in describing where fixnums but not integers in + general are accepted. + (Creating Strings): Use a more contemporary example to illustrate + how concat deals with lists including integers about #xFF. Delete + some obsolete documentation on same. + (Char Table Types): Document that only fixnums are accepted as + values in syntax tables. + * lispref/searching.texi (String Search, Search and Replace): + Be exact in describing where fixnums but not integers in general + are accepted. + * lispref/range-tables.texi (Range Tables): Be exact in describing + them; only fixnums are accepted to describe ranges. + * lispref/os.texi (Killing XEmacs, User Identification) + (Time of Day, Time Conversion): + Be more exact about using fixnum where only fixed-precision + integers are accepted. + * lispref/objects.texi (Integer Type): Be more exact (and + up-to-date) about the possible values for + integers. Cross-reference to documentation of the bignum extension. + (Equality Predicates): + (Range Table Type): + (Array Type): Use fixnum, not integer, to describe a + fixed-precision integer. + (Syntax Table Type): Correct some English syntax here. + * lispref/numbers.texi (Numbers): Change the phrasing here to use + fixnum to mean the fixed-precision integers normal in emacs. + Document that our terminology deviates from that of Common Lisp, + and that we're working on it. + (Compatibility Issues): Reiterate the Common Lisp versus Emacs + Lisp compatibility issues. + (Comparison of Numbers, Arithmetic Operations): + * lispref/commands.texi (Command Loop Info, Working With Events): + * lispref/buffers.texi (Modification Time): + Be more exact in describing where fixnums but not integers in + general are accepted. + 2010-01-06 Jerry James * internals/internals.texi (Debugging and Testing): Document diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/buffers.texi --- a/man/lispref/buffers.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/buffers.texi Wed Jan 27 00:37:59 2010 -0600 @@ -524,7 +524,7 @@ If @var{time} is not @code{nil}, it should have the form @code{(@var{high} . @var{low})} or @code{(@var{high} @var{low})}, in -either case containing two integers, each of which holds 16 bits of the +either case containing two fixnums, each of which holds 16 bits of the time. This function is useful if the buffer was not read from the file diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/commands.texi --- a/man/lispref/commands.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/commands.texi Wed Jan 27 00:37:59 2010 -0600 @@ -762,7 +762,7 @@ @defvar echo-keystrokes This variable determines how much time should elapse before command -characters echo. Its value must be an integer, which specifies the +characters echo. Its value must be a float or a fixnum, which specifies the number of seconds to wait before echoing. If the user types a prefix key (say @kbd{C-x}) and then delays this many seconds before continuing, the key @kbd{C-x} is echoed in the echo area. Any subsequent characters @@ -1324,7 +1324,7 @@ @item @code{button} The event button. This an integer, either 1, 2 or 3. It is allowed -only for button-press and button-release events. +for button-press, button-release and misc-user events. @item @code{modifiers} The event modifiers. This is a list of modifier symbols. It is allowed diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/numbers.texi --- a/man/lispref/numbers.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/numbers.texi Wed Jan 27 00:37:59 2010 -0600 @@ -9,13 +9,13 @@ @cindex integers @cindex numbers - XEmacs supports two to five numeric data types. @dfn{Integers} and + XEmacs supports two to five numeric data types. @dfn{Fixnums} and @dfn{floating point numbers} are always supported. As a build-time option, @dfn{bignums}, @dfn{ratios}, and @dfn{bigfloats} may be enabled on some platforms. - Integers, which are what Common Lisp calls -@dfn{fixnums}, are whole numbers such as @minus{}3, 0, #b0111, #xFEED, + Fixnums (called just @dfn{integers} in GNU Emacs and older versions +of XEmacs) are whole numbers such as @minus{}3, 0, #b0111, #xFEED, #o744. Their values are exact, and their range is limited. The number prefixes `#b', `#o', and `#x' are supported to represent numbers in binary, octal, and hexadecimal notation (or radix). Floating point @@ -52,14 +52,15 @@ The exact rules are more carefully explained elsewhere (@pxref{Canonicalization and Contagion}). - Note that the term ``integer'' is used throughout the XEmacs -documentation and code to mean ``fixnum''. This is inconsistent with -Common Lisp, and likely to cause confusion. Similarly, ``float'' is -used to mean ``fixed precision floating point number'', and the Common -Lisp distinctions among @dfn{short-floats}, @dfn{long-floats}, -@emph{etc.}, and bigfloats (which are not standardized in Common Lisp) -are not reflected in XEmacs terminology. (Volunteers to fix this in the -XEmacs manuals would be heartily welcomed.) + Common Lisp terminology and historical Emacs terminology conflict +here, to an extent. We attempt to use ``fixnum'' and ``integer'' +consistently, but older XEmacs and GNU Emacs code and documentation use +the latter to mean the former. ``Float'' is used in Emacs documentation +to mean ``fixed precision floating point number'', and the Common Lisp +distinctions among @dfn{short-floats}, @dfn{long-floats}, @emph{etc.}, +and bigfloats (which are not standardized in Common Lisp) are not +reflected in XEmacs terminology. We're working on this, but volunteers +to fix it in the XEmacs manuals would be heartily welcomed. @menu * Integer Basics:: Representation and range of integers. @@ -541,12 +542,11 @@ yet.) @item -Terminology is not Common-Lisp-conforming. For example, ``integer'' for -Emacs Lisp means what Common Lisp calls ``fixnum''. This issue is being -investigated, but the use of ``integer'' for fixnum is pervasive and may -cause backward-compatibility and GNU-Emacs-compatibility problems. -There are similar issues for floating point numbers. Since Emacs Lisp -has not had a ratio type before, there should be no problems there. +Our documentation's terminology, and our API terminology, is not always +Common-Lisp-conforming. Many places use ``integer'' where ``fixnum'' +better reflects what the code accepts or produces; there are similar +issues for the varying types of floating point numbers. Since Emacs +Lisp has not had a ratio type before, there are no problems there. @item An atom with ratio read syntax now returns a number, not a symbol. @@ -759,8 +759,8 @@ @b{Common Lisp note:} Comparing numbers in Common Lisp always requires @code{=} because Common Lisp implements multi-word integers, and two distinct integer objects can have the same numeric value. XEmacs Lisp -can have just one integer object for any given value because it has a -limited range of integer values. +can have just one fixnum object for any given value because it has a +limited range of fixnum values. @end quotation In addition to numbers, all of the following functions also accept @@ -914,7 +914,8 @@ It is important to note that in XEmacs Lisp, arithmetic functions do not check for overflow. Thus @code{(1+ 134217727)} may evaluate to -@minus{}134217728, depending on your hardware. +@minus{}134217728, depending on your hardware and whether your XEmacs +supports bignums. @defun 1+ number This function returns @var{number} plus one. @var{number} may be a diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/objects.texi --- a/man/lispref/objects.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/objects.texi Wed Jan 27 00:37:59 2010 -0600 @@ -290,31 +290,25 @@ @node Integer Type @subsection Integer Type - The range of values for integers in XEmacs Lisp is @minus{}134217728 to -134217727 (28 bits; i.e., -@ifinfo --2**27 -@end ifinfo -@tex -$-2^{27}$ -@end tex -to -@ifinfo -2**27 - 1) -@end ifinfo -@tex -$2^{28}-1$) -@end tex -on most machines. (Some machines, in particular 64-bit machines such as -the DEC Alpha, may provide a wider range.) It is important to note that -the XEmacs Lisp arithmetic functions do not check for overflow. Thus -@code{(1+ 134217727)} is @minus{}134217728 on most machines. (However, -you @emph{will} get an error if you attempt to read an out-of-range -number using the Lisp reader.) - - The read syntax for integers is a sequence of (base ten) digits with -an optional sign at the beginning. (The printed representation produced -by the Lisp interpreter never has a leading @samp{+}.) + In XEmacs Lisp, integers can be fixnums (that is, fixed-precision +integers) or bignums (arbitrary-precision integers), if compile-time +configuration supports this. The read syntax for the two types is the +same, the type chosen depending on the numeric values involved. + + The range of values for fixnums in XEmacs Lisp is given by the +constants @code{most-positive-fixnum} and @code{most-negative-fixnum}. +On 32-bit machines, these constants reflect 31 value bits, ranging from +@minus{}1073741824 to 1073741823. + + In the absence of @xref{The Bignum Extension}, XEmacs Lisp +arithmetic functions do not check for overflow; so the code snippet +@code{(= most-negative-fixnum (1+ most-positive-fixnum))} will give +@code{t}. However, you @emph{will} get an error if you attempt to read +an out-of-range number using the Lisp reader. + + The main read syntax for integers is a sequence of base ten digits +with an optional sign at the beginning. (The printed representation +produced by the Lisp interpreter never has a leading @samp{+}.) @example @group @@ -1022,7 +1016,7 @@ read syntax; see @ref{String Type}, @ref{Vector Type}, and @ref{Bit Vector Type}. - An array may have any length up to the largest integer; but once + An array may have any length up to the largest fixnum; but once created, it has a fixed size. The first element of an array has index zero, the second element has index 1, and so on. This is called @dfn{zero-origin} indexing. For example, an array of four elements has @@ -1331,7 +1325,7 @@ @subsection Range Table Type @cindex range table type - A @dfn{range table} is a table that maps from ranges of integers to + A @dfn{range table} is a table that maps from ranges of fixnums to arbitrary Lisp objects. Range tables automatically combine overlapping ranges that map to the same Lisp object, and operations are provided for mapping over all of the ranges in a range table. @@ -1714,7 +1708,7 @@ @subsection Syntax Table Type Under XEmacs 20, a @dfn{syntax table} is a particular type of char -table. Under XEmacs 19, a syntax table a vector of 256 integers. In +table. Under XEmacs 19, a syntax table is a vector of 256 integers. In both cases, each element defines how one character is interpreted when it appears in a buffer. For example, in C mode (@pxref{Major Modes}), the @samp{+} character is punctuation, but in Lisp mode it is a valid @@ -2245,7 +2239,7 @@ change in one will be reflected by the same change in the other. @code{eq} returns @code{t} if @var{object1} and @var{object2} are -integers with the same value. It is preferable to use @code{=} or +fixnums with the same value. It is preferable to use @code{=} or @code{eql} in many contexts for numeric comparison, especially since bignums (integers with values that would have otherwise overflowed, only available on some builds) with the same value are not @code{eq}; diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/os.texi --- a/man/lispref/os.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/os.texi Wed Jan 27 00:37:59 2010 -0600 @@ -419,7 +419,7 @@ @deffn Command kill-emacs &optional exit-data This function exits the XEmacs process and kills it. -If @var{exit-data} is an integer, then it is used as the exit status +If @var{exit-data} is a fixnum, then it is used as the exit status of the XEmacs process. (This is useful primarily in batch operation; see @ref{Batch Mode}.) @@ -765,7 +765,7 @@ on the effective @sc{uid}, not the real @sc{uid}. If you specify @var{uid}, the value is the user name that corresponds -to @var{uid} (which should be an integer). +to @var{uid} (which should be a fixnum). @example @group @@ -884,7 +884,7 @@ @c Emacs 19 feature The argument @var{time-value}, if given, specifies a time to format instead of the current time. The argument should be a list whose first -two elements are integers. Thus, you can use times obtained from +two elements are fixnums. Thus, you can use times obtained from @code{current-time} (see below) and from @code{file-attributes} (@pxref{File Attributes}). @@ -935,15 +935,15 @@ The argument @var{time-value}, if given, specifies a time to analyze instead of the current time. The argument should be a cons cell -containing two integers, or a list whose first two elements are -integers. Thus, you can use times obtained from @code{current-time} +containing two fixnums, or a list whose first two elements are +fixnums. Thus, you can use times obtained from @code{current-time} (see above) and from @code{file-attributes} (@pxref{File Attributes}). @end defun @node Time Conversion @section Time Conversion - These functions convert time values (lists of two or three integers) + These functions convert time values (lists of two or three fixnums) to strings or to calendrical information. There is also a function to convert calendrical information to a time value. You can get time values from the functions @code{current-time} (@pxref{Time of Day}) and diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/positions.texi --- a/man/lispref/positions.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/positions.texi Wed Jan 27 00:37:59 2010 -0600 @@ -505,7 +505,7 @@ @var{pixels} is negative. The optional second argument @var{window} is the window to move in, and defaults to the selected window. The optional third argument @var{how} specifies the stopping condition. A -negative integer indicates that the motion should be no more +negative fixnum indicates that the motion should be no more than @var{pixels}. A positive value indicates that the motion should be at least @var{pixels}. Any other value indicates that the motion should be as close as possible to @var{pixels}. diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/processes.texi --- a/man/lispref/processes.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/processes.texi Wed Jan 27 00:37:59 2010 -0600 @@ -757,7 +757,7 @@ @code{process-connection-type} in @ref{Asynchronous Processes}. Some of the functions below take a @var{signal} argument, which -identifies a signal to be sent. It must be either an integer or a +identifies a signal to be sent. It must be either a fixnum or a symbol which names the signal, like @code{SIGSEGV}. @defun process-send-signal signal &optional process current-group diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/range-tables.texi --- a/man/lispref/range-tables.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/range-tables.texi Wed Jan 27 00:37:59 2010 -0600 @@ -7,8 +7,8 @@ @chapter Range Tables @cindex Range Tables -A range table is a table that efficiently associated values with -ranges of integers. +A range table is a table that efficiently associates values with +ranges of fixnums. Note that range tables have a read syntax, like this: diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/searching.texi --- a/man/lispref/searching.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/searching.texi Wed Jan 27 00:37:59 2010 -0600 @@ -80,7 +80,7 @@ to return the new position of point in that case, but some programs may depend on a value of @code{nil}.) -If @var{count} is supplied (it must be an integer), then the search is +If @var{count} is supplied (it must be a fixnum), then the search is repeated that many times (each time starting at the end of the previous time's match). If @var{count} is negative, the search direction is backward. If the successive searches succeed, the function succeeds, @@ -1039,7 +1039,7 @@ with. If it is a string, that string is used. It can also be a list of strings, to be used in cyclic order. -If @var{repeat-count} is non-@code{nil}, it should be an integer. Then +If @var{repeat-count} is non-@code{nil}, it should be a fixnum. Then it specifies how many times to use each of the strings in the @var{replacements} list before advancing cyclicly to the next one. diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/strings.texi --- a/man/lispref/strings.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/strings.texi Wed Jan 27 00:37:59 2010 -0600 @@ -145,7 +145,7 @@ @defun make-string length character This function returns a new string consisting entirely of @var{length} successive copies of @var{character}. @var{length} must be a -non-negative integer. +non-negative fixnum. @example (make-string 5 ?x) @@ -224,7 +224,7 @@ @xref{Duplicable Extents}. A @code{wrong-type-argument} error is signaled if either @var{start} or -@var{end} is not an integer or @code{nil}. An @code{args-out-of-range} +@var{end} is not a fixnum or @code{nil}. An @code{args-out-of-range} error is signaled if @var{start} indicates a character following @var{end}, or if either integer is out of range for @var{string}. @@ -246,8 +246,8 @@ @example (concat "abc" "-def") @result{} "abc-def" -(concat "abc" (list 120 (+ 256 121)) [122]) - @result{} "abcxyz" +(equal (concat "abc" (list 120 (+ 256 121)) [122]) (format "abcx%cz" 377)) + @result{} t ;; @r{@code{nil} is an empty sequence.} (concat "abc" nil "-def") @result{} "abc-def" @@ -258,30 +258,9 @@ @end example @noindent -The second example above shows how characters stored in strings are -taken modulo 256. In other words, each character in the string is -stored in one byte. - The @code{concat} function always constructs a new string that is not @code{eq} to any existing string. -When an argument is an integer (not a sequence of integers), it is -converted to a string of digits making up the decimal printed -representation of the integer. @strong{Don't use this feature; we plan -to eliminate it. If you already use this feature, change your programs -now!} The proper way to convert an integer to a decimal number in this -way is with @code{format} (@pxref{Formatting Strings}) or -@code{number-to-string} (@pxref{String Conversion}). - -@example -@group -(concat 137) - @result{} "137" -(concat 54 321) - @result{} "54321" -@end group -@end example - For information about other concatenation functions, see the description of @code{mapconcat} in @ref{Mapping Functions}, @code{vconcat} in @ref{Vectors}, @code{bvconcat} in @ref{Bit Vectors}, and @code{append} @@ -1189,7 +1168,7 @@ @item syntax Used for syntax tables, which specify the syntax of a particular character. Higher-level Lisp functions are provided for -working with syntax tables. The valid values are integers. +working with syntax tables. The valid values are fixnums. @end table @defun char-table-type char-table diff -r a47abe9c47f2 -r c27efc9acb5a man/lispref/text.texi --- a/man/lispref/text.texi Tue Jan 26 18:08:47 2010 -0600 +++ b/man/lispref/text.texi Wed Jan 27 00:37:59 2010 -0600 @@ -1679,7 +1679,7 @@ @var{force} is the special value @code{coerce}, it says to add whitespace at the end of the line to reach that column. -If @var{column} is not a non-negative integer, an error is signaled. +If @var{column} is not a non-negative fixnum, an error is signaled. The return value is the column number actually moved to. @end defun @@ -2698,7 +2698,7 @@ @var{contents})}. Normally, there is one element for each XEmacs register that has been used. -The object @var{name} is a character (an integer) identifying the +The object @var{name} is a character identifying the register. The object @var{contents} is a string, marker, or list representing the register contents. A string represents text stored in the register. A marker represents a position. A list represents a diff -r a47abe9c47f2 -r c27efc9acb5a src/ChangeLog --- a/src/ChangeLog Tue Jan 26 18:08:47 2010 -0600 +++ b/src/ChangeLog Wed Jan 27 00:37:59 2010 -0600 @@ -165,6 +165,47 @@ and to give the same answer all the time when treating a rational that is itself is an integer as a ratio. +2010-01-24 Aidan Kehoe + + Fix problems with #'eql, extended number types, and the hash table + implementation; change the Bintegerp bytecode to fixnump semantics + even on bignum builds, since #'integerp can have a fast + implementation in terms of #'fixnump for most of its extant uses, + but not vice-versa. + + * lisp.h: Always #include number.h; we want the macros provided in + it, even if the various number types are not available. + * number.h (NON_FIXNUM_NUMBER_P): New macro, giving 1 when its + argument is of non-immediate number type. Equivalent to FLOATP if + WITH_NUMBER_TYPES is not defined. + + * elhash.c (lisp_object_eql_equal, lisp_object_eql_hash): + Use NON_FIXNUM_NUMBER_P in these functions, instead of FLOATP, + giving more correct behaviour in the presence of the extended + number types. + * bytecode.c (Bfixnump, execute_optimized_program): + Rename Bintegerp to Bfixnump; change its semantics to reflect the + new name on builds with bignum support. + + * data.c (Ffixnump, Fintegerp, syms_of_data, vars_of_data): + Always make #'fixnump available, even on non-BIGNUM builds; + always implement #'integerp in this file, even on BIGNUM builds. + Move most-positive-fixnum, most-negative-fixnum here from + number.c, so they are Lisp constants even on builds without number + types, and attempts to change or bind them error. + Use the NUMBERP and INTEGERP macros even on builds without + extended number types. + * data.c (fixnum_char_or_marker_to_int): + Rename this function from integer_char_or_marker_to_int, to better + reflect the arguments it accepts. + + * number.c (Fevenp, Foddp, syms_of_number): + Never provide #'integerp in this file. Remove #'oddp, + #'evenp; their implementations are overridden by those in cl.el. + * number.c (vars_of_number): + most-positive-fixnum, most-negative-fixnum are no longer here. + +>>>>>>> other 2010-01-17 Vin Shelton * fileio.c (check_writable): Remove cast from 2010-01-14 diff -r a47abe9c47f2 -r c27efc9acb5a src/bytecode.c --- a/src/bytecode.c Tue Jan 26 18:08:47 2010 -0600 +++ b/src/bytecode.c Wed Jan 27 00:37:59 2010 -0600 @@ -232,7 +232,7 @@ Bquo = 0245, Brem = 0246, Bnumberp = 0247, - Bintegerp = 0250, + Bfixnump = 0250, /* Was Bintegerp. */ BRgoto = 0252, BRgotoifnil = 0253, @@ -1076,12 +1076,8 @@ #endif break; - case Bintegerp: -#ifdef HAVE_BIGNUM - TOP_LVALUE = INTEGERP (TOP) ? Qt : Qnil; -#else + case Bfixnump: TOP_LVALUE = INTP (TOP) ? Qt : Qnil; -#endif break; case Beq: diff -r a47abe9c47f2 -r c27efc9acb5a src/data.c --- a/src/data.c Tue Jan 26 18:08:47 2010 -0600 +++ b/src/data.c Wed Jan 27 00:37:59 2010 -0600 @@ -65,6 +65,8 @@ Lisp_Object Qerror_lacks_explanatory_string; Lisp_Object Qfloatp; +Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; + #ifdef DEBUG_XEMACS int debug_issue_ebola_notices; @@ -420,7 +422,7 @@ */ (integer)) { - CHECK_INT (integer); + CHECK_INTEGER (integer); if (CHAR_INTP (integer)) return make_char (XINT (integer)); else @@ -456,31 +458,34 @@ return CHAR_OR_CHAR_INTP (object) || STRINGP (object) ? Qt : Qnil; } -#ifdef HAVE_BIGNUM -/* In this case, integerp is defined in number.c. */ DEFUN ("fixnump", Ffixnump, 1, 1, 0, /* Return t if OBJECT is a fixnum. + +In this implementation, a fixnum is an immediate integer, and has a +maximum value described by the constant `most-positive-fixnum'. This +contrasts with bignums, integers where the values are limited by your +available memory. */ (object)) { return INTP (object) ? Qt : Qnil; } -#else DEFUN ("integerp", Fintegerp, 1, 1, 0, /* -Return t if OBJECT is an integer. +Return t if OBJECT is an integer, nil otherwise. + +On builds without bignum support, this function is identical to `fixnump'. */ (object)) { - return INTP (object) ? Qt : Qnil; + return INTEGERP (object) ? Qt : Qnil; } -#endif DEFUN ("integer-or-marker-p", Finteger_or_marker_p, 1, 1, 0, /* Return t if OBJECT is an integer or a marker (editor pointer). */ (object)) { - return INTP (object) || MARKERP (object) ? Qt : Qnil; + return INTEGERP (object) || MARKERP (object) ? Qt : Qnil; } DEFUN ("integer-or-char-p", Finteger_or_char_p, 1, 1, 0, /* @@ -488,7 +493,7 @@ */ (object)) { - return INTP (object) || CHARP (object) ? Qt : Qnil; + return INTEGERP (object) || CHARP (object) ? Qt : Qnil; } DEFUN ("integer-char-or-marker-p", Finteger_char_or_marker_p, 1, 1, 0, /* @@ -496,7 +501,7 @@ */ (object)) { - return INTP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil; + return INTEGERP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil; } DEFUN ("natnump", Fnatnump, 1, 1, 0, /* @@ -542,11 +547,7 @@ */ (object)) { -#ifdef WITH_NUMBER_TYPES return NUMBERP (object) ? Qt : Qnil; -#else - return INT_OR_FLOATP (object) ? Qt : Qnil; -#endif } DEFUN ("number-or-marker-p", Fnumber_or_marker_p, 1, 1, 0, /* @@ -554,7 +555,7 @@ */ (object)) { - return INT_OR_FLOATP (object) || MARKERP (object) ? Qt : Qnil; + return NUMBERP (object) || MARKERP (object) ? Qt : Qnil; } DEFUN ("number-char-or-marker-p", Fnumber_char_or_marker_p, 1, 1, 0, /* @@ -562,9 +563,7 @@ */ (object)) { - return (INT_OR_FLOATP (object) || - CHARP (object) || - MARKERP (object)) + return (NUMBERP (object) || CHARP (object) || MARKERP (object)) ? Qt : Qnil; } @@ -740,6 +739,19 @@ if (INTP (index_)) idx = XINT (index_); else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */ +#ifdef HAVE_BIGNUM + else if (BIGNUMP (index_)) + { + Lisp_Object canon = Fcanonicalize_number (index_); + if (EQ (canon, index_)) + { + /* We don't support non-fixnum indices. */ + goto range_error; + } + index_ = canon; + goto retry; + } +#endif else { index_ = wrong_type_argument (Qinteger_or_char_p, index_); @@ -795,6 +807,19 @@ if (INTP (index_)) idx = XINT (index_); else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */ +#ifdef HAVE_BIGNUM + else if (BIGNUMP (index_)) + { + Lisp_Object canon = Fcanonicalize_number (index_); + if (EQ (canon, index_)) + { + /* We don't support non-fixnum indices. */ + goto range_error; + } + index_ = canon; + goto retry; + } +#endif else { index_ = wrong_type_argument (Qinteger_or_char_p, index_); @@ -884,7 +909,7 @@ #endif /* WITH_NUMBER_TYPES */ static EMACS_INT -integer_char_or_marker_to_int (Lisp_Object obj) +fixnum_char_or_marker_to_int (Lisp_Object obj) { retry: if (INTP (obj)) return XINT (obj); @@ -892,6 +917,9 @@ else if (MARKERP (obj)) return marker_position (obj); else { + /* On bignum builds, we can only be called from #'lognot, which + protects against this happening: */ + assert (!BIGNUMP (obj)); obj = wrong_type_argument (Qinteger_char_or_marker_p, obj); goto retry; } @@ -1192,11 +1220,7 @@ */ (number)) { -#ifdef WITH_NUMBER_TYPES CHECK_NUMBER (number); -#else - CHECK_INT_OR_FLOAT (number); -#endif if (FLOATP (number)) { @@ -2132,7 +2156,7 @@ Lisp_Object *args_end = args + nargs; while (args < args_end) - bits &= integer_char_or_marker_to_int (*args++); + bits &= fixnum_char_or_marker_to_int (*args++); return make_int (bits); #endif /* HAVE_BIGNUM */ @@ -2184,7 +2208,7 @@ Lisp_Object *args_end = args + nargs; while (args < args_end) - bits |= integer_char_or_marker_to_int (*args++); + bits |= fixnum_char_or_marker_to_int (*args++); return make_int (bits); #endif /* HAVE_BIGNUM */ @@ -2206,7 +2230,7 @@ return make_int (0); while (!(CHARP (args[0]) || MARKERP (args[0]) || INTEGERP (args[0]))) - args[0] = wrong_type_argument (Qnumber_char_or_marker_p, args[0]); + args[0] = wrong_type_argument (Qinteger_char_or_marker_p, args[0]); result = args[0]; if (CHARP (result)) @@ -2216,7 +2240,7 @@ for (i = 1; i < nargs; i++) { while (!(CHARP (args[i]) || MARKERP (args[i]) || INTEGERP (args[i]))) - args[i] = wrong_type_argument (Qnumber_char_or_marker_p, args[i]); + args[i] = wrong_type_argument (Qinteger_char_or_marker_p, args[i]); other = args[i]; if (promote_args (&result, &other) == FIXNUM_T) { @@ -2235,7 +2259,7 @@ Lisp_Object *args_end = args + nargs; while (args < args_end) - bits ^= integer_char_or_marker_to_int (*args++); + bits ^= fixnum_char_or_marker_to_int (*args++); return make_int (bits); #endif /* !HAVE_BIGNUM */ @@ -2247,6 +2271,9 @@ */ (number)) { + while (!(CHARP (number) || MARKERP (number) || INTEGERP (number))) + number = wrong_type_argument (Qinteger_char_or_marker_p, number); + #ifdef HAVE_BIGNUM if (BIGNUMP (number)) { @@ -2254,7 +2281,8 @@ return make_bignum_bg (scratch_bignum); } #endif /* HAVE_BIGNUM */ - return make_int (~ integer_char_or_marker_to_int (number)); + + return make_int (~ fixnum_char_or_marker_to_int (number)); } DEFUN ("%", Frem, 2, 2, 0, /* @@ -2284,8 +2312,8 @@ return Fcanonicalize_number (make_bignum_bg (scratch_bignum)); } #else /* !HAVE_BIGNUM */ - EMACS_INT ival1 = integer_char_or_marker_to_int (number1); - EMACS_INT ival2 = integer_char_or_marker_to_int (number2); + EMACS_INT ival1 = fixnum_char_or_marker_to_int (number1); + EMACS_INT ival2 = fixnum_char_or_marker_to_int (number2); if (ival2 == 0) Fsignal (Qarith_error, Qnil); @@ -3550,11 +3578,8 @@ DEFSUBR (Fchar_to_int); DEFSUBR (Fint_to_char); DEFSUBR (Fchar_or_char_int_p); -#ifdef HAVE_BIGNUM DEFSUBR (Ffixnump); -#else DEFSUBR (Fintegerp); -#endif DEFSUBR (Finteger_or_marker_p); DEFSUBR (Finteger_or_char_p); DEFSUBR (Finteger_char_or_marker_p); @@ -3644,6 +3669,16 @@ Vall_weak_boxes = Qnil; dump_add_weak_object_chain (&Vall_weak_boxes); + DEFVAR_CONST_INT ("most-negative-fixnum", &Vmost_negative_fixnum /* +The fixnum closest in value to negative infinity. +*/); + Vmost_negative_fixnum = EMACS_INT_MIN; + + DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /* +The fixnum closest in value to positive infinity. +*/); + Vmost_positive_fixnum = EMACS_INT_MAX; + #ifdef DEBUG_XEMACS DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /* If non-zero, note when your code may be suffering from char-int confoundance. diff -r a47abe9c47f2 -r c27efc9acb5a src/elhash.c --- a/src/elhash.c Tue Jan 26 18:08:47 2010 -0600 +++ b/src/elhash.c Wed Jan 27 00:37:59 2010 -0600 @@ -207,13 +207,14 @@ static int lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2) { - return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0)); + return EQ (obj1, obj2) || + (NON_FIXNUM_NUMBER_P (obj1) && internal_equal (obj1, obj2, 0)); } static Hashcode lisp_object_eql_hash (Lisp_Object obj) { - return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj); + return NON_FIXNUM_NUMBER_P (obj) ? internal_hash (obj, 0) : LISP_HASH (obj); } static int diff -r a47abe9c47f2 -r c27efc9acb5a src/lisp.h --- a/src/lisp.h Tue Jan 26 18:08:47 2010 -0600 +++ b/src/lisp.h Wed Jan 27 00:37:59 2010 -0600 @@ -4195,11 +4195,7 @@ /************************************************************************/ /* Other numeric types */ /************************************************************************/ -#ifdef WITH_NUMBER_TYPES #include "number.h" -#else -#define make_integer(x) make_int(x) -#endif /************************************************************************/ diff -r a47abe9c47f2 -r c27efc9acb5a src/number.c --- a/src/number.c Tue Jan 26 18:08:47 2010 -0600 +++ b/src/number.c Wed Jan 27 00:37:59 2010 -0600 @@ -32,7 +32,7 @@ Lisp_Object Qrationalp, Qfloatingp, Qrealp; Lisp_Object Vdefault_float_precision; -Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; + static Lisp_Object Qunsupported_type; static Lisp_Object Vbigfloat_max_prec; static int number_initialized; @@ -139,38 +139,6 @@ } -/********************************* Integers *********************************/ -DEFUN ("integerp", Fintegerp, 1, 1, 0, /* -Return t if OBJECT is an integer, nil otherwise. -*/ - (object)) -{ - return INTEGERP (object) ? Qt : Qnil; -} - -DEFUN ("evenp", Fevenp, 1, 1, 0, /* -Return t if INTEGER is even, nil otherwise. -*/ - (integer)) -{ - CONCHECK_INTEGER (integer); - return (BIGNUMP (integer) - ? bignum_evenp (XBIGNUM_DATA (integer)) - : XTYPE (integer) == Lisp_Type_Int_Even) ? Qt : Qnil; -} - -DEFUN ("oddp", Foddp, 1, 1, 0, /* -Return t if INTEGER is odd, nil otherwise. -*/ - (integer)) -{ - CONCHECK_INTEGER (integer); - return (BIGNUMP (integer) - ? bignum_oddp (XBIGNUM_DATA (integer)) - : XTYPE (integer) == Lisp_Type_Int_Odd) ? Qt : Qnil; -} - - /********************************** Ratios **********************************/ #ifdef HAVE_RATIO static void @@ -270,7 +238,7 @@ return Fcanonicalize_number (make_bignum_bg (XRATIO_DENOMINATOR (rational))); } -#endif +#else return make_int (1); } @@ -810,9 +778,6 @@ /* Functions */ DEFSUBR (Fbignump); - DEFSUBR (Fintegerp); - DEFSUBR (Fevenp); - DEFSUBR (Foddp); DEFSUBR (Fratiop); DEFSUBR (Frationalp); DEFSUBR (Fnumerator); @@ -855,16 +820,6 @@ Vbigfloat_max_prec = make_int (0); #endif /* HAVE_BIGFLOAT */ - DEFVAR_CONST_INT ("most-negative-fixnum", &Vmost_negative_fixnum /* -The fixnum closest in value to negative infinity. -*/); - Vmost_negative_fixnum = EMACS_INT_MIN; - - DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /* -The fixnum closest in value to positive infinity. -*/); - Vmost_positive_fixnum = EMACS_INT_MAX; - Fprovide (intern ("number-types")); #ifdef HAVE_BIGNUM Fprovide (intern ("bignum")); diff -r a47abe9c47f2 -r c27efc9acb5a src/number.h --- a/src/number.h Tue Jan 26 18:08:47 2010 -0600 +++ b/src/number.h Wed Jan 27 00:37:59 2010 -0600 @@ -338,4 +338,35 @@ extern enum number_type get_number_type (Lisp_Object); extern enum number_type promote_args (Lisp_Object *, Lisp_Object *); +#ifdef WITH_NUMBER_TYPES +DECLARE_INLINE_HEADER ( +int +non_fixnum_number_p (Lisp_Object object)) +{ + if (LRECORDP (object)) + { + switch (XRECORD_LHEADER (object)->type) + { + case lrecord_type_float: +#ifdef HAVE_BIGNUM + case lrecord_type_bignum: +#endif +#ifdef HAVE_RATIO + case lrecord_type_ratio: +#endif +#ifdef HAVE_BIGFLOAT + case lrecord_type_bigfloat: +#endif + return 1; + } + } + return 0; +} +#define NON_FIXNUM_NUMBER_P(X) non_fixnum_number_p (X) + +#else +#define NON_FIXNUM_NUMBER_P FLOATP +#endif + + #endif /* INCLUDED_number_h_ */ diff -r a47abe9c47f2 -r c27efc9acb5a tests/automated/lisp-tests.el --- a/tests/automated/lisp-tests.el Tue Jan 26 18:08:47 2010 -0600 +++ b/tests/automated/lisp-tests.el Wed Jan 27 00:37:59 2010 -0600 @@ -2181,4 +2181,52 @@ do (Assert (functionp real-function) (format "checking %S is a function" real-function))) +;; #'member, #'assoc tests. + +(when (featurep 'bignum) + (let* ((member*-list `(0 9 342 [hi there] ,(1+ most-positive-fixnum) 0 + 0.0 ,(1- most-negative-fixnum) nil)) + (assoc*-list (loop + for elt in member*-list + collect (cons elt (random)))) + (hashing (make-hash-table :test 'eql)) + hashed-bignum) + (macrolet + ((1+most-positive-fixnum () + (1+ most-positive-fixnum)) + (1-most-negative-fixnum () + (1- most-negative-fixnum)) + (*-2-most-positive-fixnum () + (* 2 most-positive-fixnum))) + (Assert-eq + (member* (1+ most-positive-fixnum) member*-list) + (member* (1+ most-positive-fixnum) member*-list :test #'eql) + "checking #'member* correct if #'eql not explicitly specified") + (Assert-eq + (assoc* (1+ most-positive-fixnum) assoc*-list) + (assoc* (1+ most-positive-fixnum) assoc*-list :test #'eql) + "checking #'assoc* correct if #'eql not explicitly specified") + (Assert-eq + (rassoc* (1- most-negative-fixnum) assoc*-list) + (rassoc* (1- most-negative-fixnum) assoc*-list :test #'eql) + "checking #'rassoc* correct if #'eql not explicitly specified") + (Assert-eq + (eql (1+most-positive-fixnum) (1+ most-positive-fixnum)) + t + "checking #'eql handles a bignum literal properly.") + (Assert-eq + (member* (1+most-positive-fixnum) member*-list) + (member* (1+ most-positive-fixnum) member*-list :test #'equal) + "checking #'member* compiler macro correct with literal bignum") + (Assert-eq + (assoc* (1+most-positive-fixnum) assoc*-list) + (assoc* (1+ most-positive-fixnum) assoc*-list :test #'equal) + "checking #'assoc* compiler macro correct with literal bignum") + (puthash (setq hashed-bignum (*-2-most-positive-fixnum)) + (gensym) hashing) + (Assert-eq + (gethash (* 2 most-positive-fixnum) hashing) + (gethash hashed-bignum hashing) + "checking hashing works correctly with #'eql tests and bignums")))) + ;;; end of lisp-tests.el