diff options
| author | Stefan Monnier | 2014-10-23 17:44:36 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-10-23 17:44:36 -0400 |
| commit | 864d69a119e50eaabb80076bf13e3a5b0c8815cd (patch) | |
| tree | df2392e9725d06a781642127cf1dad549e9dc117 | |
| parent | e77628bd580fe5a1345306a75853704b0b0d557c (diff) | |
| download | emacs-864d69a119e50eaabb80076bf13e3a5b0c8815cd.tar.gz emacs-864d69a119e50eaabb80076bf13e3a5b0c8815cd.zip | |
* lisp/emacs-lisp/cl-macs.el (cl-defstruct): Define an internal predicate
even if :predicate was nil, for the benefit of typep.
Record the name of the predicate for typep's use.
(cl--make-type-test): Use pcase. Obey new cl-deftype-satisfies property.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 102 |
2 files changed, 60 insertions, 48 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7c5b1ac06a0..ac556a3a0c8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | 2014-10-23 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2014-10-23 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/cl-macs.el (cl-defstruct): Define an internal predicate | ||
| 4 | even if :predicate was nil, for the benefit of typep. | ||
| 5 | Record the name of the predicate for typep's use. | ||
| 6 | (cl--make-type-test): Use pcase. Obey new | ||
| 7 | cl-deftype-satisfies property. | ||
| 8 | |||
| 3 | * epg.el: Use cl-defstruct. | 9 | * epg.el: Use cl-defstruct. |
| 4 | (epg-make-data-from-file, epg-make-data-from-string, epg-data-file) | 10 | (epg-make-data-from-file, epg-make-data-from-string, epg-data-file) |
| 5 | (epg-data-string): Define via cl-defstruct. | 11 | (epg-data-string): Define via cl-defstruct. |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 8336a2443da..e76c0a411b7 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2487,6 +2487,8 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2487 | (setq type 'vector named 'true))) | 2487 | (setq type 'vector named 'true))) |
| 2488 | (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) | 2488 | (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) |
| 2489 | (push `(defvar ,tag-symbol) forms) | 2489 | (push `(defvar ,tag-symbol) forms) |
| 2490 | (when (and (null predicate) named) | ||
| 2491 | (setq predicate (intern (format "cl--struct-%s-p" name)))) | ||
| 2490 | (setq pred-form (and named | 2492 | (setq pred-form (and named |
| 2491 | (let ((pos (- (length descs) | 2493 | (let ((pos (- (length descs) |
| 2492 | (length (memq (assq 'cl-tag-slot descs) | 2494 | (length (memq (assq 'cl-tag-slot descs) |
| @@ -2502,7 +2504,8 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2502 | pred-check (and pred-form (> safety 0) | 2504 | pred-check (and pred-form (> safety 0) |
| 2503 | (if (and (eq (cl-caadr pred-form) 'vectorp) | 2505 | (if (and (eq (cl-caadr pred-form) 'vectorp) |
| 2504 | (= safety 1)) | 2506 | (= safety 1)) |
| 2505 | (cons 'and (cl-cdddr pred-form)) pred-form))) | 2507 | (cons 'and (cl-cdddr pred-form)) |
| 2508 | `(,predicate cl-x)))) | ||
| 2506 | (let ((pos 0) (descp descs)) | 2509 | (let ((pos 0) (descp descs)) |
| 2507 | (while descp | 2510 | (while descp |
| 2508 | (let* ((desc (pop descp)) | 2511 | (let* ((desc (pop descp)) |
| @@ -2557,13 +2560,14 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2557 | (setq pos (1+ pos)))) | 2560 | (setq pos (1+ pos)))) |
| 2558 | (setq slots (nreverse slots) | 2561 | (setq slots (nreverse slots) |
| 2559 | defaults (nreverse defaults)) | 2562 | defaults (nreverse defaults)) |
| 2560 | (and predicate pred-form | 2563 | (when pred-form |
| 2561 | (progn (push `(cl-defsubst ,predicate (cl-x) | 2564 | (push `(cl-defsubst ,predicate (cl-x) |
| 2562 | ,(if (eq (car pred-form) 'and) | 2565 | ,(if (eq (car pred-form) 'and) |
| 2563 | (append pred-form '(t)) | 2566 | (append pred-form '(t)) |
| 2564 | `(and ,pred-form t))) | 2567 | `(and ,pred-form t))) |
| 2565 | forms) | 2568 | forms) |
| 2566 | (push (cons predicate 'error-free) side-eff))) | 2569 | (push `(put ',name 'cl-deftype-satisfies ',predicate) forms) |
| 2570 | (push (cons predicate 'error-free) side-eff)) | ||
| 2567 | (and copier | 2571 | (and copier |
| 2568 | (progn (push `(defun ,copier (x) (copy-sequence x)) forms) | 2572 | (progn (push `(defun ,copier (x) (copy-sequence x)) forms) |
| 2569 | (push (cons copier t) side-eff))) | 2573 | (push (cons copier t) side-eff))) |
| @@ -2647,46 +2651,48 @@ Of course, we really can't know that for sure, so it's just a heuristic." | |||
| 2647 | (cdr (assq sym byte-compile-macro-environment)))))) | 2651 | (cdr (assq sym byte-compile-macro-environment)))))) |
| 2648 | 2652 | ||
| 2649 | (defun cl--make-type-test (val type) | 2653 | (defun cl--make-type-test (val type) |
| 2650 | (if (symbolp type) | 2654 | (pcase type |
| 2651 | (cond ((get type 'cl-deftype-handler) | 2655 | ((and `(,name . ,args) (guard (get name 'cl-deftype-handler))) |
| 2652 | (cl--make-type-test val (funcall (get type 'cl-deftype-handler)))) | 2656 | (cl--make-type-test val (apply (get name 'cl-deftype-handler) |
| 2653 | ((memq type '(nil t)) type) | 2657 | args))) |
| 2654 | ((eq type 'null) `(null ,val)) | 2658 | (`(,(and name (or 'integer 'float 'real 'number)) |
| 2655 | ((eq type 'atom) `(atom ,val)) | 2659 | . ,(or `(,min ,max) pcase--dontcare)) |
| 2656 | ((eq type 'float) `(floatp ,val)) | 2660 | `(and ,(cl--make-type-test val name) |
| 2657 | ((eq type 'real) `(numberp ,val)) | 2661 | ,(if (memq min '(* nil)) t |
| 2658 | ((eq type 'fixnum) `(integerp ,val)) | 2662 | (if (consp min) `(> ,val ,(car min)) |
| 2659 | ;; FIXME: Should `character' accept things like ?\C-\M-a ? --Stef | 2663 | `(>= ,val ,min))) |
| 2660 | ((memq type '(character string-char)) `(characterp ,val)) | 2664 | ,(if (memq max '(* nil)) t |
| 2661 | (t | 2665 | (if (consp max) |
| 2662 | (let* ((name (symbol-name type)) | 2666 | `(< ,val ,(car max)) |
| 2663 | (namep (intern (concat name "p")))) | 2667 | `(<= ,val ,max))))) |
| 2664 | (cond | 2668 | (`(,(and name (or 'and 'or 'not)) . ,args) |
| 2665 | ((cl--macroexp-fboundp namep) (list namep val)) | 2669 | (cons name (mapcar (lambda (x) (cl--make-type-test val x)) args))) |
| 2666 | ((cl--macroexp-fboundp | 2670 | (`(member . ,args) |
| 2667 | (setq namep (intern (concat name "-p")))) | 2671 | `(and (cl-member ,val ',args) t)) |
| 2668 | (list namep val)) | 2672 | (`(satisfies ,pred) `(funcall #',pred ,val)) |
| 2669 | (t (list type val)))))) | 2673 | ((and (pred symbolp) (guard (get type 'cl-deftype-handler))) |
| 2670 | (cond ((get (car type) 'cl-deftype-handler) | 2674 | (cl--make-type-test val (funcall (get type 'cl-deftype-handler)))) |
| 2671 | (cl--make-type-test val (apply (get (car type) 'cl-deftype-handler) | 2675 | ((and (pred symbolp) (guard (get type 'cl-deftype-satisfies))) |
| 2672 | (cdr type)))) | 2676 | `(funcall #',(get type 'cl-deftype-satisfies) ,val)) |
| 2673 | ((memq (car type) '(integer float real number)) | 2677 | ((or 'nil 't) type) |
| 2674 | (delq t `(and ,(cl--make-type-test val (car type)) | 2678 | ('null `(null ,val)) |
| 2675 | ,(if (memq (cadr type) '(* nil)) t | 2679 | ('atom `(atom ,val)) |
| 2676 | (if (consp (cadr type)) `(> ,val ,(cl-caadr type)) | 2680 | ('float `(floatp ,val)) |
| 2677 | `(>= ,val ,(cadr type)))) | 2681 | ('real `(numberp ,val)) |
| 2678 | ,(if (memq (cl-caddr type) '(* nil)) t | 2682 | ('fixnum `(integerp ,val)) |
| 2679 | (if (consp (cl-caddr type)) | 2683 | ;; FIXME: Implement `base-char' and `extended-char'. |
| 2680 | `(< ,val ,(cl-caaddr type)) | 2684 | ('character `(characterp ,val)) |
| 2681 | `(<= ,val ,(cl-caddr type))))))) | 2685 | ((pred symbolp) |
| 2682 | ((memq (car type) '(and or not)) | 2686 | (let* ((name (symbol-name type)) |
| 2683 | (cons (car type) | 2687 | (namep (intern (concat name "p")))) |
| 2684 | (mapcar (function (lambda (x) (cl--make-type-test val x))) | 2688 | (cond |
| 2685 | (cdr type)))) | 2689 | ((cl--macroexp-fboundp namep) (list namep val)) |
| 2686 | ((memq (car type) '(member cl-member)) | 2690 | ((cl--macroexp-fboundp |
| 2687 | `(and (cl-member ,val ',(cdr type)) t)) | 2691 | (setq namep (intern (concat name "-p")))) |
| 2688 | ((eq (car type) 'satisfies) `(funcall #',(cadr type) ,val)) | 2692 | (list namep val)) |
| 2689 | (t (error "Bad type spec: %s" type))))) | 2693 | ((cl--macroexp-fboundp type) (list type val)) |
| 2694 | (t (error "Unknown type %S" type))))) | ||
| 2695 | (_ (error "Bad type spec: %s" type)))) | ||
| 2690 | 2696 | ||
| 2691 | (defvar cl--object) | 2697 | (defvar cl--object) |
| 2692 | ;;;###autoload | 2698 | ;;;###autoload |