Mercurial > hg > xemacs-beta
diff lisp/cl-macs.el @ 5445:6506fcb40fcf
Merged with trunk.
author | Mats Lidell <matsl@xemacs.org> |
---|---|
date | Fri, 31 Dec 2010 00:27:29 +0100 |
parents | 8d29f1c4bb98 8aa511adfad6 |
children | 89331fa1c819 |
line wrap: on
line diff
--- a/lisp/cl-macs.el Sun Dec 26 01:48:40 2010 +0100 +++ b/lisp/cl-macs.el Fri Dec 31 00:27:29 2010 +0100 @@ -109,7 +109,8 @@ ;;; Check if no side effects. (defun cl-safe-expr-p (x) - (or (not (and (consp x) (not (memq (car x) '(quote function function*))))) + (or (not (and (consp x) (not (memq (car x) + '(quote function function* lambda))))) (and (symbolp (car x)) (or (memq (car x) cl-simple-funcs) (memq (car x) cl-safe-funcs) @@ -3484,56 +3485,60 @@ ;; XEmacs; inline delete-duplicates if it's called with one of the ;; common compile-time constant tests and an optional :from-end ;; argument, we want the speed in font-lock.el. -(define-compiler-macro delete-duplicates (&whole form cl-seq &rest cl-keys) - (if (not (or (memq (car-safe cl-seq) - ;; No need to check for a list at runtime with - ;; these. We could expand the list, but these are all - ;; the functions in the relevant context at the moment. - '(nreverse append nconc mapcan mapcar string-to-list)) - (and (listp cl-seq) (equal (butlast cl-seq) '(the list))))) - form - (cond - ((or (plists-equal cl-keys '(:test 'eq) t) - (plists-equal cl-keys '(:test #'eq) t)) - `(let* ((begin ,cl-seq) - cl-seq) - (while (memq (car begin) (cdr begin)) - (setq begin (cdr begin))) - (setq cl-seq begin) - (while (cddr cl-seq) - (if (memq (cadr cl-seq) (cddr cl-seq)) - (setcdr (cdr cl-seq) (cddr cl-seq))) - (setq cl-seq (cdr cl-seq))) - begin)) - ((or (plists-equal cl-keys '(:test 'eq :from-end t) t) - (plists-equal cl-keys '(:test #'eq :from-end t) t)) - `(let* ((begin ,cl-seq) - (cl-seq begin)) - (while cl-seq - (setq cl-seq (setcdr cl-seq - (delq (car cl-seq) (cdr cl-seq))))) - begin)) - ((or (plists-equal cl-keys '(:test 'equal) t) - (plists-equal cl-keys '(:test #'equal) t)) - `(let* ((begin ,cl-seq) - cl-seq) - (while (member (car begin) (cdr begin)) - (setq begin (cdr begin))) - (setq cl-seq begin) - (while (cddr cl-seq) - (if (member (cadr cl-seq) (cddr cl-seq)) - (setcdr (cdr cl-seq) (cddr cl-seq))) - (setq cl-seq (cdr cl-seq))) - begin)) - ((or (plists-equal cl-keys '(:test 'equal :from-end t) t) - (plists-equal cl-keys '(:test #'equal :from-end t) t)) - `(let* ((begin ,cl-seq) - (cl-seq begin)) - (while cl-seq - (setq cl-seq (setcdr cl-seq (delete (car cl-seq) - (cdr cl-seq))))) - begin)) - (t form)))) +(define-compiler-macro delete-duplicates (&whole form &rest cl-keys) + (let ((cl-seq (if cl-keys (pop cl-keys)))) + (if (or + (not (or (memq (car-safe cl-seq) + ;; No need to check for a list at runtime with + ;; these. We could expand the list, but these are all + ;; the functions in the relevant context at the moment. + '(nreverse append nconc mapcan mapcar string-to-list)) + (and (listp cl-seq) (equal (butlast cl-seq) '(the list))))) + ;; Wrong number of arguments. + (not (cdr form))) + form + (cond + ((or (plists-equal cl-keys '(:test 'eq) t) + (plists-equal cl-keys '(:test #'eq) t)) + `(let* ((begin ,cl-seq) + cl-seq) + (while (memq (car begin) (cdr begin)) + (setq begin (cdr begin))) + (setq cl-seq begin) + (while (cddr cl-seq) + (if (memq (cadr cl-seq) (cddr cl-seq)) + (setcdr (cdr cl-seq) (cddr cl-seq))) + (setq cl-seq (cdr cl-seq))) + begin)) + ((or (plists-equal cl-keys '(:test 'eq :from-end t) t) + (plists-equal cl-keys '(:test #'eq :from-end t) t)) + `(let* ((begin ,cl-seq) + (cl-seq begin)) + (while cl-seq + (setq cl-seq (setcdr cl-seq + (delq (car cl-seq) (cdr cl-seq))))) + begin)) + ((or (plists-equal cl-keys '(:test 'equal) t) + (plists-equal cl-keys '(:test #'equal) t)) + `(let* ((begin ,cl-seq) + cl-seq) + (while (member (car begin) (cdr begin)) + (setq begin (cdr begin))) + (setq cl-seq begin) + (while (cddr cl-seq) + (if (member (cadr cl-seq) (cddr cl-seq)) + (setcdr (cdr cl-seq) (cddr cl-seq))) + (setq cl-seq (cdr cl-seq))) + begin)) + ((or (plists-equal cl-keys '(:test 'equal :from-end t) t) + (plists-equal cl-keys '(:test #'equal :from-end t) t)) + `(let* ((begin ,cl-seq) + (cl-seq begin)) + (while cl-seq + (setq cl-seq (setcdr cl-seq (delete (car cl-seq) + (cdr cl-seq))))) + begin)) + (t form))))) ;; XEmacs; it's perfectly reasonable, and often much clearer to those ;; reading the code, to call regexp-quote on a constant string, which is @@ -3750,7 +3755,7 @@ (put function 'cl-compiler-macro #'(lambda (form &rest arguments) (if (or (null (nthcdr 3 form)) - (notevery #'cl-safe-expr-p (cdr form))) + (notevery #'cl-safe-expr-p (butlast (cdr arguments)))) form (cons 'and (mapcon #'(lambda (rest) @@ -3760,22 +3765,28 @@ (cdr form))))))) '(= < > <= >=)) -(mapc - #'(lambda (y) - (put (car y) 'side-effect-free t) - (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro) - (put (car y) 'cl-compiler-macro - (list 'lambda '(w x) - (if (symbolp (cadr y)) - (list 'list (list 'quote (cadr y)) - (list 'list (list 'quote (caddr y)) 'x)) - (cons 'list (cdr y)))))) - '((first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x) +;; XEmacs; unroll this loop at macro-expansion time, so the compiler macros +;; are byte-compiled. +(macrolet + ((inline-side-effect-free-compiler-macros (&rest details) + (cons + 'progn + (loop + for (function . details) in details + nconc `((put ',function 'side-effect-free t) + (define-compiler-macro ,function (&whole form x) + ,(if (symbolp (car details)) + (reduce #'(lambda (object1 object2) + `(list ',object1 ,object2)) + details :from-end t :initial-value 'x) + (cons 'list details)))))))) + (inline-side-effect-free-compiler-macros + (first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x) (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x) (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x) (rest 'cdr x) (plusp '> x 0) (minusp '< x 0) - (oddp 'eq (list 'logand x 1) 1) - (evenp 'eq (list 'logand x 1) 0) + (oddp 'eql (list 'logand x 1) 1) + (evenp 'eql (list 'logand x 1) 0) (caar car car) (cadr car cdr) (cdar cdr car) (cddr cdr cdr) (caaar car caar) (caadr car cadr) (cadar car cdar) (caddr car cddr) (cdaar cdr caar) (cdadr cdr cadr)