comparison lisp/cl-macs.el @ 5118:e0db3c197671 ben-lisp-object

merge up to latest default branch, doesn't compile yet
author Ben Wing <ben@xemacs.org>
date Sat, 26 Dec 2009 21:18:49 -0600
parents e29fcfd8df5f
children 95b04754ea8c 8b50bee3c88c
comparison
equal deleted inserted replaced
5117:3742ea8250b5 5118:e0db3c197671
273 '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) 273 '(&optional &rest &key &allow-other-keys &aux &whole &body &environment))
274 274
275 (defvar cl-macro-environment nil) 275 (defvar cl-macro-environment nil)
276 (defvar bind-block) (defvar bind-defs) (defvar bind-enquote) 276 (defvar bind-block) (defvar bind-defs) (defvar bind-enquote)
277 (defvar bind-inits) (defvar bind-lets) (defvar bind-forms) 277 (defvar bind-inits) (defvar bind-lets) (defvar bind-forms)
278 (defvar arglist-visited)
279 278
280 ;; npak@ispras.ru 279 ;; npak@ispras.ru
281 (defun cl-upcase-arg (arg) 280 (defun cl-upcase-arg (arg)
282 ;; Changes all non-keyword symbols in `ARG' to symbols 281 ;; Changes all non-keyword symbols in `ARG' to symbols
283 ;; with name in upper case. 282 ;; with name in upper case.
284 ;; ARG is either symbol or list of symbols or lists 283 ;; ARG is either symbol or list of symbols or lists
285 (cond ((symbolp arg) 284 (cond ((symbolp arg)
286 ;; Do not upcase &optional, &key etc. 285 ;; Do not upcase &optional, &key etc.
287 (if (memq arg lambda-list-keywords) arg 286 (if (memq arg lambda-list-keywords)
288 (intern (upcase (symbol-name arg))))) 287 arg
288 (make-symbol (upcase (symbol-name arg)))))
289 ((listp arg) 289 ((listp arg)
290 (if (memq arg arglist-visited) (error 'circular-list '(arg)))
291 (push arg arglist-visited)
292 (let ((arg (copy-list arg)) junk) 290 (let ((arg (copy-list arg)) junk)
293 ;; Clean the list 291 ;; Clean the list
294 (let ((p (last arg))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 292 (let ((p (last arg))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
295 (if (setq junk (cadr (memq '&cl-defs arg))) 293 (if (setq junk (cadr (memq '&cl-defs arg)))
296 (setq arg (delq '&cl-defs (delq junk arg)))) 294 (setq arg (delq '&cl-defs (delq junk arg))))
298 (setq arg (delq '&cl-quote arg))) 296 (setq arg (delq '&cl-quote arg)))
299 (mapcar 'cl-upcase-arg arg))) 297 (mapcar 'cl-upcase-arg arg)))
300 (t arg))) ; Maybe we are in initializer 298 (t arg))) ; Maybe we are in initializer
301 299
302 ;; npak@ispras.ru 300 ;; npak@ispras.ru
301 ;;;###autoload
303 (defun cl-function-arglist (name arglist) 302 (defun cl-function-arglist (name arglist)
304 "Returns string with printed representation of arguments list. 303 "Returns string with printed representation of arguments list.
305 Supports Common Lisp lambda lists." 304 Supports Common Lisp lambda lists."
306 (if (not (or (listp arglist) (symbolp arglist))) 305 (if (not (or (listp arglist) (symbolp arglist)))
307 "Not available" 306 "Not available"
308 (setq arglist-visited nil) 307 (check-argument-type #'true-list-p arglist)
309 (condition-case nil 308 (let ((print-gensym nil))
310 (prin1-to-string 309 (condition-case nil
311 (cons (if (eq name 'cl-none) 'lambda name) 310 (prin1-to-string
312 (cond ((null arglist) nil) 311 (cons (if (eq name 'cl-none) 'lambda name)
313 ((listp arglist) (cl-upcase-arg arglist)) 312 (cond ((null arglist) nil)
314 ((symbolp arglist) 313 ((listp arglist) (cl-upcase-arg arglist))
315 (cl-upcase-arg (list '&rest arglist))) 314 ((symbolp arglist)
316 (t (wrong-type-argument 'listp arglist))))) 315 (cl-upcase-arg (list '&rest arglist)))
317 (t "Not available")))) 316 (t (wrong-type-argument 'listp arglist)))))
318 317 (t "Not available")))))
319 318
320 (defun cl-transform-lambda (form bind-block) 319 (defun cl-transform-lambda (form bind-block)
321 (let* ((args (car form)) (body (cdr form)) 320 (let* ((args (car form)) (body (cdr form))
322 (bind-defs nil) (bind-enquote nil) 321 (bind-defs nil) (bind-enquote nil)
323 (bind-inits nil) (bind-lets nil) (bind-forms nil) 322 (bind-inits nil) (bind-lets nil) (bind-forms nil)
324 (header nil) (simple-args nil) 323 (header nil) (simple-args nil)
324 (complex-arglist (cl-function-arglist bind-block args))
325 (doc "")) 325 (doc ""))
326 ;; Add CL lambda list to documentation. npak@ispras.ru
327 (if (and (stringp (car body))
328 (cdr body))
329 (setq doc (pop body)))
330 (push (concat doc
331 "\nCommon Lisp lambda list:\n"
332 " " (cl-function-arglist bind-block args)
333 "\n\n")
334 header)
335
336 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive)) 326 (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive))
337 (push (pop body) header)) 327 (push (pop body) header))
338 (setq args (if (listp args) (copy-list args) (list '&rest args))) 328 (setq args (if (listp args) (copy-list args) (list '&rest args)))
339 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 329 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
340 (if (setq bind-defs (cadr (memq '&cl-defs args))) 330 (if (setq bind-defs (cadr (memq '&cl-defs args)))
351 (not (and (eq (car args) '&optional) 341 (not (and (eq (car args) '&optional)
352 (or bind-defs (consp (cadr args)))))) 342 (or bind-defs (consp (cadr args))))))
353 (push (pop args) simple-args)) 343 (push (pop args) simple-args))
354 (or (eq bind-block 'cl-none) 344 (or (eq bind-block 'cl-none)
355 (setq body (list (list* 'block bind-block body)))) 345 (setq body (list (list* 'block bind-block body))))
346 (setq simple-args (nreverse simple-args)
347 header (nreverse header))
348 ;; Add CL lambda list to documentation, if the CL lambda list differs
349 ;; from the non-CL lambda list. npak@ispras.ru
350 (unless (equal complex-arglist
351 (cl-function-arglist bind-block simple-args))
352 (and (stringp (car header)) (setq doc (pop header)))
353 (push (concat doc
354 "\n\nCommon Lisp lambda list:\n"
355 " " complex-arglist "\n\n")
356 header))
356 (if (null args) 357 (if (null args)
357 (list* nil (nreverse simple-args) (nconc (nreverse header) body)) 358 (list* nil simple-args (nconc header body))
358 (if (memq '&optional simple-args) (push '&optional args)) 359 (if (memq '&optional simple-args) (push '&optional args))
359 (cl-do-arglist args nil (- (length simple-args) 360 (cl-do-arglist args nil (- (length simple-args)
360 (if (memq '&optional simple-args) 1 0))) 361 (if (memq '&optional simple-args) 1 0)))
361 (setq bind-lets (nreverse bind-lets)) 362 (setq bind-lets (nreverse bind-lets))
362 (list* (and bind-inits (list* 'eval-when '(compile load eval) 363 (list* (and bind-inits (list* 'eval-when '(compile load eval)
363 (nreverse bind-inits))) 364 (nreverse bind-inits)))
364 (nconc (nreverse simple-args) 365 (nconc simple-args
365 (list '&rest (car (pop bind-lets)))) 366 (list '&rest (car (pop bind-lets))))
366 ;; XEmacs change: we add usage information using Nickolay's 367 ;; XEmacs change: we add usage information using Nickolay's
367 ;; approach above 368 ;; approach above
368 (nconc (nreverse header) 369 (nconc header
369 (list (nconc (list 'let* bind-lets) 370 (list (nconc (list 'let* bind-lets)
370 (nreverse bind-forms) body))))))) 371 (nreverse bind-forms) body)))))))
371 372
372 (defun cl-do-arglist (args expr &optional num) ; uses bind-* 373 (defun cl-do-arglist (args expr &optional num) ; uses bind-*
373 (if (nlistp args) 374 (if (nlistp args)
608 609
609 ;;; Conditional control structures. 610 ;;; Conditional control structures.
610 611
611 ;;;###autoload 612 ;;;###autoload
612 (defmacro case (expr &rest clauses) 613 (defmacro case (expr &rest clauses)
613 "(case EXPR CLAUSES...): evals EXPR, chooses from CLAUSES on that value. 614 "Evals EXPR, chooses from CLAUSES on that value.
614 Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared 615 Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared
615 against each key in each KEYLIST; the corresponding BODY is evaluated. 616 against each key in each KEYLIST; the corresponding BODY is evaluated.
616 If no clause succeeds, case returns nil. A single atom may be used in 617 If no clause succeeds, case returns nil. A single atom may be used in
617 place of a KEYLIST of one atom. A KEYLIST of `t' or `otherwise' is 618 place of a KEYLIST of one atom. A KEYLIST of `t' or `otherwise' is
618 allowed only in the final clause, and matches if no other keys match. 619 allowed only in the final clause, and matches if no other keys match.
653 ;; anything to introduce it, as there is probably much more CL stuff 654 ;; anything to introduce it, as there is probably much more CL stuff
654 ;; missing, and the feature is not essential. --hniksic 655 ;; missing, and the feature is not essential. --hniksic
655 656
656 ;;;###autoload 657 ;;;###autoload
657 (defmacro ecase (expr &rest clauses) 658 (defmacro ecase (expr &rest clauses)
658 "(ecase EXPR CLAUSES...): like `case', but error if no case fits. 659 "Like `case', but error if no case fits.
659 `otherwise'-clauses are not allowed." 660 `otherwise'-clauses are not allowed."
660 ;; XEmacs addition: disallow t and otherwise 661 ;; XEmacs addition: disallow t and otherwise
661 (let ((disallowed (or (assq t clauses) 662 (let ((disallowed (or (assq t clauses)
662 (assq 'otherwise clauses)))) 663 (assq 'otherwise clauses))))
663 (if disallowed 664 (if disallowed
664 (error "`%s' is not allowed in ecase" (car disallowed)))) 665 (error "`%s' is not allowed in ecase" (car disallowed))))
665 (list* 'case expr (append clauses '((ecase-error-flag))))) 666 (list* 'case expr (append clauses '((ecase-error-flag)))))
666 667
667 ;;;###autoload 668 ;;;###autoload
668 (defmacro typecase (expr &rest clauses) 669 (defmacro typecase (expr &rest clauses)
669 "(typecase EXPR CLAUSES...): evals EXPR, chooses from CLAUSES on that value. 670 "Evals EXPR, chooses from CLAUSES on that value.
670 Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it 671 Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it
671 satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds, 672 satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds,
672 typecase returns nil. A TYPE of `t' or `otherwise' is allowed only in the 673 typecase returns nil. A TYPE of `t' or `otherwise' is allowed only in the
673 final clause, and matches if no other keys match." 674 final clause, and matches if no other keys match."
674 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym))) 675 (let* ((temp (if (cl-simple-expr-p expr 3) expr (gensym)))
689 (if (eq temp expr) body 690 (if (eq temp expr) body
690 (list 'let (list (list temp expr)) body)))) 691 (list 'let (list (list temp expr)) body))))
691 692
692 ;;;###autoload 693 ;;;###autoload
693 (defmacro etypecase (expr &rest clauses) 694 (defmacro etypecase (expr &rest clauses)
694 "(etypecase EXPR CLAUSES...): like `typecase', but error if no case fits. 695 "Like `typecase', but error if no case fits.
695 `otherwise'-clauses are not allowed." 696 `otherwise'-clauses are not allowed."
696 (list* 'typecase expr (append clauses '((ecase-error-flag))))) 697 (list* 'typecase expr (append clauses '((ecase-error-flag)))))
697 698
698 699
699 ;;; Blocks and exits. 700 ;;; Blocks and exits.
700 701
701 ;;;###autoload 702 ;;;###autoload
702 (defmacro block (name &rest body) 703 (defmacro block (name &rest body)
703 "(block NAME BODY...): define a lexically-scoped block named NAME. 704 "Define a lexically-scoped block named NAME.
704 NAME may be any symbol. Code inside the BODY forms can call `return-from' 705 NAME may be any symbol. Code inside the BODY forms can call `return-from'
705 to jump prematurely out of the block. This differs from `catch' and `throw' 706 to jump prematurely out of the block. This differs from `catch' and `throw'
706 in two respects: First, the NAME is an unevaluated symbol rather than a 707 in two respects: First, the NAME is an unevaluated symbol rather than a
707 quoted symbol or other form; and second, NAME is lexically rather than 708 quoted symbol or other form; and second, NAME is lexically rather than
708 dynamically scoped: Only references to it within BODY will work. These 709 dynamically scoped: Only references to it within BODY will work. These
713 (list* 'catch (list 'quote (intern (format "--cl-block-%s--" name))) 714 (list* 'catch (list 'quote (intern (format "--cl-block-%s--" name)))
714 body)))) 715 body))))
715 716
716 (defvar cl-active-block-names nil) 717 (defvar cl-active-block-names nil)
717 718
718 (put 'cl-block-wrapper 'byte-compile 'cl-byte-compile-block) 719 (put 'cl-block-wrapper 'byte-compile
719 (defun cl-byte-compile-block (cl-form) 720 #'(lambda (cl-form)
720 (if (fboundp 'byte-compile-form-do-effect) ; Check for optimizing compiler 721 (if (/= (length cl-form) 2)
721 (progn 722 (byte-compile-warn-wrong-args cl-form 1))
722 (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil)) 723
723 (cl-active-block-names (cons cl-entry cl-active-block-names)) 724 (if (fboundp 'byte-compile-form-do-effect) ; Check for optimizing
724 (cl-body (byte-compile-top-level 725 ; compiler
725 (cons 'progn (cddr (nth 1 cl-form)))))) 726 (progn
726 (if (cdr cl-entry) 727 (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil))
727 (byte-compile-form (list 'catch (nth 1 (nth 1 cl-form)) cl-body)) 728 (cl-active-block-names (cons cl-entry
728 (byte-compile-form cl-body)))) 729 cl-active-block-names))
729 (byte-compile-form (nth 1 cl-form)))) 730 (cl-body (byte-compile-top-level
730 731 (cons 'progn (cddr (nth 1 cl-form))))))
731 (put 'cl-block-throw 'byte-compile 'cl-byte-compile-throw) 732 (if (cdr cl-entry)
732 (defun cl-byte-compile-throw (cl-form) 733 (byte-compile-form (list 'catch (nth 1 (nth 1 cl-form))
733 (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names))) 734 cl-body))
734 (if cl-found (setcdr cl-found t))) 735 (byte-compile-form cl-body))))
735 (byte-compile-normal-call (cons 'throw (cdr cl-form)))) 736 (byte-compile-form (nth 1 cl-form)))))
737
738 (put 'cl-block-throw 'byte-compile
739 #'(lambda (cl-form)
740 (let ((cl-found (assq (nth 1 (nth 1 cl-form)) cl-active-block-names)))
741 (if cl-found (setcdr cl-found t)))
742 (byte-compile-throw (cons 'throw (cdr cl-form)))))
736 743
737 ;;;###autoload 744 ;;;###autoload
738 (defmacro return (&optional result) 745 (defmacro return (&optional result)
739 "(return [RESULT]): return from the block named nil. 746 "Return from the block named nil.
740 This is equivalent to `(return-from nil RESULT)'." 747 This is equivalent to `(return-from nil RESULT)'."
741 (list 'return-from nil result)) 748 (list 'return-from nil result))
742 749
743 ;;;###autoload 750 ;;;###autoload
744 (defmacro return-from (name &optional result) 751 (defmacro return-from (name &optional result)
745 "(return-from NAME [RESULT]): return from the block named NAME. 752 "Return from the block named NAME.
746 This jumps out to the innermost enclosing `(block NAME ...)' form, 753 This jumps out to the innermost enclosing `(block NAME ...)' form,
747 returning RESULT from that form (or nil if RESULT is omitted). 754 returning RESULT from that form (or nil if RESULT is omitted).
748 This is compatible with Common Lisp, but note that `defun' and 755 This is compatible with Common Lisp, but note that `defun' and
749 `defmacro' do not create implicit blocks as they do in Common Lisp." 756 `defmacro' do not create implicit blocks as they do in Common Lisp."
750 (let ((name2 (intern (format "--cl-block-%s--" name)))) 757 (let ((name2 (intern (format "--cl-block-%s--" name))))
1695 1702
1696 ;;; Binding control structures. 1703 ;;; Binding control structures.
1697 1704
1698 ;;;###autoload 1705 ;;;###autoload
1699 (defmacro progv (symbols values &rest body) 1706 (defmacro progv (symbols values &rest body)
1700 "(progv SYMBOLS VALUES BODY...): bind SYMBOLS to VALUES dynamically in BODY. 1707 "Bind SYMBOLS to VALUES dynamically in BODY.
1701 The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists. 1708 The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists.
1702 Each SYMBOL in the first list is bound to the corresponding VALUE in the 1709 Each SYMBOL in the first list is bound to the corresponding VALUE in the
1703 second list (or made unbound if VALUES is shorter than SYMBOLS); then the 1710 second list (or made unbound if VALUES is shorter than SYMBOLS); then the
1704 BODY forms are executed and their result is returned. This is much like 1711 BODY forms are executed and their result is returned. This is much like
1705 a `let' form, except that the list of symbols can be computed at run-time." 1712 a `let' form, except that the list of symbols can be computed at run-time."
1784 cl-macro-environment))))) 1791 cl-macro-environment)))))
1785 1792
1786 (defvar cl-closure-vars nil) 1793 (defvar cl-closure-vars nil)
1787 ;;;###autoload 1794 ;;;###autoload
1788 (defmacro lexical-let (bindings &rest body) 1795 (defmacro lexical-let (bindings &rest body)
1789 "(lexical-let BINDINGS BODY...): like `let', but lexically scoped. 1796 "Like `let', but lexically scoped.
1790 The main visible difference is that lambdas inside BODY will create 1797 The main visible difference is that lambdas inside BODY will create
1791 lexical closures as in Common Lisp." 1798 lexical closures as in Common Lisp."
1792 (let* ((cl-closure-vars cl-closure-vars) 1799 (let* ((cl-closure-vars cl-closure-vars)
1793 (vars (mapcar #'(lambda (x) 1800 (vars (mapcar #'(lambda (x)
1794 (or (consp x) (setq x (list x))) 1801 (or (consp x) (setq x (list x)))
1824 vars)) 1831 vars))
1825 ebody)))) 1832 ebody))))
1826 1833
1827 ;;;###autoload 1834 ;;;###autoload
1828 (defmacro lexical-let* (bindings &rest body) 1835 (defmacro lexical-let* (bindings &rest body)
1829 "(lexical-let* BINDINGS BODY...): like `let*', but lexically scoped. 1836 "Like `let*', but lexically scoped.
1830 The main visible difference is that lambdas inside BODY will create 1837 The main visible difference is that lambdas inside BODY will create
1831 lexical closures as in Common Lisp." 1838 lexical closures as in Common Lisp."
1832 (if (null bindings) (cons 'progn body) 1839 (if (null bindings) (cons 'progn body)
1833 (setq bindings (reverse bindings)) 1840 (setq bindings (reverse bindings))
1834 (while bindings 1841 (while bindings
1839 (list 'progn 1846 (list 'progn
1840 (list 'defalias (list 'quote func) 1847 (list 'defalias (list 'quote func)
1841 (list 'function (cons 'lambda rest))) 1848 (list 'function (cons 'lambda rest)))
1842 (list 'quote func))) 1849 (list 'quote func)))
1843 1850
1844 1851 ;;; Multiple values. We support full Common Lisp conventions here.
1845 ;;; Multiple values. 1852
1846 1853 ;;;###autoload
1847 ;;;###autoload 1854 (defmacro multiple-value-bind (syms form &rest body)
1848 (defmacro multiple-value-bind (vars form &rest body) 1855 "Collect and bind multiple return values.
1849 "(multiple-value-bind (SYM SYM...) FORM BODY): collect multiple return values. 1856
1850 FORM must return a list; the BODY is then executed with the first N elements 1857 If FORM returns multiple values, each symbol in SYMS is bound to one of
1851 of this list bound (`let'-style) to each of the symbols SYM in turn. This 1858 them, in order, and BODY is executed. If FORM returns fewer multiple values
1852 is analogous to the Common Lisp `multiple-value-bind' macro, using lists to 1859 than there are SYMS, remaining SYMS are bound to nil. If FORM does
1853 simulate true multiple return values. For compatibility, (values A B C) is 1860 not return multiple values, it is treated as returning one multiple value.
1854 a synonym for (list A B C)." 1861
1855 (let ((temp (gensym)) (n -1)) 1862 Returns the value given by the last element of BODY."
1856 (list* 'let* (cons (list temp form) 1863 (if (null syms)
1857 (mapcar #'(lambda (v) 1864 `(progn ,form ,@body)
1858 (list v (list 'nth (setq n (1+ n)) temp))) 1865 (if (= 1 (length syms))
1859 vars)) 1866 ;; Code written to deal with other "implementations" of multiple
1860 body))) 1867 ;; values may have a one-element SYMS.
1861 1868 `(let ((,(car syms) ,form))
1862 ;;;###autoload 1869 ,@body)
1863 (defmacro multiple-value-setq (vars form) 1870 (let ((temp (gensym)))
1864 "(multiple-value-setq (SYM SYM...) FORM): collect multiple return values. 1871 `(let* ((,temp (multiple-value-list-internal 0 ,(length syms) ,form))
1865 FORM must return a list; the first N elements of this list are stored in 1872 ,@(loop
1866 each of the symbols SYM in turn. This is analogous to the Common Lisp 1873 for var in syms
1867 `multiple-value-setq' macro, using lists to simulate true multiple return 1874 collect `(,var (prog1 (car ,temp)
1868 values. For compatibility, (values A B C) is a synonym for (list A B C)." 1875 (setq ,temp (cdr ,temp))))))
1869 (cond ((null vars) (list 'progn form nil)) 1876 ,@body)))))
1870 ((null (cdr vars)) (list 'setq (car vars) (list 'car form))) 1877
1871 (t 1878 ;;;###autoload
1872 (let* ((temp (gensym)) (n 0)) 1879 (defmacro multiple-value-setq (syms form)
1873 (list 'let (list (list temp form)) 1880 "Collect and set multiple values.
1874 (list 'prog1 (list 'setq (pop vars) (list 'car temp)) 1881
1875 (cons 'setq 1882 FORM should normally return multiple values; the first N values are stored
1876 (apply 'nconc 1883 in the symbols in SYMS in turn. If FORM returns fewer than N values, the
1877 (mapcar 1884 remaining symbols have their values set to nil. FORM not returning multiple
1878 #'(lambda (v) 1885 values is treated as FORM returning one multiple value, with other elements
1879 (list v (list 1886 of SYMS initialized to nil.
1880 'nth 1887
1881 (setq n (1+ n)) 1888 Returns the first of the multiple values given by FORM."
1882 temp))) 1889 (if (null syms)
1883 vars))))))))) 1890 ;; Never return multiple values from multiple-value-setq:
1884 1891 (and form `(values ,form))
1892 (if (= 1 (length syms))
1893 `(setq ,(car syms) ,form)
1894 (let ((temp (gensym)))
1895 `(let* ((,temp (multiple-value-list-internal 0 ,(length syms) ,form)))
1896 (setq ,@(loop
1897 for sym in syms
1898 nconc `(,sym (car-safe ,temp)
1899 ,temp (cdr-safe ,temp))))
1900 ,(car syms))))))
1901
1902 ;;;###autoload
1903 (defmacro multiple-value-list (form)
1904 "Evaluate FORM and return a list of the multiple values it returned."
1905 `(multiple-value-list-internal 0 multiple-values-limit ,form))
1906
1907 ;;;###autoload
1908 (defmacro nth-value (n form)
1909 "Evaluate FORM and return the Nth multiple value it returned."
1910 (if (integerp n)
1911 `(car (multiple-value-list-internal ,n ,(1+ n) ,form))
1912 (let ((temp (gensym)))
1913 `(let ((,temp ,n))
1914 (car (multiple-value-list-internal ,temp (1+ ,temp) ,form))))))
1885 1915
1886 ;;; Declarations. 1916 ;;; Declarations.
1887 1917
1888 ;;;###autoload 1918 ;;;###autoload
1889 (defmacro locally (&rest body) (cons 'progn body)) 1919 (defmacro locally (&rest body) (cons 'progn body))
2344 (get-setf-method x cl-macro-environment)) 2374 (get-setf-method x cl-macro-environment))
2345 args)) 2375 args))
2346 (store-temp (gensym "--values-store--"))) 2376 (store-temp (gensym "--values-store--")))
2347 (list (apply 'append (mapcar 'first methods)) 2377 (list (apply 'append (mapcar 'first methods))
2348 (apply 'append (mapcar 'second methods)) 2378 (apply 'append (mapcar 'second methods))
2349 (list store-temp) 2379 `((,store-temp
2350 (cons 'list 2380 (multiple-value-list-internal 0 ,(if args (length args) 1))))
2381 (cons 'values
2351 (mapcar #'(lambda (m) 2382 (mapcar #'(lambda (m)
2352 (cl-setf-do-store (cons (car (third m)) (fourth m)) 2383 (cl-setf-do-store (cons (car (third m)) (fourth m))
2353 (list 'pop store-temp))) 2384 (list 'pop store-temp)))
2354 methods)) 2385 methods))
2355 (cons 'list (mapcar 'fifth methods))))) 2386 (cons 'list (mapcar 'fifth methods)))))
2408 (sublis subs (nth 4 method))))) 2439 (sublis subs (nth 4 method)))))
2409 2440
2410 (defun cl-setf-do-store (spec val) 2441 (defun cl-setf-do-store (spec val)
2411 (let ((sym (car spec)) 2442 (let ((sym (car spec))
2412 (form (cdr spec))) 2443 (form (cdr spec)))
2413 (if (or (cl-const-expr-p val) 2444 (if (consp sym)
2414 (and (cl-simple-expr-p val) (eq (cl-expr-contains form sym) 1)) 2445 ;; XEmacs change, only used for implementing #'values at the moment.
2415 (cl-setf-simple-store-p sym form)) 2446 (let* ((orig (copy-list sym))
2416 (subst val sym form) 2447 (intermediate (last orig))
2417 (list 'let (list (list sym val)) form)))) 2448 (circular-limit 32))
2449 (while (consp (car intermediate))
2450 (when (zerop circular-limit)
2451 (error 'circular-list "Form seems to contain loops"))
2452 (setq intermediate (last (car intermediate))
2453 circular-limit (1- circular-limit)))
2454 (setcdr intermediate (list val))
2455 `(let (,orig)
2456 ,form))
2457 (if (or (cl-const-expr-p val)
2458 (and (cl-simple-expr-p val)
2459 (eq (cl-expr-contains form sym) 1))
2460 (cl-setf-simple-store-p sym form))
2461 (subst val sym form)
2462 (list 'let (list (list sym val)) form)))))
2418 2463
2419 (defun cl-setf-simple-store-p (sym form) 2464 (defun cl-setf-simple-store-p (sym form)
2420 (and (consp form) (eq (cl-expr-contains form sym) 1) 2465 (and (consp form) (eq (cl-expr-contains form sym) 1)
2421 (eq (nth (1- (length form)) form) sym) 2466 (eq (nth (1- (length form)) form) sym)
2422 (symbolp (car form)) (fboundp (car form)) 2467 (symbolp (car form)) (fboundp (car form))
2475 (list 'car temp) 2520 (list 'car temp)
2476 (cl-setf-do-store (nth 1 method) (list 'cdr temp))))))) 2521 (cl-setf-do-store (nth 1 method) (list 'cdr temp)))))))
2477 2522
2478 ;;;###autoload 2523 ;;;###autoload
2479 (defmacro remf (place tag) 2524 (defmacro remf (place tag)
2480 "(remf PLACE TAG): remove TAG from property list PLACE. 2525 "Remove TAG from property list PLACE.
2481 PLACE may be a symbol, or any generalized variable allowed by `setf'. 2526 PLACE may be a symbol, or any generalized variable allowed by `setf'.
2482 The form returns true if TAG was found and removed, nil otherwise." 2527 The form returns true if TAG was found and removed, nil otherwise."
2483 (let* ((method (cl-setf-do-modify place t)) 2528 (let* ((method (cl-setf-do-modify place t))
2484 (tag-temp (and (not (cl-const-expr-p tag)) (gensym "--remf-tag--"))) 2529 (tag-temp (and (not (cl-const-expr-p tag)) (gensym "--remf-tag--")))
2485 (val-temp (and (not (cl-simple-expr-p place)) 2530 (val-temp (and (not (cl-simple-expr-p place))
2540 (cl-setf-do-store (nth 1 method) form)))))) 2585 (cl-setf-do-store (nth 1 method) form))))))
2541 (let ((method (cl-setf-do-modify (car places) 'unsafe))) 2586 (let ((method (cl-setf-do-modify (car places) 'unsafe)))
2542 (list 'let* (append (car method) (list (list temp (nth 2 method)))) 2587 (list 'let* (append (car method) (list (list temp (nth 2 method))))
2543 (cl-setf-do-store (nth 1 method) form) nil))))) 2588 (cl-setf-do-store (nth 1 method) form) nil)))))
2544 2589
2590 ;; This function is not in Common Lisp, and there are gaps in its structure and
2591 ;; implementation that reflect that it was never well-specified. E.g. with
2592 ;; setf, the question of whether a PLACE is bound or not and how to make it
2593 ;; unbound doesn't arise, but we need some way of specifying that for letf to
2594 ;; be sensible for gethash, symbol-value and so on; currently we just hard-code
2595 ;; symbol-value, symbol-function and values (the latter is XEmacs work that
2596 ;; I've just done) in the body of this function, and the following gives the
2597 ;; wrong behaviour for gethash:
2598 ;;
2599 ;; (setq my-hash-table #s(hash-table test equal data ())
2600 ;; print-gensym t)
2601 ;; => t
2602 ;; (gethash "my-key" my-hash-table (gensym))
2603 ;; => #:G68010
2604 ;; (letf (((gethash "my-key" my-hash-table) 4000))
2605 ;; (message "key value is %S" (gethash "my-key" my-hash-table)))
2606 ;; => "key value is 4000"
2607 ;; (gethash "my-key" my-hash-table (gensym))
2608 ;; => nil ;; should be an uninterned symbol.
2609 ;;
2610 ;; Aidan Kehoe, Fr Nov 13 16:12:21 GMT 2009
2611
2545 ;;;###autoload 2612 ;;;###autoload
2546 (defmacro letf (bindings &rest body) 2613 (defmacro letf (bindings &rest body)
2547 "(letf ((PLACE VALUE) ...) BODY...): temporarily bind to PLACEs. 2614 "(letf ((PLACE VALUE) ...) BODY...): temporarily bind to PLACEs.
2548 This is the analogue of `let', but with generalized variables (in the 2615 This is the analogue of `let', but with generalized variables (in the
2549 sense of `setf') for the PLACEs. Each PLACE is set to the corresponding 2616 sense of `setf') for the PLACEs. Each PLACE is set to the corresponding
2561 (list 'symbol-value (list 'quote (caar rev))) 2628 (list 'symbol-value (list 'quote (caar rev)))
2562 (caar rev))) 2629 (caar rev)))
2563 (value (cadar rev)) 2630 (value (cadar rev))
2564 (method (cl-setf-do-modify place 'no-opt)) 2631 (method (cl-setf-do-modify place 'no-opt))
2565 (save (gensym "--letf-save--")) 2632 (save (gensym "--letf-save--"))
2566 (bound (and (memq (car place) '(symbol-value symbol-function)) 2633 (bound (and (memq (car place)
2634 '(symbol-value symbol-function values))
2567 (gensym "--letf-bound--"))) 2635 (gensym "--letf-bound--")))
2568 (temp (and (not (cl-const-expr-p value)) (cdr bindings) 2636 (temp (and (not (cl-const-expr-p value)) (cdr bindings)
2569 (gensym "--letf-val--")))) 2637 (gensym "--letf-val--")))
2638 (syms (and (eq 'values (car place))
2639 (gensym "--letf-syms--")))
2640 (cursor (and syms (gensym "--letf-cursor--"))))
2570 (setq lets (nconc (car method) 2641 (setq lets (nconc (car method)
2571 (if bound 2642 (cond
2572 (list (list bound 2643 (syms
2573 (list (if (eq (car place) 2644 `((,syms ',(loop
2574 'symbol-value) 2645 for sym in (cdr place)
2575 'boundp 'fboundp) 2646 nconc (if (symbolp sym) (list sym))))
2576 (nth 1 (nth 2 method)))) 2647 (,cursor ,syms)
2577 (list save (list 'and bound 2648 (,bound nil)
2578 (nth 2 method)))) 2649 (,save
2579 (list (list save (nth 2 method)))) 2650 (prog2
2651 (while (consp ,cursor)
2652 (setq ,bound
2653 (cons (and (boundp (car ,cursor))
2654 (symbol-value
2655 (car ,cursor)))
2656 ,bound)
2657 ,cursor (cdr ,cursor)))
2658 ;; Just using ,bound as a temporary
2659 ;; variable here, to initialise ,save:
2660 (nreverse ,bound)
2661 ;; Now, really initialise ,bound:
2662 (setq ,cursor ,syms
2663 ,bound nil
2664 ,bound
2665 (progn (while (consp ,cursor)
2666 (setq ,bound
2667 (cons
2668 (boundp (car ,cursor))
2669 ,bound)
2670 ,cursor (cdr ,cursor)))
2671 (nreverse ,bound)))))))
2672 (bound
2673 (list (list bound
2674 (list (if (eq (car place)
2675 'symbol-value)
2676 'boundp 'fboundp)
2677 (nth 1 (nth 2 method))))
2678 (list save (list 'and bound
2679 (nth 2 method)))))
2680 (t
2681 (list (list save (nth 2 method)))))
2580 (and temp (list (list temp value))) 2682 (and temp (list (list temp value)))
2581 lets) 2683 lets)
2582 body (list 2684 body (list
2583 (list 'unwind-protect 2685 (list 'unwind-protect
2584 (cons 'progn 2686 (cons 'progn
2585 (if (cdr (car rev)) 2687 (if (cdr (car rev))
2586 (cons (cl-setf-do-store (nth 1 method) 2688 (cons (cl-setf-do-store (nth 1 method)
2587 (or temp value)) 2689 (or temp value))
2588 body) 2690 body)
2589 body)) 2691 body))
2590 (if bound 2692 (cond
2591 (list 'if bound 2693 (syms
2592 (cl-setf-do-store (nth 1 method) save) 2694 `(while (consp ,syms)
2593 (list (if (eq (car place) 'symbol-value) 2695 (if (car ,bound)
2594 'makunbound 'fmakunbound) 2696 (set (car ,syms) (car ,save))
2595 (nth 1 (nth 2 method)))) 2697 (makunbound (car ,syms)))
2596 (cl-setf-do-store (nth 1 method) save)))) 2698 (setq ,syms (cdr ,syms)
2699 ,bound (cdr ,bound)
2700 ,save (cdr ,save))))
2701 (bound
2702 (list 'if bound
2703 (cl-setf-do-store (nth 1 method) save)
2704 (list (if (eq (car place)
2705 'symbol-function)
2706 'fmakunbound
2707 'makunbound)
2708 (nth 1 (nth 2 method)))))
2709 (t
2710 (cl-setf-do-store (nth 1 method) save)))))
2597 rev (cdr rev)))) 2711 rev (cdr rev))))
2598 (list* 'let* lets body)))) 2712 (list* 'let* lets body))))
2599 2713
2600 ;;;###autoload 2714 ;;;###autoload
2601 (defmacro letf* (bindings &rest body) 2715 (defmacro letf* (bindings &rest body)
2614 (setq body (list (list* 'letf (list (pop bindings)) body)))) 2728 (setq body (list (list* 'letf (list (pop bindings)) body))))
2615 (car body))) 2729 (car body)))
2616 2730
2617 ;;;###autoload 2731 ;;;###autoload
2618 (defmacro callf (func place &rest args) 2732 (defmacro callf (func place &rest args)
2619 "(callf FUNC PLACE ARGS...): set PLACE to (FUNC PLACE ARGS...). 2733 "Set PLACE to (FUNC PLACE ARGS...).
2620 FUNC should be an unquoted function name. PLACE may be a symbol, 2734 FUNC should be an unquoted function name. PLACE may be a symbol,
2621 or any generalized variable allowed by `setf'." 2735 or any generalized variable allowed by `setf'."
2622 (let* ((method (cl-setf-do-modify place (cons 'list args))) 2736 (let* ((method (cl-setf-do-modify place (cons 'list args)))
2623 (rargs (cons (nth 2 method) args))) 2737 (rargs (cons (nth 2 method) args)))
2624 (list 'let* (car method) 2738 (list 'let* (car method)
2627 (list* 'funcall (list 'function func) 2741 (list* 'funcall (list 'function func)
2628 rargs)))))) 2742 rargs))))))
2629 2743
2630 ;;;###autoload 2744 ;;;###autoload
2631 (defmacro callf2 (func arg1 place &rest args) 2745 (defmacro callf2 (func arg1 place &rest args)
2632 "(callf2 FUNC ARG1 PLACE ARGS...): set PLACE to (FUNC ARG1 PLACE ARGS...). 2746 "Set PLACE to (FUNC ARG1 PLACE ARGS...).
2633 Like `callf', but PLACE is the second argument of FUNC, not the first." 2747 Like `callf', but PLACE is the second argument of FUNC, not the first."
2634 (if (and (cl-safe-expr-p arg1) (cl-simple-expr-p place) (symbolp func)) 2748 (if (and (cl-safe-expr-p arg1) (cl-simple-expr-p place) (symbolp func))
2635 (list 'setf place (list* func arg1 place args)) 2749 (list 'setf place (list* func arg1 place args))
2636 (let* ((method (cl-setf-do-modify place (cons 'list args))) 2750 (let* ((method (cl-setf-do-modify place (cons 'list args)))
2637 (temp (and (not (cl-const-expr-p arg1)) (gensym "--arg1--"))) 2751 (temp (and (not (cl-const-expr-p arg1)) (gensym "--arg1--")))
2642 (list* 'funcall (list 'function func) 2756 (list* 'funcall (list 'function func)
2643 rargs))))))) 2757 rargs)))))))
2644 2758
2645 ;;;###autoload 2759 ;;;###autoload
2646 (defmacro define-modify-macro (name arglist func &optional doc) 2760 (defmacro define-modify-macro (name arglist func &optional doc)
2647 "(define-modify-macro NAME ARGLIST FUNC): define a `setf'-like modify macro. 2761 "Define a `setf'-like modify macro.
2648 If NAME is called, it combines its PLACE argument with the other arguments 2762 If NAME is called, it combines its PLACE argument with the other arguments
2649 from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)" 2763 from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)"
2650 (if (memq '&key arglist) (error "&key not allowed in define-modify-macro")) 2764 (if (memq '&key arglist) (error "&key not allowed in define-modify-macro"))
2651 (let ((place (gensym "--place--"))) 2765 (let ((place (gensym "--place--")))
2652 (list 'defmacro* name (cons place arglist) doc 2766 (list 'defmacro* name (cons place arglist) doc
2896 3010
2897 ;;; Types and assertions. 3011 ;;; Types and assertions.
2898 3012
2899 ;;;###autoload 3013 ;;;###autoload
2900 (defmacro deftype (name arglist &rest body) 3014 (defmacro deftype (name arglist &rest body)
2901 "(deftype NAME ARGLIST BODY...): define NAME as a new data type. 3015 "Define NAME as a new data type.
2902 The type name can then be used in `typecase', `check-type', etc." 3016 The type name can then be used in `typecase', `check-type', etc."
2903 (list 'eval-when '(compile load eval) 3017 (list 'eval-when '(compile load eval)
2904 (cl-transform-function-property 3018 (cl-transform-function-property
2905 name 'cl-deftype-handler (cons (list* '&cl-defs ''('*) arglist) body)))) 3019 name 'cl-deftype-handler (cons (list* '&cl-defs ''('*) arglist) body))))
2906 3020
3004 3118
3005 ;;; Compiler macros. 3119 ;;; Compiler macros.
3006 3120
3007 ;;;###autoload 3121 ;;;###autoload
3008 (defmacro define-compiler-macro (func args &rest body) 3122 (defmacro define-compiler-macro (func args &rest body)
3009 "(define-compiler-macro FUNC ARGLIST BODY...): Define a compiler-only macro. 3123 "Define a compiler-only macro.
3010 This is like `defmacro', but macro expansion occurs only if the call to 3124 This is like `defmacro', but macro expansion occurs only if the call to
3011 FUNC is compiled (i.e., not interpreted). Compiler macros should be used 3125 FUNC is compiled (i.e., not interpreted). Compiler macros should be used
3012 for optimizing the way calls to FUNC are compiled; the form returned by 3126 for optimizing the way calls to FUNC are compiled; the form returned by
3013 BODY should do the same thing as a call to the normal function called 3127 BODY should do the same thing as a call to the normal function called
3014 FUNC, though possibly more efficiently. Note that, like regular macros, 3128 FUNC, though possibly more efficiently. Note that, like regular macros,
3167 (cl-simple-expr-p val)) res 3281 (cl-simple-expr-p val)) res
3168 (let ((temp (gensym))) 3282 (let ((temp (gensym)))
3169 (list 'let (list (list temp val)) (subst temp val res))))) 3283 (list 'let (list (list temp val)) (subst temp val res)))))
3170 form)) 3284 form))
3171 3285
3286 ;; XEmacs; inline delete-duplicates if it's called with a literal
3287 ;; #'equal or #'eq and no other keywords, we want the speed in
3288 ;; font-lock.el.
3289 (define-compiler-macro delete-duplicates (&whole form cl-seq &rest cl-keys)
3290 (let ((listp-check
3291 (if (memq (car-safe cl-seq)
3292 ;; No need to check for a list at runtime with these. We
3293 ;; could expand the list, but these are all the functions
3294 ;; in the relevant context at the moment.
3295 '(nreverse append nconc mapcan mapcar))
3296 t
3297 '(listp begin))))
3298 (cond ((and (= 4 (length form))
3299 (eq :test (third form))
3300 (or (equal '(quote eq) (fourth form))
3301 (equal '(function eq) (fourth form))))
3302 `(let* ((begin ,cl-seq)
3303 (cl-seq begin))
3304 (if ,listp-check
3305 (progn
3306 (while cl-seq
3307 (setq cl-seq (setcdr cl-seq (delq (car cl-seq)
3308 (cdr cl-seq)))))
3309 begin)
3310 ;; Call cl-delete-duplicates explicitly, to avoid the form
3311 ;; getting compiler-macroexpanded again:
3312 (cl-delete-duplicates begin ',cl-keys nil))))
3313 ((and (= 4 (length form))
3314 (eq :test (third form))
3315 (or (equal '(quote equal) (fourth form))
3316 (equal '(function equal) (fourth form))))
3317 `(let* ((begin ,cl-seq)
3318 (cl-seq begin))
3319 (if ,listp-check
3320 (progn
3321 (while cl-seq
3322 (setq cl-seq (setcdr cl-seq (delete (car cl-seq)
3323 (cdr cl-seq)))))
3324 begin)
3325 ;; Call cl-delete-duplicates explicitly, to avoid the form
3326 ;; getting compiler-macroexpanded again:
3327 (cl-delete-duplicates begin ',cl-keys nil))))
3328 (t
3329 form))))
3330
3331 ;; XEmacs change, the GNU mapc doesn't accept the Common Lisp args, so this
3332 ;; change isn't helpful.
3333 (define-compiler-macro mapc (&whole form cl-func cl-seq &rest cl-rest)
3334 (if cl-rest
3335 form
3336 (cons 'mapc-internal (cdr form))))
3337
3338 (define-compiler-macro mapcar* (&whole form cl-func cl-x &rest cl-rest)
3339 (if cl-rest
3340 form
3341 (cons 'mapcar (cdr form))))
3342
3343 ;; XEmacs; it's perfectly reasonable, and often much clearer to those
3344 ;; reading the code, to call regexp-quote on a constant string, which is
3345 ;; something we can optimise here easily.
3346 (define-compiler-macro regexp-quote (&whole form string)
3347 (if (stringp string)
3348 (regexp-quote string)
3349 form))
3172 3350
3173 (mapc 3351 (mapc
3174 #'(lambda (y) 3352 #'(lambda (y)
3175 (put (car y) 'side-effect-free t) 3353 (put (car y) 'side-effect-free t)
3176 (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro) 3354 (put (car y) 'byte-compile 'cl-byte-compile-compiler-macro)