Mercurial > emacs
comparison lisp/emacs-lisp/cl-macs.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | c2ff7876bd60 |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
1 ;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*- | 1 ;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*- |
2 | 2 |
3 ;; Copyright (C) 1993 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1993, 2003, 2004, 2005 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Dave Gillespie <daveg@synaptics.com> | 5 ;; Author: Dave Gillespie <daveg@synaptics.com> |
6 ;; Version: 2.02 | 6 ;; Version: 2.02 |
7 ;; Keywords: extensions | 7 ;; Keywords: extensions |
8 | 8 |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 ;; GNU General Public License for more details. | 19 ;; GNU General Public License for more details. |
20 | 20 |
21 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
24 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02110-1301, USA. |
25 | 25 |
26 ;;; Commentary: | 26 ;;; Commentary: |
27 | 27 |
28 ;; These are extensions to Emacs Lisp that provide a degree of | 28 ;; These are extensions to Emacs Lisp that provide a degree of |
29 ;; Common Lisp compatibility, beyond what is already built-in | 29 ;; Common Lisp compatibility, beyond what is already built-in |
162 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y)))) | 162 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y)))) |
163 | 163 |
164 ;;; Symbols. | 164 ;;; Symbols. |
165 | 165 |
166 (defvar *gensym-counter*) | 166 (defvar *gensym-counter*) |
167 (defun gensym (&optional arg) | 167 (defun gensym (&optional prefix) |
168 "Generate a new uninterned symbol. | 168 "Generate a new uninterned symbol. |
169 The name is made by appending a number to PREFIX, default \"G\"." | 169 The name is made by appending a number to PREFIX, default \"G\"." |
170 (let ((prefix (if (stringp arg) arg "G")) | 170 (let ((pfix (if (stringp prefix) prefix "G")) |
171 (num (if (integerp arg) arg | 171 (num (if (integerp prefix) prefix |
172 (prog1 *gensym-counter* | 172 (prog1 *gensym-counter* |
173 (setq *gensym-counter* (1+ *gensym-counter*)))))) | 173 (setq *gensym-counter* (1+ *gensym-counter*)))))) |
174 (make-symbol (format "%s%d" prefix num)))) | 174 (make-symbol (format "%s%d" pfix num)))) |
175 | 175 |
176 (defun gentemp (&optional arg) | 176 (defun gentemp (&optional prefix) |
177 "Generate a new interned symbol with a unique name. | 177 "Generate a new interned symbol with a unique name. |
178 The name is made by appending a number to PREFIX, default \"G\"." | 178 The name is made by appending a number to PREFIX, default \"G\"." |
179 (let ((prefix (if (stringp arg) arg "G")) | 179 (let ((pfix (if (stringp prefix) prefix "G")) |
180 name) | 180 name) |
181 (while (intern-soft (setq name (format "%s%d" prefix *gensym-counter*))) | 181 (while (intern-soft (setq name (format "%s%d" pfix *gensym-counter*))) |
182 (setq *gensym-counter* (1+ *gensym-counter*))) | 182 (setq *gensym-counter* (1+ *gensym-counter*))) |
183 (intern name))) | 183 (intern name))) |
184 | 184 |
185 | 185 |
186 ;;; Program structure. | 186 ;;; Program structure. |
205 (form (list* 'defmacro name (cdr res)))) | 205 (form (list* 'defmacro name (cdr res)))) |
206 (if (car res) (list 'progn (car res) form) form))) | 206 (if (car res) (list 'progn (car res) form) form))) |
207 | 207 |
208 (defmacro function* (func) | 208 (defmacro function* (func) |
209 "Introduce a function. | 209 "Introduce a function. |
210 Like normal `function', except that if argument is a lambda form, its | 210 Like normal `function', except that if argument is a lambda form, |
211 ARGLIST allows full Common Lisp conventions." | 211 its argument list allows full Common Lisp conventions." |
212 (if (eq (car-safe func) 'lambda) | 212 (if (eq (car-safe func) 'lambda) |
213 (let* ((res (cl-transform-lambda (cdr func) 'cl-none)) | 213 (let* ((res (cl-transform-lambda (cdr func) 'cl-none)) |
214 (form (list 'function (cons 'lambda (cdr res))))) | 214 (form (list 'function (cons 'lambda (cdr res))))) |
215 (if (car res) (list 'progn (car res) form) form)) | 215 (if (car res) (list 'progn (car res) form) form)) |
216 (list 'function func))) | 216 (list 'function func))) |
231 (defun cl-transform-lambda (form bind-block) | 231 (defun cl-transform-lambda (form bind-block) |
232 (let* ((args (car form)) (body (cdr form)) (orig-args args) | 232 (let* ((args (car form)) (body (cdr form)) (orig-args args) |
233 (bind-defs nil) (bind-enquote nil) | 233 (bind-defs nil) (bind-enquote nil) |
234 (bind-inits nil) (bind-lets nil) (bind-forms nil) | 234 (bind-inits nil) (bind-lets nil) (bind-forms nil) |
235 (header nil) (simple-args nil)) | 235 (header nil) (simple-args nil)) |
236 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive)) | 236 (while (or (stringp (car body)) |
237 (memq (car-safe (car body)) '(interactive declare))) | |
237 (push (pop body) header)) | 238 (push (pop body) header)) |
238 (setq args (if (listp args) (copy-list args) (list '&rest args))) | 239 (setq args (if (listp args) (copy-list args) (list '&rest args))) |
239 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) | 240 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) |
240 (if (setq bind-defs (cadr (memq '&cl-defs args))) | 241 (if (setq bind-defs (cadr (memq '&cl-defs args))) |
241 (setq args (delq '&cl-defs (delq bind-defs args)) | 242 (setq args (delq '&cl-defs (delq bind-defs args)) |
264 (nconc (nreverse simple-args) | 265 (nconc (nreverse simple-args) |
265 (list '&rest (car (pop bind-lets)))) | 266 (list '&rest (car (pop bind-lets)))) |
266 (nconc (let ((hdr (nreverse header))) | 267 (nconc (let ((hdr (nreverse header))) |
267 (require 'help-fns) | 268 (require 'help-fns) |
268 (cons (help-add-fundoc-usage | 269 (cons (help-add-fundoc-usage |
269 (if (stringp (car hdr)) (pop hdr)) orig-args) | 270 (if (stringp (car hdr)) (pop hdr)) |
271 ;; orig-args can contain &cl-defs (an internal CL | |
272 ;; thingy that I do not understand), so remove it. | |
273 (let ((x (memq '&cl-defs orig-args))) | |
274 (if (null x) orig-args | |
275 (delq (car x) (remq (cadr x) orig-args))))) | |
270 hdr)) | 276 hdr)) |
271 (list (nconc (list 'let* bind-lets) | 277 (list (nconc (list 'let* bind-lets) |
272 (nreverse bind-forms) body))))))) | 278 (nreverse bind-forms) body))))))) |
273 | 279 |
274 (defun cl-do-arglist (args expr &optional num) ; uses bind-* | 280 (defun cl-do-arglist (args expr &optional num) ; uses bind-* |
285 (safety (if (cl-compiling-file) cl-optimize-safety 3)) | 291 (safety (if (cl-compiling-file) cl-optimize-safety 3)) |
286 (keys nil) | 292 (keys nil) |
287 (laterarg nil) (exactarg nil) minarg) | 293 (laterarg nil) (exactarg nil) minarg) |
288 (or num (setq num 0)) | 294 (or num (setq num 0)) |
289 (if (listp (cadr restarg)) | 295 (if (listp (cadr restarg)) |
290 (setq restarg (gensym "--rest--")) | 296 (setq restarg (make-symbol "--cl-rest--")) |
291 (setq restarg (cadr restarg))) | 297 (setq restarg (cadr restarg))) |
292 (push (list restarg expr) bind-lets) | 298 (push (list restarg expr) bind-lets) |
293 (if (eq (car args) '&whole) | 299 (if (eq (car args) '&whole) |
294 (push (list (cl-pop2 args) restarg) bind-lets)) | 300 (push (list (cl-pop2 args) restarg) bind-lets)) |
295 (let ((p args)) | 301 (let ((p args)) |
347 (def (if (cdr arg) (cadr arg) | 353 (def (if (cdr arg) (cadr arg) |
348 (or (car bind-defs) (cadr (assq varg bind-defs))))) | 354 (or (car bind-defs) (cadr (assq varg bind-defs))))) |
349 (look (list 'memq (list 'quote karg) restarg))) | 355 (look (list 'memq (list 'quote karg) restarg))) |
350 (and def bind-enquote (setq def (list 'quote def))) | 356 (and def bind-enquote (setq def (list 'quote def))) |
351 (if (cddr arg) | 357 (if (cddr arg) |
352 (let* ((temp (or (nth 2 arg) (gensym))) | 358 (let* ((temp (or (nth 2 arg) (make-symbol "--cl-var--"))) |
353 (val (list 'car (list 'cdr temp)))) | 359 (val (list 'car (list 'cdr temp)))) |
354 (cl-do-arglist temp look) | 360 (cl-do-arglist temp look) |
355 (cl-do-arglist varg | 361 (cl-do-arglist varg |
356 (list 'if temp | 362 (list 'if temp |
357 (list 'prog1 val (list 'setq temp t)) | 363 (list 'prog1 val (list 'setq temp t)) |
370 (list 'list nil def)))))))) | 376 (list 'list nil def)))))))) |
371 (push karg keys))))) | 377 (push karg keys))))) |
372 (setq keys (nreverse keys)) | 378 (setq keys (nreverse keys)) |
373 (or (and (eq (car args) '&allow-other-keys) (pop args)) | 379 (or (and (eq (car args) '&allow-other-keys) (pop args)) |
374 (null keys) (= safety 0) | 380 (null keys) (= safety 0) |
375 (let* ((var (gensym "--keys--")) | 381 (let* ((var (make-symbol "--cl-keys--")) |
376 (allow '(:allow-other-keys)) | 382 (allow '(:allow-other-keys)) |
377 (check (list | 383 (check (list |
378 'while var | 384 'while var |
379 (list | 385 (list |
380 'cond | 386 'cond |
480 | 486 |
481 | 487 |
482 ;;; Conditional control structures. | 488 ;;; Conditional control structures. |
483 | 489 |
484 (defmacro case (expr &rest clauses) | 490 (defmacro case (expr &rest clauses) |
485 "Eval EXPR and choose from CLAUSES on that value. | 491 "Eval EXPR and choose among clauses on that value. |
486 Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared | 492 Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared |
487 against each key in each KEYLIST; the corresponding BODY is evaluated. | 493 against each key in each KEYLIST; the corresponding BODY is evaluated. |
488 If no clause succeeds, case returns nil. A single atom may be used in | 494 If no clause succeeds, case returns nil. A single atom may be used in |
489 place of a KEYLIST of one atom. A KEYLIST of `t' or `otherwise' is | 495 place of a KEYLIST of one atom. A KEYLIST of t or `otherwise' is |
490 allowed only in the final clause, and matches if no other keys match. | 496 allowed only in the final clause, and matches if no other keys match. |
491 Key values are compared by `eql'." | 497 Key values are compared by `eql'. |
492 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym))) | 498 \n(fn EXPR (KEYLIST BODY...)...)" |
499 (let* ((temp (if (cl-simple-expr-p expr 3) expr (make-symbol "--cl-var--"))) | |
493 (head-list nil) | 500 (head-list nil) |
494 (body (cons | 501 (body (cons |
495 'cond | 502 'cond |
496 (mapcar | 503 (mapcar |
497 (function | 504 (function |
514 (if (eq temp expr) body | 521 (if (eq temp expr) body |
515 (list 'let (list (list temp expr)) body)))) | 522 (list 'let (list (list temp expr)) body)))) |
516 | 523 |
517 (defmacro ecase (expr &rest clauses) | 524 (defmacro ecase (expr &rest clauses) |
518 "Like `case', but error if no case fits. | 525 "Like `case', but error if no case fits. |
519 `otherwise'-clauses are not allowed." | 526 `otherwise'-clauses are not allowed. |
527 \n(fn EXPR (KEYLIST BODY...)...)" | |
520 (list* 'case expr (append clauses '((ecase-error-flag))))) | 528 (list* 'case expr (append clauses '((ecase-error-flag))))) |
521 | 529 |
522 (defmacro typecase (expr &rest clauses) | 530 (defmacro typecase (expr &rest clauses) |
523 "Evals EXPR, chooses from CLAUSES on that value. | 531 "Evals EXPR, chooses among clauses on that value. |
524 Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it | 532 Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it |
525 satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds, | 533 satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds, |
526 typecase returns nil. A TYPE of `t' or `otherwise' is allowed only in the | 534 typecase returns nil. A TYPE of t or `otherwise' is allowed only in the |
527 final clause, and matches if no other keys match." | 535 final clause, and matches if no other keys match. |
528 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym))) | 536 \n(fn EXPR (TYPE BODY...)...)" |
537 (let* ((temp (if (cl-simple-expr-p expr 3) expr (make-symbol "--cl-var--"))) | |
529 (type-list nil) | 538 (type-list nil) |
530 (body (cons | 539 (body (cons |
531 'cond | 540 'cond |
532 (mapcar | 541 (mapcar |
533 (function | 542 (function |
544 (if (eq temp expr) body | 553 (if (eq temp expr) body |
545 (list 'let (list (list temp expr)) body)))) | 554 (list 'let (list (list temp expr)) body)))) |
546 | 555 |
547 (defmacro etypecase (expr &rest clauses) | 556 (defmacro etypecase (expr &rest clauses) |
548 "Like `typecase', but error if no case fits. | 557 "Like `typecase', but error if no case fits. |
549 `otherwise'-clauses are not allowed." | 558 `otherwise'-clauses are not allowed. |
559 \n(fn EXPR (TYPE BODY...)...)" | |
550 (list* 'typecase expr (append clauses '((ecase-error-flag))))) | 560 (list* 'typecase expr (append clauses '((ecase-error-flag))))) |
551 | 561 |
552 | 562 |
553 ;;; Blocks and exits. | 563 ;;; Blocks and exits. |
554 | 564 |
637 (loop-map-form nil) (loop-first-flag nil) | 647 (loop-map-form nil) (loop-first-flag nil) |
638 (loop-destr-temps nil) (loop-symbol-macs nil)) | 648 (loop-destr-temps nil) (loop-symbol-macs nil)) |
639 (setq args (append args '(cl-end-loop))) | 649 (setq args (append args '(cl-end-loop))) |
640 (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause)) | 650 (while (not (eq (car args) 'cl-end-loop)) (cl-parse-loop-clause)) |
641 (if loop-finish-flag | 651 (if loop-finish-flag |
642 (push (list (list loop-finish-flag t)) loop-bindings)) | 652 (push `((,loop-finish-flag t)) loop-bindings)) |
643 (if loop-first-flag | 653 (if loop-first-flag |
644 (progn (push (list (list loop-first-flag t)) loop-bindings) | 654 (progn (push `((,loop-first-flag t)) loop-bindings) |
645 (push (list 'setq loop-first-flag nil) loop-steps))) | 655 (push `(setq ,loop-first-flag nil) loop-steps))) |
646 (let* ((epilogue (nconc (nreverse loop-finally) | 656 (let* ((epilogue (nconc (nreverse loop-finally) |
647 (list (or loop-result-explicit loop-result)))) | 657 (list (or loop-result-explicit loop-result)))) |
648 (ands (cl-loop-build-ands (nreverse loop-body))) | 658 (ands (cl-loop-build-ands (nreverse loop-body))) |
649 (while-body (nconc (cadr ands) (nreverse loop-steps))) | 659 (while-body (nconc (cadr ands) (nreverse loop-steps))) |
650 (body (append | 660 (body (append |
651 (nreverse loop-initially) | 661 (nreverse loop-initially) |
652 (list (if loop-map-form | 662 (list (if loop-map-form |
653 (list 'block '--cl-finish-- | 663 (list 'block '--cl-finish-- |
654 (subst | 664 (subst |
655 (if (eq (car ands) t) while-body | 665 (if (eq (car ands) t) while-body |
656 (cons (list 'or (car ands) | 666 (cons `(or ,(car ands) |
657 '(return-from --cl-finish-- | 667 (return-from --cl-finish-- |
658 nil)) | 668 nil)) |
659 while-body)) | 669 while-body)) |
660 '--cl-map loop-map-form)) | 670 '--cl-map loop-map-form)) |
661 (list* 'while (car ands) while-body))) | 671 (list* 'while (car ands) while-body))) |
662 (if loop-finish-flag | 672 (if loop-finish-flag |
663 (if (equal epilogue '(nil)) (list loop-result-var) | 673 (if (equal epilogue '(nil)) (list loop-result-var) |
664 (list (list 'if loop-finish-flag | 674 `((if ,loop-finish-flag |
665 (cons 'progn epilogue) loop-result-var))) | 675 (progn ,@epilogue) ,loop-result-var))) |
666 epilogue)))) | 676 epilogue)))) |
667 (if loop-result-var (push (list loop-result-var) loop-bindings)) | 677 (if loop-result-var (push (list loop-result-var) loop-bindings)) |
668 (while loop-bindings | 678 (while loop-bindings |
669 (if (cdar loop-bindings) | 679 (if (cdar loop-bindings) |
670 (setq body (list (cl-loop-let (pop loop-bindings) body t))) | 680 (setq body (list (cl-loop-let (pop loop-bindings) body t))) |
675 (setq body (list (cl-loop-let lets body nil)))))) | 685 (setq body (list (cl-loop-let lets body nil)))))) |
676 (if loop-symbol-macs | 686 (if loop-symbol-macs |
677 (setq body (list (list* 'symbol-macrolet loop-symbol-macs body)))) | 687 (setq body (list (list* 'symbol-macrolet loop-symbol-macs body)))) |
678 (list* 'block loop-name body))))) | 688 (list* 'block loop-name body))))) |
679 | 689 |
680 (defun cl-parse-loop-clause () ; uses args, loop-* | 690 (defun cl-parse-loop-clause () ; uses args, loop-* |
681 (let ((word (pop args)) | 691 (let ((word (pop args)) |
682 (hash-types '(hash-key hash-keys hash-value hash-values)) | 692 (hash-types '(hash-key hash-keys hash-value hash-values)) |
683 (key-types '(key-code key-codes key-seq key-seqs | 693 (key-types '(key-code key-codes key-seq key-seqs |
684 key-binding key-bindings))) | 694 key-binding key-bindings))) |
685 (cond | 695 (cond |
708 | 718 |
709 ((memq word '(for as)) | 719 ((memq word '(for as)) |
710 (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil) | 720 (let ((loop-for-bindings nil) (loop-for-sets nil) (loop-for-steps nil) |
711 (ands nil)) | 721 (ands nil)) |
712 (while | 722 (while |
713 (let ((var (or (pop args) (gensym)))) | 723 ;; Use `gensym' rather than `make-symbol'. It's important that |
724 ;; (not (eq (symbol-name var1) (symbol-name var2))) because | |
725 ;; these vars get added to the cl-macro-environment. | |
726 (let ((var (or (pop args) (gensym "--cl-var--")))) | |
714 (setq word (pop args)) | 727 (setq word (pop args)) |
715 (if (eq word 'being) (setq word (pop args))) | 728 (if (eq word 'being) (setq word (pop args))) |
716 (if (memq word '(the each)) (setq word (pop args))) | 729 (if (memq word '(the each)) (setq word (pop args))) |
717 (if (memq word '(buffer buffers)) | 730 (if (memq word '(buffer buffers)) |
718 (setq word 'in args (cons '(buffer-list) args))) | 731 (setq word 'in args (cons '(buffer-list) args))) |
731 (cl-pop2 args))) | 744 (cl-pop2 args))) |
732 (end (and (memq (car args) | 745 (end (and (memq (car args) |
733 '(to upto downto above below)) | 746 '(to upto downto above below)) |
734 (cl-pop2 args))) | 747 (cl-pop2 args))) |
735 (step (and (eq (car args) 'by) (cl-pop2 args))) | 748 (step (and (eq (car args) 'by) (cl-pop2 args))) |
736 (end-var (and (not (cl-const-expr-p end)) (gensym))) | 749 (end-var (and (not (cl-const-expr-p end)) |
750 (make-symbol "--cl-var--"))) | |
737 (step-var (and (not (cl-const-expr-p step)) | 751 (step-var (and (not (cl-const-expr-p step)) |
738 (gensym)))) | 752 (make-symbol "--cl-var--")))) |
739 (and step (numberp step) (<= step 0) | 753 (and step (numberp step) (<= step 0) |
740 (error "Loop `by' value is not positive: %s" step)) | 754 (error "Loop `by' value is not positive: %s" step)) |
741 (push (list var (or start 0)) loop-for-bindings) | 755 (push (list var (or start 0)) loop-for-bindings) |
742 (if end-var (push (list end-var end) loop-for-bindings)) | 756 (if end-var (push (list end-var end) loop-for-bindings)) |
743 (if step-var (push (list step-var step) | 757 (if step-var (push (list step-var step) |
744 loop-for-bindings)) | 758 loop-for-bindings)) |
745 (if end | 759 (if end |
746 (push (list | 760 (push (list |
747 (if down (if excl '> '>=) (if excl '< '<=)) | 761 (if down (if excl '> '>=) (if excl '< '<=)) |
748 var (or end-var end)) loop-body)) | 762 var (or end-var end)) loop-body)) |
749 (push (list var (list (if down '- '+) var | 763 (push (list var (list (if down '- '+) var |
750 (or step-var step 1))) | 764 (or step-var step 1))) |
751 loop-for-steps))) | 765 loop-for-steps))) |
752 | 766 |
753 ((memq word '(in in-ref on)) | 767 ((memq word '(in in-ref on)) |
754 (let* ((on (eq word 'on)) | 768 (let* ((on (eq word 'on)) |
755 (temp (if (and on (symbolp var)) var (gensym)))) | 769 (temp (if (and on (symbolp var)) |
770 var (make-symbol "--cl-var--")))) | |
756 (push (list temp (pop args)) loop-for-bindings) | 771 (push (list temp (pop args)) loop-for-bindings) |
757 (push (list 'consp temp) loop-body) | 772 (push (list 'consp temp) loop-body) |
758 (if (eq word 'in-ref) | 773 (if (eq word 'in-ref) |
759 (push (list var (list 'car temp)) loop-symbol-macs) | 774 (push (list var (list 'car temp)) loop-symbol-macs) |
760 (or (eq temp var) | 775 (or (eq temp var) |
761 (progn | 776 (progn |
762 (push (list var nil) loop-for-bindings) | 777 (push (list var nil) loop-for-bindings) |
763 (push (list var (if on temp (list 'car temp))) | 778 (push (list var (if on temp (list 'car temp))) |
764 loop-for-sets)))) | 779 loop-for-sets)))) |
765 (push (list temp | 780 (push (list temp |
766 (if (eq (car args) 'by) | 781 (if (eq (car args) 'by) |
767 (let ((step (cl-pop2 args))) | 782 (let ((step (cl-pop2 args))) |
768 (if (and (memq (car-safe step) | 783 (if (and (memq (car-safe step) |
769 '(quote function | 784 '(quote function |
770 function*)) | 785 function*)) |
771 (symbolp (nth 1 step))) | 786 (symbolp (nth 1 step))) |
772 (list (nth 1 step) temp) | 787 (list (nth 1 step) temp) |
773 (list 'funcall step temp))) | 788 (list 'funcall step temp))) |
774 (list 'cdr temp))) | 789 (list 'cdr temp))) |
775 loop-for-steps))) | 790 loop-for-steps))) |
776 | 791 |
777 ((eq word '=) | 792 ((eq word '=) |
778 (let* ((start (pop args)) | 793 (let* ((start (pop args)) |
779 (then (if (eq (car args) 'then) (cl-pop2 args) start))) | 794 (then (if (eq (car args) 'then) (cl-pop2 args) start))) |
780 (push (list var nil) loop-for-bindings) | 795 (push (list var nil) loop-for-bindings) |
781 (if (or ands (eq (car args) 'and)) | 796 (if (or ands (eq (car args) 'and)) |
782 (progn | 797 (progn |
783 (push (list var | 798 (push `(,var |
784 (list 'if | 799 (if ,(or loop-first-flag |
785 (or loop-first-flag | 800 (setq loop-first-flag |
786 (setq loop-first-flag | 801 (make-symbol "--cl-var--"))) |
787 (gensym))) | 802 ,start ,var)) |
788 start var)) | 803 loop-for-sets) |
789 loop-for-sets) | |
790 (push (list var then) loop-for-steps)) | 804 (push (list var then) loop-for-steps)) |
791 (push (list var | 805 (push (list var |
792 (if (eq start then) start | 806 (if (eq start then) start |
793 (list 'if | 807 `(if ,(or loop-first-flag |
794 (or loop-first-flag | 808 (setq loop-first-flag |
795 (setq loop-first-flag (gensym))) | 809 (make-symbol "--cl-var--"))) |
796 start then))) | 810 ,start ,then))) |
797 loop-for-sets)))) | 811 loop-for-sets)))) |
798 | 812 |
799 ((memq word '(across across-ref)) | 813 ((memq word '(across across-ref)) |
800 (let ((temp-vec (gensym)) (temp-idx (gensym))) | 814 (let ((temp-vec (make-symbol "--cl-vec--")) |
815 (temp-idx (make-symbol "--cl-idx--"))) | |
801 (push (list temp-vec (pop args)) loop-for-bindings) | 816 (push (list temp-vec (pop args)) loop-for-bindings) |
802 (push (list temp-idx -1) loop-for-bindings) | 817 (push (list temp-idx -1) loop-for-bindings) |
803 (push (list '< (list 'setq temp-idx (list '1+ temp-idx)) | 818 (push (list '< (list 'setq temp-idx (list '1+ temp-idx)) |
804 (list 'length temp-vec)) loop-body) | 819 (list 'length temp-vec)) loop-body) |
805 (if (eq word 'across-ref) | 820 (if (eq word 'across-ref) |
806 (push (list var (list 'aref temp-vec temp-idx)) | 821 (push (list var (list 'aref temp-vec temp-idx)) |
807 loop-symbol-macs) | 822 loop-symbol-macs) |
808 (push (list var nil) loop-for-bindings) | 823 (push (list var nil) loop-for-bindings) |
809 (push (list var (list 'aref temp-vec temp-idx)) | 824 (push (list var (list 'aref temp-vec temp-idx)) |
810 loop-for-sets)))) | 825 loop-for-sets)))) |
811 | 826 |
812 ((memq word '(element elements)) | 827 ((memq word '(element elements)) |
813 (let ((ref (or (memq (car args) '(in-ref of-ref)) | 828 (let ((ref (or (memq (car args) '(in-ref of-ref)) |
814 (and (not (memq (car args) '(in of))) | 829 (and (not (memq (car args) '(in of))) |
815 (error "Expected `of'")))) | 830 (error "Expected `of'")))) |
816 (seq (cl-pop2 args)) | 831 (seq (cl-pop2 args)) |
817 (temp-seq (gensym)) | 832 (temp-seq (make-symbol "--cl-seq--")) |
818 (temp-idx (if (eq (car args) 'using) | 833 (temp-idx (if (eq (car args) 'using) |
819 (if (and (= (length (cadr args)) 2) | 834 (if (and (= (length (cadr args)) 2) |
820 (eq (caadr args) 'index)) | 835 (eq (caadr args) 'index)) |
821 (cadr (cl-pop2 args)) | 836 (cadr (cl-pop2 args)) |
822 (error "Bad `using' clause")) | 837 (error "Bad `using' clause")) |
823 (gensym)))) | 838 (make-symbol "--cl-idx--")))) |
824 (push (list temp-seq seq) loop-for-bindings) | 839 (push (list temp-seq seq) loop-for-bindings) |
825 (push (list temp-idx 0) loop-for-bindings) | 840 (push (list temp-idx 0) loop-for-bindings) |
826 (if ref | 841 (if ref |
827 (let ((temp-len (gensym))) | 842 (let ((temp-len (make-symbol "--cl-len--"))) |
828 (push (list temp-len (list 'length temp-seq)) | 843 (push (list temp-len (list 'length temp-seq)) |
829 loop-for-bindings) | 844 loop-for-bindings) |
830 (push (list var (list 'elt temp-seq temp-idx)) | 845 (push (list var (list 'elt temp-seq temp-idx)) |
831 loop-symbol-macs) | 846 loop-symbol-macs) |
832 (push (list '< temp-idx temp-len) loop-body)) | 847 (push (list '< temp-idx temp-len) loop-body)) |
833 (push (list var nil) loop-for-bindings) | 848 (push (list var nil) loop-for-bindings) |
834 (push (list 'and temp-seq | 849 (push (list 'and temp-seq |
835 (list 'or (list 'consp temp-seq) | 850 (list 'or (list 'consp temp-seq) |
836 (list '< temp-idx | 851 (list '< temp-idx |
837 (list 'length temp-seq)))) | 852 (list 'length temp-seq)))) |
838 loop-body) | 853 loop-body) |
839 (push (list var (list 'if (list 'consp temp-seq) | 854 (push (list var (list 'if (list 'consp temp-seq) |
840 (list 'pop temp-seq) | 855 (list 'pop temp-seq) |
841 (list 'aref temp-seq temp-idx))) | 856 (list 'aref temp-seq temp-idx))) |
842 loop-for-sets)) | 857 loop-for-sets)) |
843 (push (list temp-idx (list '1+ temp-idx)) | 858 (push (list temp-idx (list '1+ temp-idx)) |
844 loop-for-steps))) | 859 loop-for-steps))) |
845 | 860 |
846 ((memq word hash-types) | 861 ((memq word hash-types) |
847 (or (memq (car args) '(in of)) (error "Expected `of'")) | 862 (or (memq (car args) '(in of)) (error "Expected `of'")) |
848 (let* ((table (cl-pop2 args)) | 863 (let* ((table (cl-pop2 args)) |
849 (other (if (eq (car args) 'using) | 864 (other (if (eq (car args) 'using) |
850 (if (and (= (length (cadr args)) 2) | 865 (if (and (= (length (cadr args)) 2) |
851 (memq (caadr args) hash-types) | 866 (memq (caadr args) hash-types) |
852 (not (eq (caadr args) word))) | 867 (not (eq (caadr args) word))) |
853 (cadr (cl-pop2 args)) | 868 (cadr (cl-pop2 args)) |
854 (error "Bad `using' clause")) | 869 (error "Bad `using' clause")) |
855 (gensym)))) | 870 (make-symbol "--cl-var--")))) |
856 (if (memq word '(hash-value hash-values)) | 871 (if (memq word '(hash-value hash-values)) |
857 (setq var (prog1 other (setq other var)))) | 872 (setq var (prog1 other (setq other var)))) |
858 (setq loop-map-form | 873 (setq loop-map-form |
859 (list 'maphash (list 'function | 874 `(maphash (lambda (,var ,other) . --cl-map) ,table)))) |
860 (list* 'lambda (list var other) | |
861 '--cl-map)) table)))) | |
862 | 875 |
863 ((memq word '(symbol present-symbol external-symbol | 876 ((memq word '(symbol present-symbol external-symbol |
864 symbols present-symbols external-symbols)) | 877 symbols present-symbols external-symbols)) |
865 (let ((ob (and (memq (car args) '(in of)) (cl-pop2 args)))) | 878 (let ((ob (and (memq (car args) '(in of)) (cl-pop2 args)))) |
866 (setq loop-map-form | 879 (setq loop-map-form |
867 (list 'mapatoms (list 'function | 880 `(mapatoms (lambda (,var) . --cl-map) ,ob)))) |
868 (list* 'lambda (list var) | |
869 '--cl-map)) ob)))) | |
870 | 881 |
871 ((memq word '(overlay overlays extent extents)) | 882 ((memq word '(overlay overlays extent extents)) |
872 (let ((buf nil) (from nil) (to nil)) | 883 (let ((buf nil) (from nil) (to nil)) |
873 (while (memq (car args) '(in of from to)) | 884 (while (memq (car args) '(in of from to)) |
874 (cond ((eq (car args) 'from) (setq from (cl-pop2 args))) | 885 (cond ((eq (car args) 'from) (setq from (cl-pop2 args))) |
875 ((eq (car args) 'to) (setq to (cl-pop2 args))) | 886 ((eq (car args) 'to) (setq to (cl-pop2 args))) |
876 (t (setq buf (cl-pop2 args))))) | 887 (t (setq buf (cl-pop2 args))))) |
877 (setq loop-map-form | 888 (setq loop-map-form |
878 (list 'cl-map-extents | 889 `(cl-map-extents |
879 (list 'function (list 'lambda (list var (gensym)) | 890 (lambda (,var ,(make-symbol "--cl-var--")) |
880 '(progn . --cl-map) nil)) | 891 (progn . --cl-map) nil) |
881 buf from to)))) | 892 ,buf ,from ,to)))) |
882 | 893 |
883 ((memq word '(interval intervals)) | 894 ((memq word '(interval intervals)) |
884 (let ((buf nil) (prop nil) (from nil) (to nil) | 895 (let ((buf nil) (prop nil) (from nil) (to nil) |
885 (var1 (gensym)) (var2 (gensym))) | 896 (var1 (make-symbol "--cl-var1--")) |
897 (var2 (make-symbol "--cl-var2--"))) | |
886 (while (memq (car args) '(in of property from to)) | 898 (while (memq (car args) '(in of property from to)) |
887 (cond ((eq (car args) 'from) (setq from (cl-pop2 args))) | 899 (cond ((eq (car args) 'from) (setq from (cl-pop2 args))) |
888 ((eq (car args) 'to) (setq to (cl-pop2 args))) | 900 ((eq (car args) 'to) (setq to (cl-pop2 args))) |
889 ((eq (car args) 'property) | 901 ((eq (car args) 'property) |
890 (setq prop (cl-pop2 args))) | 902 (setq prop (cl-pop2 args))) |
891 (t (setq buf (cl-pop2 args))))) | 903 (t (setq buf (cl-pop2 args))))) |
892 (if (and (consp var) (symbolp (car var)) (symbolp (cdr var))) | 904 (if (and (consp var) (symbolp (car var)) (symbolp (cdr var))) |
893 (setq var1 (car var) var2 (cdr var)) | 905 (setq var1 (car var) var2 (cdr var)) |
894 (push (list var (list 'cons var1 var2)) loop-for-sets)) | 906 (push (list var (list 'cons var1 var2)) loop-for-sets)) |
895 (setq loop-map-form | 907 (setq loop-map-form |
896 (list 'cl-map-intervals | 908 `(cl-map-intervals |
897 (list 'function (list 'lambda (list var1 var2) | 909 (lambda (,var1 ,var2) . --cl-map) |
898 '(progn . --cl-map))) | 910 ,buf ,prop ,from ,to)))) |
899 buf prop from to)))) | |
900 | 911 |
901 ((memq word key-types) | 912 ((memq word key-types) |
902 (or (memq (car args) '(in of)) (error "Expected `of'")) | 913 (or (memq (car args) '(in of)) (error "Expected `of'")) |
903 (let ((map (cl-pop2 args)) | 914 (let ((map (cl-pop2 args)) |
904 (other (if (eq (car args) 'using) | 915 (other (if (eq (car args) 'using) |
905 (if (and (= (length (cadr args)) 2) | 916 (if (and (= (length (cadr args)) 2) |
906 (memq (caadr args) key-types) | 917 (memq (caadr args) key-types) |
907 (not (eq (caadr args) word))) | 918 (not (eq (caadr args) word))) |
908 (cadr (cl-pop2 args)) | 919 (cadr (cl-pop2 args)) |
909 (error "Bad `using' clause")) | 920 (error "Bad `using' clause")) |
910 (gensym)))) | 921 (make-symbol "--cl-var--")))) |
911 (if (memq word '(key-binding key-bindings)) | 922 (if (memq word '(key-binding key-bindings)) |
912 (setq var (prog1 other (setq other var)))) | 923 (setq var (prog1 other (setq other var)))) |
913 (setq loop-map-form | 924 (setq loop-map-form |
914 (list (if (memq word '(key-seq key-seqs)) | 925 `(,(if (memq word '(key-seq key-seqs)) |
915 'cl-map-keymap-recursively 'cl-map-keymap) | 926 'cl-map-keymap-recursively 'map-keymap) |
916 (list 'function (list* 'lambda (list var other) | 927 (lambda (,var ,other) . --cl-map) ,map)))) |
917 '--cl-map)) map)))) | |
918 | 928 |
919 ((memq word '(frame frames screen screens)) | 929 ((memq word '(frame frames screen screens)) |
920 (let ((temp (gensym))) | 930 (let ((temp (make-symbol "--cl-var--"))) |
921 (push (list var '(selected-frame)) | 931 (push (list var '(selected-frame)) |
922 loop-for-bindings) | 932 loop-for-bindings) |
923 (push (list temp nil) loop-for-bindings) | 933 (push (list temp nil) loop-for-bindings) |
924 (push (list 'prog1 (list 'not (list 'eq var temp)) | 934 (push (list 'prog1 (list 'not (list 'eq var temp)) |
925 (list 'or temp (list 'setq temp var))) | 935 (list 'or temp (list 'setq temp var))) |
926 loop-body) | 936 loop-body) |
927 (push (list var (list 'next-frame var)) | 937 (push (list var (list 'next-frame var)) |
928 loop-for-steps))) | 938 loop-for-steps))) |
929 | 939 |
930 ((memq word '(window windows)) | 940 ((memq word '(window windows)) |
931 (let ((scr (and (memq (car args) '(in of)) (cl-pop2 args))) | 941 (let ((scr (and (memq (car args) '(in of)) (cl-pop2 args))) |
932 (temp (gensym))) | 942 (temp (make-symbol "--cl-var--"))) |
933 (push (list var (if scr | 943 (push (list var (if scr |
934 (list 'frame-selected-window scr) | 944 (list 'frame-selected-window scr) |
935 '(selected-window))) | 945 '(selected-window))) |
936 loop-for-bindings) | 946 loop-for-bindings) |
937 (push (list temp nil) loop-for-bindings) | 947 (push (list temp nil) loop-for-bindings) |
938 (push (list 'prog1 (list 'not (list 'eq var temp)) | 948 (push (list 'prog1 (list 'not (list 'eq var temp)) |
939 (list 'or temp (list 'setq temp var))) | 949 (list 'or temp (list 'setq temp var))) |
940 loop-body) | 950 loop-body) |
941 (push (list var (list 'next-window var)) loop-for-steps))) | 951 (push (list var (list 'next-window var)) loop-for-steps))) |
942 | 952 |
943 (t | 953 (t |
944 (let ((handler (and (symbolp word) | 954 (let ((handler (and (symbolp word) |
945 (get word 'cl-loop-for-handler)))) | 955 (get word 'cl-loop-for-handler)))) |
953 (push (nreverse loop-for-bindings) loop-bindings) | 963 (push (nreverse loop-for-bindings) loop-bindings) |
954 (setq loop-bindings (nconc (mapcar 'list loop-for-bindings) | 964 (setq loop-bindings (nconc (mapcar 'list loop-for-bindings) |
955 loop-bindings))) | 965 loop-bindings))) |
956 (if loop-for-sets | 966 (if loop-for-sets |
957 (push (list 'progn | 967 (push (list 'progn |
958 (cl-loop-let (nreverse loop-for-sets) 'setq ands) | 968 (cl-loop-let (nreverse loop-for-sets) 'setq ands) |
959 t) loop-body)) | 969 t) loop-body)) |
960 (if loop-for-steps | 970 (if loop-for-steps |
961 (push (cons (if ands 'psetq 'setq) | 971 (push (cons (if ands 'psetq 'setq) |
962 (apply 'append (nreverse loop-for-steps))) | 972 (apply 'append (nreverse loop-for-steps))) |
963 loop-steps)))) | 973 loop-steps)))) |
964 | 974 |
965 ((eq word 'repeat) | 975 ((eq word 'repeat) |
966 (let ((temp (gensym))) | 976 (let ((temp (make-symbol "--cl-var--"))) |
967 (push (list (list temp (pop args))) loop-bindings) | 977 (push (list (list temp (pop args))) loop-bindings) |
968 (push (list '>= (list 'setq temp (list '1- temp)) 0) loop-body))) | 978 (push (list '>= (list 'setq temp (list '1- temp)) 0) loop-body))) |
969 | 979 |
970 ((memq word '(collect collecting)) | 980 ((memq word '(collect collecting)) |
971 (let ((what (pop args)) | 981 (let ((what (pop args)) |
972 (var (cl-loop-handle-accum nil 'nreverse))) | 982 (var (cl-loop-handle-accum nil 'nreverse))) |
973 (if (eq var loop-accum-var) | 983 (if (eq var loop-accum-var) |
974 (push (list 'progn (list 'push what var) t) loop-body) | 984 (push (list 'progn (list 'push what var) t) loop-body) |
975 (push (list 'progn | 985 (push (list 'progn |
976 (list 'setq var (list 'nconc var (list 'list what))) | 986 (list 'setq var (list 'nconc var (list 'list what))) |
977 t) loop-body)))) | 987 t) loop-body)))) |
978 | 988 |
979 ((memq word '(nconc nconcing append appending)) | 989 ((memq word '(nconc nconcing append appending)) |
980 (let ((what (pop args)) | 990 (let ((what (pop args)) |
981 (var (cl-loop-handle-accum nil 'nreverse))) | 991 (var (cl-loop-handle-accum nil 'nreverse))) |
982 (push (list 'progn | 992 (push (list 'progn |
983 (list 'setq var | 993 (list 'setq var |
984 (if (eq var loop-accum-var) | 994 (if (eq var loop-accum-var) |
985 (list 'nconc | 995 (list 'nconc |
986 (list (if (memq word '(nconc nconcing)) | 996 (list (if (memq word '(nconc nconcing)) |
987 'nreverse 'reverse) | 997 'nreverse 'reverse) |
988 what) | 998 what) |
989 var) | 999 var) |
990 (list (if (memq word '(nconc nconcing)) | 1000 (list (if (memq word '(nconc nconcing)) |
991 'nconc 'append) | 1001 'nconc 'append) |
992 var what))) t) loop-body))) | 1002 var what))) t) loop-body))) |
993 | 1003 |
994 ((memq word '(concat concating)) | 1004 ((memq word '(concat concating)) |
995 (let ((what (pop args)) | 1005 (let ((what (pop args)) |
996 (var (cl-loop-handle-accum ""))) | 1006 (var (cl-loop-handle-accum ""))) |
997 (push (list 'progn (list 'callf 'concat var what) t) loop-body))) | 1007 (push (list 'progn (list 'callf 'concat var what) t) loop-body))) |
1011 (var (cl-loop-handle-accum 0))) | 1021 (var (cl-loop-handle-accum 0))) |
1012 (push (list 'progn (list 'if what (list 'incf var)) t) loop-body))) | 1022 (push (list 'progn (list 'if what (list 'incf var)) t) loop-body))) |
1013 | 1023 |
1014 ((memq word '(minimize minimizing maximize maximizing)) | 1024 ((memq word '(minimize minimizing maximize maximizing)) |
1015 (let* ((what (pop args)) | 1025 (let* ((what (pop args)) |
1016 (temp (if (cl-simple-expr-p what) what (gensym))) | 1026 (temp (if (cl-simple-expr-p what) what (make-symbol "--cl-var--"))) |
1017 (var (cl-loop-handle-accum nil)) | 1027 (var (cl-loop-handle-accum nil)) |
1018 (func (intern (substring (symbol-name word) 0 3))) | 1028 (func (intern (substring (symbol-name word) 0 3))) |
1019 (set (list 'setq var (list 'if var (list func var temp) temp)))) | 1029 (set (list 'setq var (list 'if var (list func var temp) temp)))) |
1020 (push (list 'progn (if (eq temp what) set | 1030 (push (list 'progn (if (eq temp what) set |
1021 (list 'let (list (list temp what)) set)) | 1031 (list 'let (list (list temp what)) set)) |
1022 t) loop-body))) | 1032 t) loop-body))) |
1023 | 1033 |
1024 ((eq word 'with) | 1034 ((eq word 'with) |
1025 (let ((bindings nil)) | 1035 (let ((bindings nil)) |
1026 (while (progn (push (list (pop args) | 1036 (while (progn (push (list (pop args) |
1027 (and (eq (car args) '=) (cl-pop2 args))) | 1037 (and (eq (car args) '=) (cl-pop2 args))) |
1028 bindings) | 1038 bindings) |
1029 (eq (car args) 'and)) | 1039 (eq (car args) 'and)) |
1030 (pop args)) | 1040 (pop args)) |
1031 (push (nreverse bindings) loop-bindings))) | 1041 (push (nreverse bindings) loop-bindings))) |
1032 | 1042 |
1033 ((eq word 'while) | 1043 ((eq word 'while) |
1035 | 1045 |
1036 ((eq word 'until) | 1046 ((eq word 'until) |
1037 (push (list 'not (pop args)) loop-body)) | 1047 (push (list 'not (pop args)) loop-body)) |
1038 | 1048 |
1039 ((eq word 'always) | 1049 ((eq word 'always) |
1040 (or loop-finish-flag (setq loop-finish-flag (gensym))) | 1050 (or loop-finish-flag (setq loop-finish-flag (make-symbol "--cl-flag--"))) |
1041 (push (list 'setq loop-finish-flag (pop args)) loop-body) | 1051 (push (list 'setq loop-finish-flag (pop args)) loop-body) |
1042 (setq loop-result t)) | 1052 (setq loop-result t)) |
1043 | 1053 |
1044 ((eq word 'never) | 1054 ((eq word 'never) |
1045 (or loop-finish-flag (setq loop-finish-flag (gensym))) | 1055 (or loop-finish-flag (setq loop-finish-flag (make-symbol "--cl-flag--"))) |
1046 (push (list 'setq loop-finish-flag (list 'not (pop args))) | 1056 (push (list 'setq loop-finish-flag (list 'not (pop args))) |
1047 loop-body) | 1057 loop-body) |
1048 (setq loop-result t)) | 1058 (setq loop-result t)) |
1049 | 1059 |
1050 ((eq word 'thereis) | 1060 ((eq word 'thereis) |
1051 (or loop-finish-flag (setq loop-finish-flag (gensym))) | 1061 (or loop-finish-flag (setq loop-finish-flag (make-symbol "--cl-flag--"))) |
1052 (or loop-result-var (setq loop-result-var (gensym))) | 1062 (or loop-result-var (setq loop-result-var (make-symbol "--cl-var--"))) |
1053 (push (list 'setq loop-finish-flag | 1063 (push (list 'setq loop-finish-flag |
1054 (list 'not (list 'setq loop-result-var (pop args)))) | 1064 (list 'not (list 'setq loop-result-var (pop args)))) |
1055 loop-body)) | 1065 loop-body)) |
1056 | 1066 |
1057 ((memq word '(if when unless)) | 1067 ((memq word '(if when unless)) |
1058 (let* ((cond (pop args)) | 1068 (let* ((cond (pop args)) |
1059 (then (let ((loop-body nil)) | 1069 (then (let ((loop-body nil)) |
1060 (cl-parse-loop-clause) | 1070 (cl-parse-loop-clause) |
1067 (if (eq (car args) 'end) (pop args)) | 1077 (if (eq (car args) 'end) (pop args)) |
1068 (if (eq word 'unless) (setq then (prog1 else (setq else then)))) | 1078 (if (eq word 'unless) (setq then (prog1 else (setq else then)))) |
1069 (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then)) | 1079 (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then)) |
1070 (if simple (nth 1 else) (list (nth 2 else)))))) | 1080 (if simple (nth 1 else) (list (nth 2 else)))))) |
1071 (if (cl-expr-contains form 'it) | 1081 (if (cl-expr-contains form 'it) |
1072 (let ((temp (gensym))) | 1082 (let ((temp (make-symbol "--cl-var--"))) |
1073 (push (list temp) loop-bindings) | 1083 (push (list temp) loop-bindings) |
1074 (setq form (list* 'if (list 'setq temp cond) | 1084 (setq form (list* 'if (list 'setq temp cond) |
1075 (subst temp 'it form)))) | 1085 (subst temp 'it form)))) |
1076 (setq form (list* 'if cond form))) | 1086 (setq form (list* 'if cond form))) |
1077 (push (if simple (list 'progn form t) form) loop-body)))) | 1087 (push (if simple (list 'progn form t) form) loop-body)))) |
1081 (or (consp (car args)) (error "Syntax error on `do' clause")) | 1091 (or (consp (car args)) (error "Syntax error on `do' clause")) |
1082 (while (consp (car args)) (push (pop args) body)) | 1092 (while (consp (car args)) (push (pop args) body)) |
1083 (push (cons 'progn (nreverse (cons t body))) loop-body))) | 1093 (push (cons 'progn (nreverse (cons t body))) loop-body))) |
1084 | 1094 |
1085 ((eq word 'return) | 1095 ((eq word 'return) |
1086 (or loop-finish-flag (setq loop-finish-flag (gensym))) | 1096 (or loop-finish-flag (setq loop-finish-flag (make-symbol "--cl-var--"))) |
1087 (or loop-result-var (setq loop-result-var (gensym))) | 1097 (or loop-result-var (setq loop-result-var (make-symbol "--cl-var--"))) |
1088 (push (list 'setq loop-result-var (pop args) | 1098 (push (list 'setq loop-result-var (pop args) |
1089 loop-finish-flag nil) loop-body)) | 1099 loop-finish-flag nil) loop-body)) |
1090 | 1100 |
1091 (t | 1101 (t |
1092 (let ((handler (and (symbolp word) (get word 'cl-loop-handler)))) | 1102 (let ((handler (and (symbolp word) (get word 'cl-loop-handler)))) |
1093 (or handler (error "Expected a loop keyword, found %s" word)) | 1103 (or handler (error "Expected a loop keyword, found %s" word)) |
1094 (funcall handler)))) | 1104 (funcall handler)))) |
1102 (and par p | 1112 (and par p |
1103 (progn | 1113 (progn |
1104 (setq par nil p specs) | 1114 (setq par nil p specs) |
1105 (while p | 1115 (while p |
1106 (or (cl-const-expr-p (cadar p)) | 1116 (or (cl-const-expr-p (cadar p)) |
1107 (let ((temp (gensym))) | 1117 (let ((temp (make-symbol "--cl-var--"))) |
1108 (push (list temp (cadar p)) temps) | 1118 (push (list temp (cadar p)) temps) |
1109 (setcar (cdar p) temp))) | 1119 (setcar (cdar p) temp))) |
1110 (setq p (cdr p))))) | 1120 (setq p (cdr p))))) |
1111 (while specs | 1121 (while specs |
1112 (if (and (consp (car specs)) (listp (caar specs))) | 1122 (if (and (consp (car specs)) (listp (caar specs))) |
1113 (let* ((spec (caar specs)) (nspecs nil) | 1123 (let* ((spec (caar specs)) (nspecs nil) |
1114 (expr (cadr (pop specs))) | 1124 (expr (cadr (pop specs))) |
1115 (temp (cdr (or (assq spec loop-destr-temps) | 1125 (temp (cdr (or (assq spec loop-destr-temps) |
1116 (car (push (cons spec (or (last spec 0) | 1126 (car (push (cons spec (or (last spec 0) |
1117 (gensym))) | 1127 (make-symbol "--cl-var--"))) |
1118 loop-destr-temps)))))) | 1128 loop-destr-temps)))))) |
1119 (push (list temp expr) new) | 1129 (push (list temp expr) new) |
1120 (while (consp spec) | 1130 (while (consp spec) |
1121 (push (list (pop spec) | 1131 (push (list (pop spec) |
1122 (and expr (list (if spec 'pop 'car) temp))) | 1132 (and expr (list (if spec 'pop 'car) temp))) |
1123 nspecs)) | 1133 nspecs)) |
1136 (progn (push (list (list var def)) loop-bindings) | 1146 (progn (push (list (list var def)) loop-bindings) |
1137 (push var loop-accum-vars))) | 1147 (push var loop-accum-vars))) |
1138 var) | 1148 var) |
1139 (or loop-accum-var | 1149 (or loop-accum-var |
1140 (progn | 1150 (progn |
1141 (push (list (list (setq loop-accum-var (gensym)) def)) | 1151 (push (list (list (setq loop-accum-var (make-symbol "--cl-var--")) def)) |
1142 loop-bindings) | 1152 loop-bindings) |
1143 (setq loop-result (if func (list func loop-accum-var) | 1153 (setq loop-result (if func (list func loop-accum-var) |
1144 loop-accum-var)) | 1154 loop-accum-var)) |
1145 loop-accum-var)))) | 1155 loop-accum-var)))) |
1146 | 1156 |
1170 | 1180 |
1171 ;;; Other iteration control structures. | 1181 ;;; Other iteration control structures. |
1172 | 1182 |
1173 (defmacro do (steps endtest &rest body) | 1183 (defmacro do (steps endtest &rest body) |
1174 "The Common Lisp `do' loop. | 1184 "The Common Lisp `do' loop. |
1175 Format is: (do ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" | 1185 |
1186 \(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" | |
1176 (cl-expand-do-loop steps endtest body nil)) | 1187 (cl-expand-do-loop steps endtest body nil)) |
1177 | 1188 |
1178 (defmacro do* (steps endtest &rest body) | 1189 (defmacro do* (steps endtest &rest body) |
1179 "The Common Lisp `do*' loop. | 1190 "The Common Lisp `do*' loop. |
1180 Format is: (do* ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" | 1191 |
1192 \(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" | |
1181 (cl-expand-do-loop steps endtest body t)) | 1193 (cl-expand-do-loop steps endtest body t)) |
1182 | 1194 |
1183 (defun cl-expand-do-loop (steps endtest body star) | 1195 (defun cl-expand-do-loop (steps endtest body star) |
1184 (list 'block nil | 1196 (list 'block nil |
1185 (list* (if star 'let* 'let) | 1197 (list* (if star 'let* 'let) |
1205 "Loop over a list. | 1217 "Loop over a list. |
1206 Evaluate BODY with VAR bound to each `car' from LIST, in turn. | 1218 Evaluate BODY with VAR bound to each `car' from LIST, in turn. |
1207 Then evaluate RESULT to get return value, default nil. | 1219 Then evaluate RESULT to get return value, default nil. |
1208 | 1220 |
1209 \(fn (VAR LIST [RESULT]) BODY...)" | 1221 \(fn (VAR LIST [RESULT]) BODY...)" |
1210 (let ((temp (gensym "--dolist-temp--"))) | 1222 (let ((temp (make-symbol "--cl-dolist-temp--"))) |
1211 (list 'block nil | 1223 (list 'block nil |
1212 (list* 'let (list (list temp (nth 1 spec)) (car spec)) | 1224 (list* 'let (list (list temp (nth 1 spec)) (car spec)) |
1213 (list* 'while temp (list 'setq (car spec) (list 'car temp)) | 1225 (list* 'while temp (list 'setq (car spec) (list 'car temp)) |
1214 (append body (list (list 'setq temp | 1226 (append body (list (list 'setq temp |
1215 (list 'cdr temp))))) | 1227 (list 'cdr temp))))) |
1222 Evaluate BODY with VAR bound to successive integers from 0, inclusive, | 1234 Evaluate BODY with VAR bound to successive integers from 0, inclusive, |
1223 to COUNT, exclusive. Then evaluate RESULT to get return value, default | 1235 to COUNT, exclusive. Then evaluate RESULT to get return value, default |
1224 nil. | 1236 nil. |
1225 | 1237 |
1226 \(fn (VAR COUNT [RESULT]) BODY...)" | 1238 \(fn (VAR COUNT [RESULT]) BODY...)" |
1227 (let ((temp (gensym "--dotimes-temp--"))) | 1239 (let ((temp (make-symbol "--cl-dotimes-temp--"))) |
1228 (list 'block nil | 1240 (list 'block nil |
1229 (list* 'let (list (list temp (nth 1 spec)) (list (car spec) 0)) | 1241 (list* 'let (list (list temp (nth 1 spec)) (list (car spec) 0)) |
1230 (list* 'while (list '< (car spec) temp) | 1242 (list* 'while (list '< (car spec) temp) |
1231 (append body (list (list 'incf (car spec))))) | 1243 (append body (list (list 'incf (car spec))))) |
1232 (or (cdr (cdr spec)) '(nil)))))) | 1244 (or (cdr (cdr spec)) '(nil)))))) |
1263 ;;; Binding control structures. | 1275 ;;; Binding control structures. |
1264 | 1276 |
1265 (defmacro progv (symbols values &rest body) | 1277 (defmacro progv (symbols values &rest body) |
1266 "Bind SYMBOLS to VALUES dynamically in BODY. | 1278 "Bind SYMBOLS to VALUES dynamically in BODY. |
1267 The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists. | 1279 The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists. |
1268 Each SYMBOL in the first list is bound to the corresponding VALUE in the | 1280 Each symbol in the first list is bound to the corresponding value in the |
1269 second list (or made unbound if VALUES is shorter than SYMBOLS); then the | 1281 second list (or made unbound if VALUES is shorter than SYMBOLS); then the |
1270 BODY forms are executed and their result is returned. This is much like | 1282 BODY forms are executed and their result is returned. This is much like |
1271 a `let' form, except that the list of symbols can be computed at run-time." | 1283 a `let' form, except that the list of symbols can be computed at run-time." |
1272 (list 'let '((cl-progv-save nil)) | 1284 (list 'let '((cl-progv-save nil)) |
1273 (list 'unwind-protect | 1285 (list 'unwind-protect |
1274 (list* 'progn (list 'cl-progv-before symbols values) body) | 1286 (list* 'progn (list 'cl-progv-before symbols values) body) |
1275 '(cl-progv-after)))) | 1287 '(cl-progv-after)))) |
1276 | 1288 |
1277 ;;; This should really have some way to shadow 'byte-compile properties, etc. | 1289 ;;; This should really have some way to shadow 'byte-compile properties, etc. |
1278 (defmacro flet (bindings &rest body) | 1290 (defmacro flet (bindings &rest body) |
1279 "Make temporary function defns. | 1291 "Make temporary function definitions. |
1280 This is an analogue of `let' that operates on the function cell of FUNC | 1292 This is an analogue of `let' that operates on the function cell of FUNC |
1281 rather than its value cell. The FORMs are evaluated with the specified | 1293 rather than its value cell. The FORMs are evaluated with the specified |
1282 function definitions in place, then the definitions are undone (the FUNCs | 1294 function definitions in place, then the definitions are undone (the FUNCs |
1283 go back to their previous definitions, or lack thereof). | 1295 go back to their previous definitions, or lack thereof). |
1284 | 1296 |
1301 (list (list 'symbol-function (list 'quote (car x))) func)))) | 1313 (list (list 'symbol-function (list 'quote (car x))) func)))) |
1302 bindings) | 1314 bindings) |
1303 body)) | 1315 body)) |
1304 | 1316 |
1305 (defmacro labels (bindings &rest body) | 1317 (defmacro labels (bindings &rest body) |
1306 "Make temporary func bindings. | 1318 "Make temporary function bindings. |
1307 This is like `flet', except the bindings are lexical instead of dynamic. | 1319 This is like `flet', except the bindings are lexical instead of dynamic. |
1308 Unlike `flet', this macro is fully compliant with the Common Lisp standard. | 1320 Unlike `flet', this macro is fully compliant with the Common Lisp standard. |
1309 | 1321 |
1310 \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" | 1322 \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" |
1311 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment)) | 1323 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment)) |
1312 (while bindings | 1324 (while bindings |
1313 (let ((var (gensym))) | 1325 ;; Use `gensym' rather than `make-symbol'. It's important that |
1326 ;; (not (eq (symbol-name var1) (symbol-name var2))) because these | |
1327 ;; vars get added to the cl-macro-environment. | |
1328 (let ((var (gensym "--cl-var--"))) | |
1314 (push var vars) | 1329 (push var vars) |
1315 (push (list 'function* (cons 'lambda (cdar bindings))) sets) | 1330 (push (list 'function* (cons 'lambda (cdar bindings))) sets) |
1316 (push var sets) | 1331 (push var sets) |
1317 (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args) | 1332 (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args) |
1318 (list 'list* '(quote funcall) (list 'quote var) | 1333 (list 'list* '(quote funcall) (list 'quote var) |
1322 cl-macro-environment))) | 1337 cl-macro-environment))) |
1323 | 1338 |
1324 ;; The following ought to have a better definition for use with newer | 1339 ;; The following ought to have a better definition for use with newer |
1325 ;; byte compilers. | 1340 ;; byte compilers. |
1326 (defmacro macrolet (bindings &rest body) | 1341 (defmacro macrolet (bindings &rest body) |
1327 "Make temporary macro defns. | 1342 "Make temporary macro definitions. |
1328 This is like `flet', but for macros instead of functions. | 1343 This is like `flet', but for macros instead of functions. |
1329 | 1344 |
1330 \(fn ((NAME ARGLIST BODY...) ...) FORM...)" | 1345 \(fn ((NAME ARGLIST BODY...) ...) FORM...)" |
1331 (if (cdr bindings) | 1346 (if (cdr bindings) |
1332 (list 'macrolet | 1347 (list 'macrolet |
1338 (cl-macroexpand-all (cons 'progn body) | 1353 (cl-macroexpand-all (cons 'progn body) |
1339 (cons (list* name 'lambda (cdr res)) | 1354 (cons (list* name 'lambda (cdr res)) |
1340 cl-macro-environment)))))) | 1355 cl-macro-environment)))))) |
1341 | 1356 |
1342 (defmacro symbol-macrolet (bindings &rest body) | 1357 (defmacro symbol-macrolet (bindings &rest body) |
1343 "Make symbol macro defns. | 1358 "Make symbol macro definitions. |
1344 Within the body FORMs, references to the variable NAME will be replaced | 1359 Within the body FORMs, references to the variable NAME will be replaced |
1345 by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). | 1360 by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). |
1346 | 1361 |
1347 \(fn ((NAME EXPANSION) ...) FORM...)" | 1362 \(fn ((NAME EXPANSION) ...) FORM...)" |
1348 (if (cdr bindings) | 1363 (if (cdr bindings) |
1356 | 1371 |
1357 (defvar cl-closure-vars nil) | 1372 (defvar cl-closure-vars nil) |
1358 (defmacro lexical-let (bindings &rest body) | 1373 (defmacro lexical-let (bindings &rest body) |
1359 "Like `let', but lexically scoped. | 1374 "Like `let', but lexically scoped. |
1360 The main visible difference is that lambdas inside BODY will create | 1375 The main visible difference is that lambdas inside BODY will create |
1361 lexical closures as in Common Lisp." | 1376 lexical closures as in Common Lisp. |
1377 \n(fn VARLIST BODY)" | |
1362 (let* ((cl-closure-vars cl-closure-vars) | 1378 (let* ((cl-closure-vars cl-closure-vars) |
1363 (vars (mapcar (function | 1379 (vars (mapcar (function |
1364 (lambda (x) | 1380 (lambda (x) |
1365 (or (consp x) (setq x (list x))) | 1381 (or (consp x) (setq x (list x))) |
1366 (push (gensym (format "--%s--" (car x))) | 1382 (push (make-symbol (format "--cl-%s--" (car x))) |
1367 cl-closure-vars) | 1383 cl-closure-vars) |
1368 (set (car cl-closure-vars) [bad-lexical-ref]) | 1384 (set (car cl-closure-vars) [bad-lexical-ref]) |
1369 (list (car x) (cadr x) (car cl-closure-vars)))) | 1385 (list (car x) (cadr x) (car cl-closure-vars)))) |
1370 bindings)) | 1386 bindings)) |
1371 (ebody | 1387 (ebody |
1372 (cl-macroexpand-all | 1388 (cl-macroexpand-all |
1398 ebody)))) | 1414 ebody)))) |
1399 | 1415 |
1400 (defmacro lexical-let* (bindings &rest body) | 1416 (defmacro lexical-let* (bindings &rest body) |
1401 "Like `let*', but lexically scoped. | 1417 "Like `let*', but lexically scoped. |
1402 The main visible difference is that lambdas inside BODY will create | 1418 The main visible difference is that lambdas inside BODY will create |
1403 lexical closures as in Common Lisp." | 1419 lexical closures as in Common Lisp. |
1420 \n(fn VARLIST BODY)" | |
1404 (if (null bindings) (cons 'progn body) | 1421 (if (null bindings) (cons 'progn body) |
1405 (setq bindings (reverse bindings)) | 1422 (setq bindings (reverse bindings)) |
1406 (while bindings | 1423 (while bindings |
1407 (setq body (list (list* 'lexical-let (list (pop bindings)) body)))) | 1424 (setq body (list (list* 'lexical-let (list (pop bindings)) body)))) |
1408 (car body))) | 1425 (car body))) |
1422 of this list bound (`let'-style) to each of the symbols SYM in turn. This | 1439 of this list bound (`let'-style) to each of the symbols SYM in turn. This |
1423 is analogous to the Common Lisp `multiple-value-bind' macro, using lists to | 1440 is analogous to the Common Lisp `multiple-value-bind' macro, using lists to |
1424 simulate true multiple return values. For compatibility, (values A B C) is | 1441 simulate true multiple return values. For compatibility, (values A B C) is |
1425 a synonym for (list A B C). | 1442 a synonym for (list A B C). |
1426 | 1443 |
1427 \(fn (SYM SYM...) FORM BODY)" | 1444 \(fn (SYM...) FORM BODY)" |
1428 (let ((temp (gensym)) (n -1)) | 1445 (let ((temp (make-symbol "--cl-var--")) (n -1)) |
1429 (list* 'let* (cons (list temp form) | 1446 (list* 'let* (cons (list temp form) |
1430 (mapcar (function | 1447 (mapcar (function |
1431 (lambda (v) | 1448 (lambda (v) |
1432 (list v (list 'nth (setq n (1+ n)) temp)))) | 1449 (list v (list 'nth (setq n (1+ n)) temp)))) |
1433 vars)) | 1450 vars)) |
1438 FORM must return a list; the first N elements of this list are stored in | 1455 FORM must return a list; the first N elements of this list are stored in |
1439 each of the symbols SYM in turn. This is analogous to the Common Lisp | 1456 each of the symbols SYM in turn. This is analogous to the Common Lisp |
1440 `multiple-value-setq' macro, using lists to simulate true multiple return | 1457 `multiple-value-setq' macro, using lists to simulate true multiple return |
1441 values. For compatibility, (values A B C) is a synonym for (list A B C). | 1458 values. For compatibility, (values A B C) is a synonym for (list A B C). |
1442 | 1459 |
1443 \(fn (SYM SYM...) FORM)" | 1460 \(fn (SYM...) FORM)" |
1444 (cond ((null vars) (list 'progn form nil)) | 1461 (cond ((null vars) (list 'progn form nil)) |
1445 ((null (cdr vars)) (list 'setq (car vars) (list 'car form))) | 1462 ((null (cdr vars)) (list 'setq (car vars) (list 'car form))) |
1446 (t | 1463 (t |
1447 (let* ((temp (gensym)) (n 0)) | 1464 (let* ((temp (make-symbol "--cl-var--")) (n 0)) |
1448 (list 'let (list (list temp form)) | 1465 (list 'let (list (list temp form)) |
1449 (list 'prog1 (list 'setq (pop vars) (list 'car temp)) | 1466 (list 'prog1 (list 'setq (pop vars) (list 'car temp)) |
1450 (cons 'setq (apply 'nconc | 1467 (cons 'setq (apply 'nconc |
1451 (mapcar (function | 1468 (mapcar (function |
1452 (lambda (v) | 1469 (lambda (v) |
1546 (defmacro defsetf (func arg1 &rest args) | 1563 (defmacro defsetf (func arg1 &rest args) |
1547 "(defsetf NAME FUNC): define a `setf' method. | 1564 "(defsetf NAME FUNC): define a `setf' method. |
1548 This macro is an easy-to-use substitute for `define-setf-method' that works | 1565 This macro is an easy-to-use substitute for `define-setf-method' that works |
1549 well for simple place forms. In the simple `defsetf' form, `setf's of | 1566 well for simple place forms. In the simple `defsetf' form, `setf's of |
1550 the form (setf (NAME ARGS...) VAL) are transformed to function or macro | 1567 the form (setf (NAME ARGS...) VAL) are transformed to function or macro |
1551 calls of the form (FUNC ARGS... VAL). Example: (defsetf aref aset). | 1568 calls of the form (FUNC ARGS... VAL). Example: |
1569 | |
1570 (defsetf aref aset) | |
1571 | |
1552 Alternate form: (defsetf NAME ARGLIST (STORE) BODY...). | 1572 Alternate form: (defsetf NAME ARGLIST (STORE) BODY...). |
1553 Here, the above `setf' call is expanded by binding the argument forms ARGS | 1573 Here, the above `setf' call is expanded by binding the argument forms ARGS |
1554 according to ARGLIST, binding the value form VAL to STORE, then executing | 1574 according to ARGLIST, binding the value form VAL to STORE, then executing |
1555 BODY, which must return a Lisp form that does the necessary `setf' operation. | 1575 BODY, which must return a Lisp form that does the necessary `setf' operation. |
1556 Actually, ARGLIST and STORE may be bound to temporary variables which are | 1576 Actually, ARGLIST and STORE may be bound to temporary variables which are |
1557 introduced automatically to preserve proper execution order of the arguments. | 1577 introduced automatically to preserve proper execution order of the arguments. |
1558 Example: (defsetf nth (n x) (v) (list 'setcar (list 'nthcdr n x) v))." | 1578 Example: |
1579 | |
1580 (defsetf nth (n x) (v) (list 'setcar (list 'nthcdr n x) v)) | |
1581 | |
1582 \(fn NAME [FUNC | ARGLIST (STORE) BODY...])" | |
1559 (if (listp arg1) | 1583 (if (listp arg1) |
1560 (let* ((largs nil) (largsr nil) | 1584 (let* ((largs nil) (largsr nil) |
1561 (temps nil) (tempsr nil) | 1585 (temps nil) (tempsr nil) |
1562 (restarg nil) (rest-temps nil) | 1586 (restarg nil) (rest-temps nil) |
1563 (store-var (car (prog1 (car args) (setq args (cdr args))))) | 1587 (store-var (car (prog1 (car args) (setq args (cdr args))))) |
1581 rest-temps (intern (format "--%s--temp--" restarg)) | 1605 rest-temps (intern (format "--%s--temp--" restarg)) |
1582 tempsr (append temps (list rest-temps))) | 1606 tempsr (append temps (list rest-temps))) |
1583 (setq largsr largs tempsr temps)) | 1607 (setq largsr largs tempsr temps)) |
1584 (let ((p1 largs) (p2 temps)) | 1608 (let ((p1 largs) (p2 temps)) |
1585 (while p1 | 1609 (while p1 |
1586 (setq lets1 (cons (list (car p2) | 1610 (setq lets1 (cons `(,(car p2) |
1587 (list 'gensym (format "--%s--" (car p1)))) | 1611 (make-symbol ,(format "--cl-%s--" (car p1)))) |
1588 lets1) | 1612 lets1) |
1589 lets2 (cons (list (car p1) (car p2)) lets2) | 1613 lets2 (cons (list (car p1) (car p2)) lets2) |
1590 p1 (cdr p1) p2 (cdr p2)))) | 1614 p1 (cdr p1) p2 (cdr p2)))) |
1591 (if restarg (setq lets2 (cons (list restarg rest-temps) lets2))) | 1615 (if restarg (setq lets2 (cons (list restarg rest-temps) lets2))) |
1592 (append (list 'define-setf-method func arg1) | 1616 `(define-setf-method ,func ,arg1 |
1593 (and docstr (list docstr)) | 1617 ,@(and docstr (list docstr)) |
1594 (list | 1618 (let* |
1595 (list 'let* | 1619 ,(nreverse |
1596 (nreverse | 1620 (cons `(,store-temp |
1597 (cons (list store-temp | 1621 (make-symbol ,(format "--cl-%s--" store-var))) |
1598 (list 'gensym (format "--%s--" store-var))) | 1622 (if restarg |
1599 (if restarg | 1623 `((,rest-temps |
1600 (append | 1624 (mapcar (lambda (_) (make-symbol "--cl-var--")) |
1601 (list | 1625 ,restarg)) |
1602 (list rest-temps | 1626 ,@lets1) |
1603 (list 'mapcar '(quote gensym) | 1627 lets1))) |
1604 restarg))) | 1628 (list ; 'values |
1605 lets1) | 1629 (,(if restarg 'list* 'list) ,@tempsr) |
1606 lets1))) | 1630 (,(if restarg 'list* 'list) ,@largsr) |
1607 (list 'list ; 'values | 1631 (list ,store-temp) |
1608 (cons (if restarg 'list* 'list) tempsr) | 1632 (let* |
1609 (cons (if restarg 'list* 'list) largsr) | 1633 ,(nreverse |
1610 (list 'list store-temp) | 1634 (cons (list store-var store-temp) |
1611 (cons 'let* | 1635 lets2)) |
1612 (cons (nreverse | 1636 ,@args) |
1613 (cons (list store-var store-temp) | 1637 (,(if restarg 'list* 'list) |
1614 lets2)) | 1638 ,@(cons (list 'quote func) tempsr)))))) |
1615 args)) | 1639 `(defsetf ,func (&rest args) (store) |
1616 (cons (if restarg 'list* 'list) | 1640 ,(let ((call `(cons ',arg1 |
1617 (cons (list 'quote func) tempsr))))))) | 1641 (append args (list store))))) |
1618 (list 'defsetf func '(&rest args) '(store) | 1642 (if (car args) |
1619 (let ((call (list 'cons (list 'quote arg1) | 1643 `(list 'progn ,call store) |
1620 '(append args (list store))))) | 1644 call))))) |
1621 (if (car args) | |
1622 (list 'list '(quote progn) call 'store) | |
1623 call))))) | |
1624 | 1645 |
1625 ;;; Some standard place types from Common Lisp. | 1646 ;;; Some standard place types from Common Lisp. |
1626 (defsetf aref aset) | 1647 (defsetf aref aset) |
1627 (defsetf car setcar) | 1648 (defsetf car setcar) |
1628 (defsetf cdr setcdr) | 1649 (defsetf cdr setcdr) |
1772 (error "%s is not suitable for use with setf-of-apply" func)) | 1793 (error "%s is not suitable for use with setf-of-apply" func)) |
1773 (list* 'apply (list 'quote (car form)) (cdr form)))) | 1794 (list* 'apply (list 'quote (car form)) (cdr form)))) |
1774 | 1795 |
1775 (define-setf-method nthcdr (n place) | 1796 (define-setf-method nthcdr (n place) |
1776 (let ((method (get-setf-method place cl-macro-environment)) | 1797 (let ((method (get-setf-method place cl-macro-environment)) |
1777 (n-temp (gensym "--nthcdr-n--")) | 1798 (n-temp (make-symbol "--cl-nthcdr-n--")) |
1778 (store-temp (gensym "--nthcdr-store--"))) | 1799 (store-temp (make-symbol "--cl-nthcdr-store--"))) |
1779 (list (cons n-temp (car method)) | 1800 (list (cons n-temp (car method)) |
1780 (cons n (nth 1 method)) | 1801 (cons n (nth 1 method)) |
1781 (list store-temp) | 1802 (list store-temp) |
1782 (list 'let (list (list (car (nth 2 method)) | 1803 (list 'let (list (list (car (nth 2 method)) |
1783 (list 'cl-set-nthcdr n-temp (nth 4 method) | 1804 (list 'cl-set-nthcdr n-temp (nth 4 method) |
1785 (nth 3 method) store-temp) | 1806 (nth 3 method) store-temp) |
1786 (list 'nthcdr n-temp (nth 4 method))))) | 1807 (list 'nthcdr n-temp (nth 4 method))))) |
1787 | 1808 |
1788 (define-setf-method getf (place tag &optional def) | 1809 (define-setf-method getf (place tag &optional def) |
1789 (let ((method (get-setf-method place cl-macro-environment)) | 1810 (let ((method (get-setf-method place cl-macro-environment)) |
1790 (tag-temp (gensym "--getf-tag--")) | 1811 (tag-temp (make-symbol "--cl-getf-tag--")) |
1791 (def-temp (gensym "--getf-def--")) | 1812 (def-temp (make-symbol "--cl-getf-def--")) |
1792 (store-temp (gensym "--getf-store--"))) | 1813 (store-temp (make-symbol "--cl-getf-store--"))) |
1793 (list (append (car method) (list tag-temp def-temp)) | 1814 (list (append (car method) (list tag-temp def-temp)) |
1794 (append (nth 1 method) (list tag def)) | 1815 (append (nth 1 method) (list tag def)) |
1795 (list store-temp) | 1816 (list store-temp) |
1796 (list 'let (list (list (car (nth 2 method)) | 1817 (list 'let (list (list (car (nth 2 method)) |
1797 (list 'cl-set-getf (nth 4 method) | 1818 (list 'cl-set-getf (nth 4 method) |
1799 (nth 3 method) store-temp) | 1820 (nth 3 method) store-temp) |
1800 (list 'getf (nth 4 method) tag-temp def-temp)))) | 1821 (list 'getf (nth 4 method) tag-temp def-temp)))) |
1801 | 1822 |
1802 (define-setf-method substring (place from &optional to) | 1823 (define-setf-method substring (place from &optional to) |
1803 (let ((method (get-setf-method place cl-macro-environment)) | 1824 (let ((method (get-setf-method place cl-macro-environment)) |
1804 (from-temp (gensym "--substring-from--")) | 1825 (from-temp (make-symbol "--cl-substring-from--")) |
1805 (to-temp (gensym "--substring-to--")) | 1826 (to-temp (make-symbol "--cl-substring-to--")) |
1806 (store-temp (gensym "--substring-store--"))) | 1827 (store-temp (make-symbol "--cl-substring-store--"))) |
1807 (list (append (car method) (list from-temp to-temp)) | 1828 (list (append (car method) (list from-temp to-temp)) |
1808 (append (nth 1 method) (list from to)) | 1829 (append (nth 1 method) (list from to)) |
1809 (list store-temp) | 1830 (list store-temp) |
1810 (list 'let (list (list (car (nth 2 method)) | 1831 (list 'let (list (list (car (nth 2 method)) |
1811 (list 'cl-set-substring (nth 4 method) | 1832 (list 'cl-set-substring (nth 4 method) |
1817 (defun get-setf-method (place &optional env) | 1838 (defun get-setf-method (place &optional env) |
1818 "Return a list of five values describing the setf-method for PLACE. | 1839 "Return a list of five values describing the setf-method for PLACE. |
1819 PLACE may be any Lisp form which can appear as the PLACE argument to | 1840 PLACE may be any Lisp form which can appear as the PLACE argument to |
1820 a macro like `setf' or `incf'." | 1841 a macro like `setf' or `incf'." |
1821 (if (symbolp place) | 1842 (if (symbolp place) |
1822 (let ((temp (gensym "--setf--"))) | 1843 (let ((temp (make-symbol "--cl-setf--"))) |
1823 (list nil nil (list temp) (list 'setq place temp) place)) | 1844 (list nil nil (list temp) (list 'setq place temp) place)) |
1824 (or (and (symbolp (car place)) | 1845 (or (and (symbolp (car place)) |
1825 (let* ((func (car place)) | 1846 (let* ((func (car place)) |
1826 (name (symbol-name func)) | 1847 (name (symbol-name func)) |
1827 (method (get func 'setf-method)) | 1848 (method (get func 'setf-method)) |
1924 | 1945 |
1925 (defun cl-do-pop (place) | 1946 (defun cl-do-pop (place) |
1926 (if (cl-simple-expr-p place) | 1947 (if (cl-simple-expr-p place) |
1927 (list 'prog1 (list 'car place) (list 'setf place (list 'cdr place))) | 1948 (list 'prog1 (list 'car place) (list 'setf place (list 'cdr place))) |
1928 (let* ((method (cl-setf-do-modify place t)) | 1949 (let* ((method (cl-setf-do-modify place t)) |
1929 (temp (gensym "--pop--"))) | 1950 (temp (make-symbol "--cl-pop--"))) |
1930 (list 'let* | 1951 (list 'let* |
1931 (append (car method) | 1952 (append (car method) |
1932 (list (list temp (nth 2 method)))) | 1953 (list (list temp (nth 2 method)))) |
1933 (list 'prog1 | 1954 (list 'prog1 |
1934 (list 'car temp) | 1955 (list 'car temp) |
1937 (defmacro remf (place tag) | 1958 (defmacro remf (place tag) |
1938 "Remove TAG from property list PLACE. | 1959 "Remove TAG from property list PLACE. |
1939 PLACE may be a symbol, or any generalized variable allowed by `setf'. | 1960 PLACE may be a symbol, or any generalized variable allowed by `setf'. |
1940 The form returns true if TAG was found and removed, nil otherwise." | 1961 The form returns true if TAG was found and removed, nil otherwise." |
1941 (let* ((method (cl-setf-do-modify place t)) | 1962 (let* ((method (cl-setf-do-modify place t)) |
1942 (tag-temp (and (not (cl-const-expr-p tag)) (gensym "--remf-tag--"))) | 1963 (tag-temp (and (not (cl-const-expr-p tag)) (make-symbol "--cl-remf-tag--"))) |
1943 (val-temp (and (not (cl-simple-expr-p place)) | 1964 (val-temp (and (not (cl-simple-expr-p place)) |
1944 (gensym "--remf-place--"))) | 1965 (make-symbol "--cl-remf-place--"))) |
1945 (ttag (or tag-temp tag)) | 1966 (ttag (or tag-temp tag)) |
1946 (tval (or val-temp (nth 2 method)))) | 1967 (tval (or val-temp (nth 2 method)))) |
1947 (list 'let* | 1968 (list 'let* |
1948 (append (car method) | 1969 (append (car method) |
1949 (and val-temp (list (list val-temp (nth 2 method)))) | 1970 (and val-temp (list (list val-temp (nth 2 method)))) |
1957 (defmacro shiftf (place &rest args) | 1978 (defmacro shiftf (place &rest args) |
1958 "Shift left among PLACEs. | 1979 "Shift left among PLACEs. |
1959 Example: (shiftf A B C) sets A to B, B to C, and returns the old A. | 1980 Example: (shiftf A B C) sets A to B, B to C, and returns the old A. |
1960 Each PLACE may be a symbol, or any generalized variable allowed by `setf'. | 1981 Each PLACE may be a symbol, or any generalized variable allowed by `setf'. |
1961 | 1982 |
1962 \(fn PLACE PLACE... VAL)" | 1983 \(fn PLACE... VAL)" |
1963 (cond | 1984 (cond |
1964 ((null args) place) | 1985 ((null args) place) |
1965 ((symbolp place) `(prog1 ,place (setq ,place (shiftf ,@args)))) | 1986 ((symbolp place) `(prog1 ,place (setq ,place (shiftf ,@args)))) |
1966 (t | 1987 (t |
1967 (let ((method (cl-setf-do-modify place 'unsafe))) | 1988 (let ((method (cl-setf-do-modify place 'unsafe))) |
1981 (first (car args))) | 2002 (first (car args))) |
1982 (while (cdr args) | 2003 (while (cdr args) |
1983 (setq sets (nconc sets (list (pop args) (car args))))) | 2004 (setq sets (nconc sets (list (pop args) (car args))))) |
1984 (nconc (list 'psetf) sets (list (car args) first)))) | 2005 (nconc (list 'psetf) sets (list (car args) first)))) |
1985 (let* ((places (reverse args)) | 2006 (let* ((places (reverse args)) |
1986 (temp (gensym "--rotatef--")) | 2007 (temp (make-symbol "--cl-rotatef--")) |
1987 (form temp)) | 2008 (form temp)) |
1988 (while (cdr places) | 2009 (while (cdr places) |
1989 (let ((method (cl-setf-do-modify (pop places) 'unsafe))) | 2010 (let ((method (cl-setf-do-modify (pop places) 'unsafe))) |
1990 (setq form (list 'let* (car method) | 2011 (setq form (list 'let* (car method) |
1991 (list 'prog1 (nth 2 method) | 2012 (list 'prog1 (nth 2 method) |
2013 (let* ((place (if (symbolp (caar rev)) | 2034 (let* ((place (if (symbolp (caar rev)) |
2014 (list 'symbol-value (list 'quote (caar rev))) | 2035 (list 'symbol-value (list 'quote (caar rev))) |
2015 (caar rev))) | 2036 (caar rev))) |
2016 (value (cadar rev)) | 2037 (value (cadar rev)) |
2017 (method (cl-setf-do-modify place 'no-opt)) | 2038 (method (cl-setf-do-modify place 'no-opt)) |
2018 (save (gensym "--letf-save--")) | 2039 (save (make-symbol "--cl-letf-save--")) |
2019 (bound (and (memq (car place) '(symbol-value symbol-function)) | 2040 (bound (and (memq (car place) '(symbol-value symbol-function)) |
2020 (gensym "--letf-bound--"))) | 2041 (make-symbol "--cl-letf-bound--"))) |
2021 (temp (and (not (cl-const-expr-p value)) (cdr bindings) | 2042 (temp (and (not (cl-const-expr-p value)) (cdr bindings) |
2022 (gensym "--letf-val--")))) | 2043 (make-symbol "--cl-letf-val--")))) |
2023 (setq lets (nconc (car method) | 2044 (setq lets (nconc (car method) |
2024 (if bound | 2045 (if bound |
2025 (list (list bound | 2046 (list (list bound |
2026 (list (if (eq (car place) | 2047 (list (if (eq (car place) |
2027 'symbol-value) | 2048 'symbol-value) |
2088 | 2109 |
2089 \(fn FUNC ARG1 PLACE ARGS...)" | 2110 \(fn FUNC ARG1 PLACE ARGS...)" |
2090 (if (and (cl-safe-expr-p arg1) (cl-simple-expr-p place) (symbolp func)) | 2111 (if (and (cl-safe-expr-p arg1) (cl-simple-expr-p place) (symbolp func)) |
2091 (list 'setf place (list* func arg1 place args)) | 2112 (list 'setf place (list* func arg1 place args)) |
2092 (let* ((method (cl-setf-do-modify place (cons 'list args))) | 2113 (let* ((method (cl-setf-do-modify place (cons 'list args))) |
2093 (temp (and (not (cl-const-expr-p arg1)) (gensym "--arg1--"))) | 2114 (temp (and (not (cl-const-expr-p arg1)) (make-symbol "--cl-arg1--"))) |
2094 (rargs (list* (or temp arg1) (nth 2 method) args))) | 2115 (rargs (list* (or temp arg1) (nth 2 method) args))) |
2095 (list 'let* (append (and temp (list (list temp arg1))) (car method)) | 2116 (list 'let* (append (and temp (list (list temp arg1))) (car method)) |
2096 (cl-setf-do-store (nth 1 method) | 2117 (cl-setf-do-store (nth 1 method) |
2097 (if (symbolp func) (cons func rargs) | 2118 (if (symbolp func) (cons func rargs) |
2098 (list* 'funcall (list 'function func) | 2119 (list* 'funcall (list 'function func) |
2101 (defmacro define-modify-macro (name arglist func &optional doc) | 2122 (defmacro define-modify-macro (name arglist func &optional doc) |
2102 "Define a `setf'-like modify macro. | 2123 "Define a `setf'-like modify macro. |
2103 If NAME is called, it combines its PLACE argument with the other arguments | 2124 If NAME is called, it combines its PLACE argument with the other arguments |
2104 from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)" | 2125 from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)" |
2105 (if (memq '&key arglist) (error "&key not allowed in define-modify-macro")) | 2126 (if (memq '&key arglist) (error "&key not allowed in define-modify-macro")) |
2106 (let ((place (gensym "--place--"))) | 2127 (let ((place (make-symbol "--cl-place--"))) |
2107 (list 'defmacro* name (cons place arglist) doc | 2128 (list 'defmacro* name (cons place arglist) doc |
2108 (list* (if (memq '&rest arglist) 'list* 'list) | 2129 (list* (if (memq '&rest arglist) 'list* 'list) |
2109 '(quote callf) (list 'quote func) place | 2130 '(quote callf) (list 'quote func) place |
2110 (cl-arglist-args arglist))))) | 2131 (cl-arglist-args arglist))))) |
2111 | 2132 |
2152 (if args | 2173 (if args |
2153 (setq conc-name (if (car args) | 2174 (setq conc-name (if (car args) |
2154 (symbol-name (car args)) "")))) | 2175 (symbol-name (car args)) "")))) |
2155 ((eq opt :constructor) | 2176 ((eq opt :constructor) |
2156 (if (cdr args) | 2177 (if (cdr args) |
2157 (push args constrs) | 2178 (progn |
2179 ;; If this defines a constructor of the same name as | |
2180 ;; the default one, don't define the default. | |
2181 (if (eq (car args) constructor) | |
2182 (setq constructor nil)) | |
2183 (push args constrs)) | |
2158 (if args (setq constructor (car args))))) | 2184 (if args (setq constructor (car args))))) |
2159 ((eq opt :copier) | 2185 ((eq opt :copier) |
2160 (if args (setq copier (car args)))) | 2186 (if args (setq copier (car args)))) |
2161 ((eq opt :predicate) | 2187 ((eq opt :predicate) |
2162 (if args (setq predicate (car args)))) | 2188 (if args (setq predicate (car args)))) |
2210 forms) | 2236 forms) |
2211 (setq incl (get incl 'cl-struct-include))))) | 2237 (setq incl (get incl 'cl-struct-include))))) |
2212 (if type | 2238 (if type |
2213 (progn | 2239 (progn |
2214 (or (memq type '(vector list)) | 2240 (or (memq type '(vector list)) |
2215 (error "Illegal :type specifier: %s" type)) | 2241 (error "Invalid :type specifier: %s" type)) |
2216 (if named (setq tag name))) | 2242 (if named (setq tag name))) |
2217 (setq type 'vector named 'true))) | 2243 (setq type 'vector named 'true))) |
2218 (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) | 2244 (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) |
2219 (push (list 'defvar tag-symbol) forms) | 2245 (push (list 'defvar tag-symbol) forms) |
2220 (setq pred-form (and named | 2246 (setq pred-form (and named |
2254 (append | 2280 (append |
2255 (and pred-check | 2281 (and pred-check |
2256 (list (list 'or pred-check | 2282 (list (list 'or pred-check |
2257 (list 'error | 2283 (list 'error |
2258 (format "%s accessing a non-%s" | 2284 (format "%s accessing a non-%s" |
2259 accessor name) | 2285 accessor name))))) |
2260 'cl-x)))) | |
2261 (list (if (eq type 'vector) (list 'aref 'cl-x pos) | 2286 (list (if (eq type 'vector) (list 'aref 'cl-x pos) |
2262 (if (= pos 0) '(car cl-x) | 2287 (if (= pos 0) '(car cl-x) |
2263 (list 'nth pos 'cl-x)))))) forms) | 2288 (list 'nth pos 'cl-x)))))) forms) |
2264 (push (cons accessor t) side-eff) | 2289 (push (cons accessor t) side-eff) |
2265 (push (list 'define-setf-method accessor '(cl-x) | 2290 (push (list 'define-setf-method accessor '(cl-x) |
2326 side-eff)) | 2351 side-eff)) |
2327 forms) | 2352 forms) |
2328 (cons 'progn (nreverse (cons (list 'quote name) forms))))) | 2353 (cons 'progn (nreverse (cons (list 'quote name) forms))))) |
2329 | 2354 |
2330 (defun cl-struct-setf-expander (x name accessor pred-form pos) | 2355 (defun cl-struct-setf-expander (x name accessor pred-form pos) |
2331 (let* ((temp (gensym "--x--")) (store (gensym "--store--"))) | 2356 (let* ((temp (make-symbol "--cl-x--")) (store (make-symbol "--cl-store--"))) |
2332 (list (list temp) (list x) (list store) | 2357 (list (list temp) (list x) (list store) |
2333 (append '(progn) | 2358 (append '(progn) |
2334 (and pred-form | 2359 (and pred-form |
2335 (list (list 'or (subst temp 'cl-x pred-form) | 2360 (list (list 'or (subst temp 'cl-x pred-form) |
2336 (list 'error | 2361 (list 'error |
2337 (format | 2362 (format |
2338 "%s storing a non-%s" accessor name) | 2363 "%s storing a non-%s" accessor name))))) |
2339 temp)))) | |
2340 (list (if (eq (car (get name 'cl-struct-type)) 'vector) | 2364 (list (if (eq (car (get name 'cl-struct-type)) 'vector) |
2341 (list 'aset temp pos store) | 2365 (list 'aset temp pos store) |
2342 (list 'setcar | 2366 (list 'setcar |
2343 (if (<= pos 5) | 2367 (if (<= pos 5) |
2344 (let ((xx temp)) | 2368 (let ((xx temp)) |
2363 (if (symbolp type) | 2387 (if (symbolp type) |
2364 (cond ((get type 'cl-deftype-handler) | 2388 (cond ((get type 'cl-deftype-handler) |
2365 (cl-make-type-test val (funcall (get type 'cl-deftype-handler)))) | 2389 (cl-make-type-test val (funcall (get type 'cl-deftype-handler)))) |
2366 ((memq type '(nil t)) type) | 2390 ((memq type '(nil t)) type) |
2367 ((eq type 'null) `(null ,val)) | 2391 ((eq type 'null) `(null ,val)) |
2392 ((eq type 'atom) `(atom ,val)) | |
2368 ((eq type 'float) `(floatp-safe ,val)) | 2393 ((eq type 'float) `(floatp-safe ,val)) |
2369 ((eq type 'real) `(numberp ,val)) | 2394 ((eq type 'real) `(numberp ,val)) |
2370 ((eq type 'fixnum) `(integerp ,val)) | 2395 ((eq type 'fixnum) `(integerp ,val)) |
2371 ;; FIXME: Should `character' accept things like ?\C-\M-a ? -stef | 2396 ;; FIXME: Should `character' accept things like ?\C-\M-a ? -stef |
2372 ((memq type '(character string-char)) `(char-valid-p ,val)) | 2397 ((memq type '(character string-char)) `(char-valid-p ,val)) |
2377 (list (intern (concat name "-p")) val))))) | 2402 (list (intern (concat name "-p")) val))))) |
2378 (cond ((get (car type) 'cl-deftype-handler) | 2403 (cond ((get (car type) 'cl-deftype-handler) |
2379 (cl-make-type-test val (apply (get (car type) 'cl-deftype-handler) | 2404 (cl-make-type-test val (apply (get (car type) 'cl-deftype-handler) |
2380 (cdr type)))) | 2405 (cdr type)))) |
2381 ((memq (car type) '(integer float real number)) | 2406 ((memq (car type) '(integer float real number)) |
2382 (delq t (and (cl-make-type-test val (car type)) | 2407 (delq t (list 'and (cl-make-type-test val (car type)) |
2383 (if (memq (cadr type) '(* nil)) t | 2408 (if (memq (cadr type) '(* nil)) t |
2384 (if (consp (cadr type)) (list '> val (caadr type)) | 2409 (if (consp (cadr type)) (list '> val (caadr type)) |
2385 (list '>= val (cadr type)))) | 2410 (list '>= val (cadr type)))) |
2386 (if (memq (caddr type) '(* nil)) t | 2411 (if (memq (caddr type) '(* nil)) t |
2387 (if (consp (caddr type)) (list '< val (caaddr type)) | 2412 (if (consp (caddr type)) (list '< val (caaddr type)) |
2393 ((memq (car type) '(member member*)) | 2418 ((memq (car type) '(member member*)) |
2394 (list 'and (list 'member* val (list 'quote (cdr type))) t)) | 2419 (list 'and (list 'member* val (list 'quote (cdr type))) t)) |
2395 ((eq (car type) 'satisfies) (list (cadr type) val)) | 2420 ((eq (car type) 'satisfies) (list (cadr type) val)) |
2396 (t (error "Bad type spec: %s" type))))) | 2421 (t (error "Bad type spec: %s" type))))) |
2397 | 2422 |
2398 (defun typep (val type) ; See compiler macro below. | 2423 (defun typep (object type) ; See compiler macro below. |
2399 "Check that OBJECT is of type TYPE. | 2424 "Check that OBJECT is of type TYPE. |
2400 TYPE is a Common Lisp-style type specifier." | 2425 TYPE is a Common Lisp-style type specifier." |
2401 (eval (cl-make-type-test 'val type))) | 2426 (eval (cl-make-type-test 'object type))) |
2402 | 2427 |
2403 (defmacro check-type (form type &optional string) | 2428 (defmacro check-type (form type &optional string) |
2404 "Verify that FORM is of type TYPE; signal an error if not. | 2429 "Verify that FORM is of type TYPE; signal an error if not. |
2405 STRING is an optional description of the desired type." | 2430 STRING is an optional description of the desired type." |
2406 (and (or (not (cl-compiling-file)) | 2431 (and (or (not (cl-compiling-file)) |
2407 (< cl-optimize-speed 3) (= cl-optimize-safety 3)) | 2432 (< cl-optimize-speed 3) (= cl-optimize-safety 3)) |
2408 (let* ((temp (if (cl-simple-expr-p form 3) form (gensym))) | 2433 (let* ((temp (if (cl-simple-expr-p form 3) |
2434 form (make-symbol "--cl-var--"))) | |
2409 (body (list 'or (cl-make-type-test temp type) | 2435 (body (list 'or (cl-make-type-test temp type) |
2410 (list 'signal '(quote wrong-type-argument) | 2436 (list 'signal '(quote wrong-type-argument) |
2411 (list 'list (or string (list 'quote type)) | 2437 (list 'list (or string (list 'quote type)) |
2412 temp (list 'quote form)))))) | 2438 temp (list 'quote form)))))) |
2413 (if (eq temp form) (list 'progn body nil) | 2439 (if (eq temp form) (list 'progn body nil) |
2433 (list 'signal '(quote cl-assertion-failed) | 2459 (list 'signal '(quote cl-assertion-failed) |
2434 (list* 'list (list 'quote form) sargs)))) | 2460 (list* 'list (list 'quote form) sargs)))) |
2435 nil)))) | 2461 nil)))) |
2436 | 2462 |
2437 (defmacro ignore-errors (&rest body) | 2463 (defmacro ignore-errors (&rest body) |
2438 "Execute FORMS; if an error occurs, return nil. | 2464 "Execute BODY; if an error occurs, return nil. |
2439 Otherwise, return result of last FORM." | 2465 Otherwise, return result of last form in BODY." |
2440 `(condition-case nil (progn ,@body) (error nil))) | 2466 `(condition-case nil (progn ,@body) (error nil))) |
2441 | 2467 |
2442 | 2468 |
2443 ;;; Compiler macros. | 2469 ;;; Compiler macros. |
2444 | 2470 |
2495 (unsafe (not (cl-safe-expr-p pbody)))) | 2521 (unsafe (not (cl-safe-expr-p pbody)))) |
2496 (while (and p (eq (cl-expr-contains args (car p)) 1)) (pop p)) | 2522 (while (and p (eq (cl-expr-contains args (car p)) 1)) (pop p)) |
2497 (list 'progn | 2523 (list 'progn |
2498 (if p nil ; give up if defaults refer to earlier args | 2524 (if p nil ; give up if defaults refer to earlier args |
2499 (list 'define-compiler-macro name | 2525 (list 'define-compiler-macro name |
2500 (list* '&whole 'cl-whole '&cl-quote args) | 2526 (if (memq '&key args) |
2527 (list* '&whole 'cl-whole '&cl-quote args) | |
2528 (cons '&cl-quote args)) | |
2501 (list* 'cl-defsubst-expand (list 'quote argns) | 2529 (list* 'cl-defsubst-expand (list 'quote argns) |
2502 (list 'quote (list* 'block name body)) | 2530 (list 'quote (list* 'block name body)) |
2503 (not (or unsafe (cl-expr-access-order pbody argns))) | 2531 (not (or unsafe (cl-expr-access-order pbody argns))) |
2504 (and (memq '&key args) 'cl-whole) unsafe argns))) | 2532 (and (memq '&key args) 'cl-whole) unsafe argns))) |
2505 (list* 'defun* name args body)))) | 2533 (list* 'defun* name args body)))) |
2598 (define-compiler-macro typep (&whole form val type) | 2626 (define-compiler-macro typep (&whole form val type) |
2599 (if (cl-const-expr-p type) | 2627 (if (cl-const-expr-p type) |
2600 (let ((res (cl-make-type-test val (cl-const-expr-val type)))) | 2628 (let ((res (cl-make-type-test val (cl-const-expr-val type)))) |
2601 (if (or (memq (cl-expr-contains res val) '(nil 1)) | 2629 (if (or (memq (cl-expr-contains res val) '(nil 1)) |
2602 (cl-simple-expr-p val)) res | 2630 (cl-simple-expr-p val)) res |
2603 (let ((temp (gensym))) | 2631 (let ((temp (make-symbol "--cl-var--"))) |
2604 (list 'let (list (list temp val)) (subst temp val res))))) | 2632 (list 'let (list (list temp val)) (subst temp val res))))) |
2605 form)) | 2633 form)) |
2606 | 2634 |
2607 | 2635 |
2608 (mapcar (function | 2636 (mapc (lambda (y) |
2609 (lambda (y) | 2637 (put (car y) 'side-effect-free t) |
2610 (put (car y) 'side-effect-free t) | 2638 (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro) |
2611 (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro) | 2639 (put (car y) 'cl-compiler-macro |
2612 (put (car y) 'cl-compiler-macro | 2640 `(lambda (w x) |
2613 (list 'lambda '(w x) | 2641 ,(if (symbolp (cadr y)) |
2614 (if (symbolp (cadr y)) | 2642 `(list ',(cadr y) |
2615 (list 'list (list 'quote (cadr y)) | 2643 (list ',(caddr y) x)) |
2616 (list 'list (list 'quote (caddr y)) 'x)) | 2644 (cons 'list (cdr y)))))) |
2617 (cons 'list (cdr y))))))) | 2645 '((first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x) |
2618 '((first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x) | 2646 (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x) |
2619 (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x) | 2647 (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x) |
2620 (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x) | 2648 (rest 'cdr x) (endp 'null x) (plusp '> x 0) (minusp '< x 0) |
2621 (rest 'cdr x) (endp 'null x) (plusp '> x 0) (minusp '< x 0) | 2649 (caaar car caar) (caadr car cadr) (cadar car cdar) |
2622 (caaar car caar) (caadr car cadr) (cadar car cdar) | 2650 (caddr car cddr) (cdaar cdr caar) (cdadr cdr cadr) |
2623 (caddr car cddr) (cdaar cdr caar) (cdadr cdr cadr) | 2651 (cddar cdr cdar) (cdddr cdr cddr) (caaaar car caaar) |
2624 (cddar cdr cdar) (cdddr cdr cddr) (caaaar car caaar) | 2652 (caaadr car caadr) (caadar car cadar) (caaddr car caddr) |
2625 (caaadr car caadr) (caadar car cadar) (caaddr car caddr) | 2653 (cadaar car cdaar) (cadadr car cdadr) (caddar car cddar) |
2626 (cadaar car cdaar) (cadadr car cdadr) (caddar car cddar) | 2654 (cadddr car cdddr) (cdaaar cdr caaar) (cdaadr cdr caadr) |
2627 (cadddr car cdddr) (cdaaar cdr caaar) (cdaadr cdr caadr) | 2655 (cdadar cdr cadar) (cdaddr cdr caddr) (cddaar cdr cdaar) |
2628 (cdadar cdr cadar) (cdaddr cdr caddr) (cddaar cdr cdaar) | 2656 (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr) )) |
2629 (cddadr cdr cdadr) (cdddar cdr cddar) (cddddr cdr cdddr) )) | |
2630 | 2657 |
2631 ;;; Things that are inline. | 2658 ;;; Things that are inline. |
2632 (proclaim '(inline floatp-safe acons map concatenate notany notevery | 2659 (proclaim '(inline floatp-safe acons map concatenate notany notevery |
2633 cl-set-elt revappend nreconc gethash)) | 2660 cl-set-elt revappend nreconc gethash)) |
2634 | 2661 |
2635 ;;; Things that are side-effect-free. | 2662 ;;; Things that are side-effect-free. |
2636 (mapcar (function (lambda (x) (put x 'side-effect-free t))) | 2663 (mapc (lambda (x) (put x 'side-effect-free t)) |
2637 '(oddp evenp signum last butlast ldiff pairlis gcd lcm | 2664 '(oddp evenp signum last butlast ldiff pairlis gcd lcm |
2638 isqrt floor* ceiling* truncate* round* mod* rem* subseq | 2665 isqrt floor* ceiling* truncate* round* mod* rem* subseq |
2639 list-length get* getf)) | 2666 list-length get* getf)) |
2640 | 2667 |
2641 ;;; Things that are side-effect-and-error-free. | 2668 ;;; Things that are side-effect-and-error-free. |
2642 (mapcar (function (lambda (x) (put x 'side-effect-free 'error-free))) | 2669 (mapc (lambda (x) (put x 'side-effect-free 'error-free)) |
2643 '(eql floatp-safe list* subst acons equalp random-state-p | 2670 '(eql floatp-safe list* subst acons equalp random-state-p |
2644 copy-tree sublis)) | 2671 copy-tree sublis)) |
2645 | 2672 |
2646 | 2673 |
2647 (run-hooks 'cl-macs-load-hook) | 2674 (run-hooks 'cl-macs-load-hook) |
2648 | 2675 |
2649 ;;; Local variables: | 2676 ;;; Local variables: |
2650 ;;; byte-compile-warnings: (redefine callargs free-vars unresolved obsolete noruntime) | 2677 ;;; byte-compile-warnings: (redefine callargs free-vars unresolved obsolete noruntime) |
2651 ;;; End: | 2678 ;;; End: |
2652 | 2679 |
2680 ;; arch-tag: afd947a6-b553-4df1-bba5-000be6388f46 | |
2653 ;;; cl-macs.el ends here | 2681 ;;; cl-macs.el ends here |