diff options
| author | Stefan Monnier | 2019-08-06 04:01:49 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2019-08-06 04:01:49 -0400 |
| commit | 1d8b5bc8dd543ada2f3c46436e43ea27faa3cd0e (patch) | |
| tree | db3ebd6d9f00fb60280efef3763271e26e60cd15 /lisp/obsolete | |
| parent | 6231483b7e13f1ad34b8aec560e7cc640059d6f9 (diff) | |
| download | emacs-1d8b5bc8dd543ada2f3c46436e43ea27faa3cd0e.tar.gz emacs-1d8b5bc8dd543ada2f3c46436e43ea27faa3cd0e.zip | |
Move cl.el to lisp/obsolete
* lisp/emacs-lisp/cl.el: Move from here...
* lisp/obsolete/cl.el: ...to here.
* lisp/subr.el (do-after-load-evaluation): Use "deprecated" in the
message when loading packages from lisp/obsolete.
Diffstat (limited to 'lisp/obsolete')
| -rw-r--r-- | lisp/obsolete/cl.el | 704 |
1 files changed, 704 insertions, 0 deletions
diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el new file mode 100644 index 00000000000..417c757ed52 --- /dev/null +++ b/lisp/obsolete/cl.el | |||
| @@ -0,0 +1,704 @@ | |||
| 1 | ;;; cl.el --- Compatibility aliases for the old CL library. -*- lexical-binding: t -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2012-2019 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 6 | ;; Deprecated-since: 27.1 | ||
| 7 | ;; Keywords: extensions | ||
| 8 | |||
| 9 | ;; This file is part of GNU Emacs. | ||
| 10 | |||
| 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 12 | ;; it under the terms of the GNU General Public License as published by | ||
| 13 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 14 | ;; (at your option) any later version. | ||
| 15 | |||
| 16 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | ;; GNU General Public License for more details. | ||
| 20 | |||
| 21 | ;; You should have received a copy of the GNU General Public License | ||
| 22 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 23 | |||
| 24 | ;;; Commentary: | ||
| 25 | |||
| 26 | ;; This is a compatibility file which provides the old names provided by CL | ||
| 27 | ;; before we cleaned up its namespace usage. | ||
| 28 | |||
| 29 | ;;; Code: | ||
| 30 | |||
| 31 | (require 'cl-lib) | ||
| 32 | (require 'macroexp) | ||
| 33 | (require 'gv) | ||
| 34 | |||
| 35 | ;; (defun cl--rename () | ||
| 36 | ;; (let ((vdefs ()) | ||
| 37 | ;; (fdefs ()) | ||
| 38 | ;; (case-fold-search nil) | ||
| 39 | ;; (files '("cl.el" "cl-macs.el" "cl-seq.el" "cl-extra.el"))) | ||
| 40 | ;; (dolist (file files) | ||
| 41 | ;; (with-current-buffer (find-file-noselect file) | ||
| 42 | ;; (goto-char (point-min)) | ||
| 43 | ;; (while (re-search-forward | ||
| 44 | ;; "^(\\(def[^ \t\n]*\\) +'?\\(\\(\\sw\\|\\s_\\)+\\)" nil t) | ||
| 45 | ;; (let ((name (match-string-no-properties 2)) | ||
| 46 | ;; (type (match-string-no-properties 1))) | ||
| 47 | ;; (unless (string-match-p "\\`cl-" name) | ||
| 48 | ;; (cond | ||
| 49 | ;; ((member type '("defvar" "defconst")) | ||
| 50 | ;; (unless (member name vdefs) (push name vdefs))) | ||
| 51 | ;; ((member type '("defun" "defsubst" "defalias" "defmacro")) | ||
| 52 | ;; (unless (member name fdefs) (push name fdefs))) | ||
| 53 | ;; ((member type '("def-edebug-spec" "defsetf" "define-setf-method" | ||
| 54 | ;; "define-compiler-macro")) | ||
| 55 | ;; nil) | ||
| 56 | ;; (t (error "Unknown type %S" type)))))))) | ||
| 57 | ;; (let ((re (concat "\\_<" (regexp-opt (append vdefs fdefs)) "\\_>")) | ||
| 58 | ;; (conflicts ())) | ||
| 59 | ;; (dolist (file files) | ||
| 60 | ;; (with-current-buffer (find-file-noselect file) | ||
| 61 | ;; (goto-char (point-min)) | ||
| 62 | ;; (while (re-search-forward re nil t) | ||
| 63 | ;; (replace-match "cl-\\&")) | ||
| 64 | ;; (save-buffer)))) | ||
| 65 | ;; (with-current-buffer (find-file-noselect "cl-rename.el") | ||
| 66 | ;; (dolist (def vdefs) | ||
| 67 | ;; (insert (format "(defvaralias '%s 'cl-%s)\n" def def))) | ||
| 68 | ;; (dolist (def fdefs) | ||
| 69 | ;; (insert (format "(defalias '%s 'cl-%s)\n" def def))) | ||
| 70 | ;; (save-buffer)))) | ||
| 71 | |||
| 72 | ;; (defun cl--unrename () | ||
| 73 | ;; ;; Taken from "Naming Conventions" node of the doc. | ||
| 74 | ;; (let* ((names '(defun* defsubst* defmacro* function* member* | ||
| 75 | ;; assoc* rassoc* get* remove* delete* | ||
| 76 | ;; mapcar* sort* floor* ceiling* truncate* | ||
| 77 | ;; round* mod* rem* random*)) | ||
| 78 | ;; (files '("cl.el" "cl-lib.el" "cl-macs.el" "cl-seq.el" "cl-extra.el")) | ||
| 79 | ;; (re (concat "\\_<cl-" (regexp-opt (mapcar #'symbol-name names)) | ||
| 80 | ;; "\\_>"))) | ||
| 81 | ;; (dolist (file files) | ||
| 82 | ;; (with-current-buffer (find-file-noselect file) | ||
| 83 | ;; (goto-char (point-min)) | ||
| 84 | ;; (while (re-search-forward re nil t) | ||
| 85 | ;; (delete-region (1- (point)) (point))) | ||
| 86 | ;; (save-buffer))))) | ||
| 87 | |||
| 88 | (defun cl-unload-function () | ||
| 89 | "Stop unloading of the Common Lisp extensions." | ||
| 90 | (message "Cannot unload the feature `cl'") | ||
| 91 | ;; Stop standard unloading! | ||
| 92 | t) | ||
| 93 | |||
| 94 | ;;; Aliases to cl-lib's features. | ||
| 95 | |||
| 96 | (dolist (var '( | ||
| 97 | ;; loop-result-var | ||
| 98 | ;; loop-result | ||
| 99 | ;; loop-initially | ||
| 100 | ;; loop-finally | ||
| 101 | ;; loop-bindings | ||
| 102 | ;; loop-args | ||
| 103 | ;; bind-inits | ||
| 104 | ;; bind-block | ||
| 105 | ;; lambda-list-keywords | ||
| 106 | float-negative-epsilon | ||
| 107 | float-epsilon | ||
| 108 | least-negative-normalized-float | ||
| 109 | least-positive-normalized-float | ||
| 110 | least-negative-float | ||
| 111 | least-positive-float | ||
| 112 | most-negative-float | ||
| 113 | most-positive-float | ||
| 114 | ;; custom-print-functions | ||
| 115 | )) | ||
| 116 | (defvaralias var (intern (format "cl-%s" var)))) | ||
| 117 | |||
| 118 | (dolist (fun '( | ||
| 119 | (get* . cl-get) | ||
| 120 | (random* . cl-random) | ||
| 121 | (rem* . cl-rem) | ||
| 122 | (mod* . cl-mod) | ||
| 123 | (round* . cl-round) | ||
| 124 | (truncate* . cl-truncate) | ||
| 125 | (ceiling* . cl-ceiling) | ||
| 126 | (floor* . cl-floor) | ||
| 127 | (rassoc* . cl-rassoc) | ||
| 128 | (assoc* . cl-assoc) | ||
| 129 | (member* . cl-member) | ||
| 130 | (delete* . cl-delete) | ||
| 131 | (remove* . cl-remove) | ||
| 132 | (defsubst* . cl-defsubst) | ||
| 133 | (sort* . cl-sort) | ||
| 134 | (function* . cl-function) | ||
| 135 | (defmacro* . cl-defmacro) | ||
| 136 | (defun* . cl-defun) | ||
| 137 | (mapcar* . cl-mapcar) | ||
| 138 | |||
| 139 | remprop | ||
| 140 | getf | ||
| 141 | tailp | ||
| 142 | list-length | ||
| 143 | nreconc | ||
| 144 | revappend | ||
| 145 | concatenate | ||
| 146 | subseq | ||
| 147 | random-state-p | ||
| 148 | make-random-state | ||
| 149 | signum | ||
| 150 | isqrt | ||
| 151 | lcm | ||
| 152 | gcd | ||
| 153 | notevery | ||
| 154 | notany | ||
| 155 | every | ||
| 156 | some | ||
| 157 | mapcon | ||
| 158 | mapl | ||
| 159 | maplist | ||
| 160 | map | ||
| 161 | equalp | ||
| 162 | coerce | ||
| 163 | tree-equal | ||
| 164 | nsublis | ||
| 165 | sublis | ||
| 166 | nsubst-if-not | ||
| 167 | nsubst-if | ||
| 168 | nsubst | ||
| 169 | subst-if-not | ||
| 170 | subst-if | ||
| 171 | subsetp | ||
| 172 | nset-exclusive-or | ||
| 173 | set-exclusive-or | ||
| 174 | nset-difference | ||
| 175 | set-difference | ||
| 176 | nintersection | ||
| 177 | intersection | ||
| 178 | nunion | ||
| 179 | union | ||
| 180 | rassoc-if-not | ||
| 181 | rassoc-if | ||
| 182 | assoc-if-not | ||
| 183 | assoc-if | ||
| 184 | member-if-not | ||
| 185 | member-if | ||
| 186 | merge | ||
| 187 | stable-sort | ||
| 188 | search | ||
| 189 | mismatch | ||
| 190 | count-if-not | ||
| 191 | count-if | ||
| 192 | count | ||
| 193 | position-if-not | ||
| 194 | position-if | ||
| 195 | position | ||
| 196 | find-if-not | ||
| 197 | find-if | ||
| 198 | find | ||
| 199 | nsubstitute-if-not | ||
| 200 | nsubstitute-if | ||
| 201 | nsubstitute | ||
| 202 | substitute-if-not | ||
| 203 | substitute-if | ||
| 204 | substitute | ||
| 205 | delete-duplicates | ||
| 206 | remove-duplicates | ||
| 207 | delete-if-not | ||
| 208 | delete-if | ||
| 209 | remove-if-not | ||
| 210 | remove-if | ||
| 211 | replace | ||
| 212 | fill | ||
| 213 | reduce | ||
| 214 | compiler-macroexpand | ||
| 215 | define-compiler-macro | ||
| 216 | assert | ||
| 217 | check-type | ||
| 218 | typep | ||
| 219 | deftype | ||
| 220 | defstruct | ||
| 221 | callf2 | ||
| 222 | callf | ||
| 223 | letf* | ||
| 224 | letf | ||
| 225 | rotatef | ||
| 226 | shiftf | ||
| 227 | remf | ||
| 228 | psetf | ||
| 229 | (define-setf-method . define-setf-expander) | ||
| 230 | the | ||
| 231 | locally | ||
| 232 | multiple-value-setq | ||
| 233 | multiple-value-bind | ||
| 234 | symbol-macrolet | ||
| 235 | macrolet | ||
| 236 | progv | ||
| 237 | psetq | ||
| 238 | do-all-symbols | ||
| 239 | do-symbols | ||
| 240 | do* | ||
| 241 | do | ||
| 242 | loop | ||
| 243 | return-from | ||
| 244 | return | ||
| 245 | block | ||
| 246 | etypecase | ||
| 247 | typecase | ||
| 248 | ecase | ||
| 249 | case | ||
| 250 | load-time-value | ||
| 251 | eval-when | ||
| 252 | destructuring-bind | ||
| 253 | gentemp | ||
| 254 | pairlis | ||
| 255 | acons | ||
| 256 | subst | ||
| 257 | adjoin | ||
| 258 | copy-list | ||
| 259 | ldiff | ||
| 260 | list* | ||
| 261 | tenth | ||
| 262 | ninth | ||
| 263 | eighth | ||
| 264 | seventh | ||
| 265 | sixth | ||
| 266 | fifth | ||
| 267 | fourth | ||
| 268 | third | ||
| 269 | endp | ||
| 270 | rest | ||
| 271 | second | ||
| 272 | first | ||
| 273 | svref | ||
| 274 | copy-seq | ||
| 275 | evenp | ||
| 276 | oddp | ||
| 277 | minusp | ||
| 278 | plusp | ||
| 279 | floatp-safe | ||
| 280 | declaim | ||
| 281 | proclaim | ||
| 282 | nth-value | ||
| 283 | multiple-value-call | ||
| 284 | multiple-value-apply | ||
| 285 | multiple-value-list | ||
| 286 | values-list | ||
| 287 | values | ||
| 288 | pushnew | ||
| 289 | decf | ||
| 290 | incf | ||
| 291 | )) | ||
| 292 | (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun))) | ||
| 293 | (intern (format "cl-%s" fun))))) | ||
| 294 | (defalias fun new))) | ||
| 295 | |||
| 296 | (defun cl--wrap-in-nil-block (fun &rest args) | ||
| 297 | `(cl-block nil ,(apply fun args))) | ||
| 298 | (advice-add 'dolist :around #'cl--wrap-in-nil-block) | ||
| 299 | (advice-add 'dotimes :around #'cl--wrap-in-nil-block) | ||
| 300 | |||
| 301 | (defun cl--pass-args-to-cl-declare (&rest specs) | ||
| 302 | (macroexpand `(cl-declare ,@specs))) | ||
| 303 | (advice-add 'declare :after #'cl--pass-args-to-cl-declare) | ||
| 304 | |||
| 305 | ;;; Features provided a bit differently in Elisp. | ||
| 306 | |||
| 307 | ;; First, the old lexical-let is now better served by `lexical-binding', tho | ||
| 308 | ;; it's not 100% compatible. | ||
| 309 | |||
| 310 | (defvar cl-closure-vars nil) | ||
| 311 | (defvar cl--function-convert-cache nil) | ||
| 312 | |||
| 313 | (defun cl--function-convert (f) | ||
| 314 | "Special macro-expander for special cases of (function F). | ||
| 315 | The two cases that are handled are: | ||
| 316 | - closure-conversion of lambda expressions for `lexical-let'. | ||
| 317 | - renaming of F when it's a function defined via `cl-labels' or `labels'." | ||
| 318 | (require 'cl-macs) | ||
| 319 | (declare-function cl--expr-contains-any "cl-macs" (x y)) | ||
| 320 | (declare-function cl--labels-convert "cl-macs" (f)) | ||
| 321 | (defvar cl--labels-convert-cache) | ||
| 322 | (cond | ||
| 323 | ;; ¡¡Big Ugly Hack!! We can't use a compiler-macro because those are checked | ||
| 324 | ;; *after* handling `function', but we want to stop macroexpansion from | ||
| 325 | ;; being applied infinitely, so we use a cache to return the exact `form' | ||
| 326 | ;; being expanded even though we don't receive it. | ||
| 327 | ((eq f (car cl--function-convert-cache)) (cdr cl--function-convert-cache)) | ||
| 328 | ((eq (car-safe f) 'lambda) | ||
| 329 | (let ((body (mapcar (lambda (f) | ||
| 330 | (macroexpand-all f macroexpand-all-environment)) | ||
| 331 | (cddr f)))) | ||
| 332 | (if (and cl-closure-vars | ||
| 333 | (cl--expr-contains-any body cl-closure-vars)) | ||
| 334 | (let* ((new (mapcar 'cl-gensym cl-closure-vars)) | ||
| 335 | (sub (cl-pairlis cl-closure-vars new)) (decls nil)) | ||
| 336 | (while (or (stringp (car body)) | ||
| 337 | (eq (car-safe (car body)) 'interactive)) | ||
| 338 | (push (list 'quote (pop body)) decls)) | ||
| 339 | (put (car (last cl-closure-vars)) 'used t) | ||
| 340 | `(list 'lambda '(&rest --cl-rest--) | ||
| 341 | ,@(cl-sublis sub (nreverse decls)) | ||
| 342 | (list 'apply | ||
| 343 | (list 'function | ||
| 344 | #'(lambda ,(append new (cadr f)) | ||
| 345 | ,@(cl-sublis sub body))) | ||
| 346 | ,@(nconc (mapcar (lambda (x) `(list 'quote ,x)) | ||
| 347 | cl-closure-vars) | ||
| 348 | '((quote --cl-rest--)))))) | ||
| 349 | (let* ((newf `(lambda ,(cadr f) ,@body)) | ||
| 350 | (res `(function ,newf))) | ||
| 351 | (setq cl--function-convert-cache (cons newf res)) | ||
| 352 | res)))) | ||
| 353 | (t | ||
| 354 | (cl--labels-convert f)))) | ||
| 355 | |||
| 356 | (defmacro lexical-let (bindings &rest body) | ||
| 357 | "Like `let', but lexically scoped. | ||
| 358 | The main visible difference is that lambdas inside BODY will create | ||
| 359 | lexical closures as in Common Lisp. | ||
| 360 | \n(fn BINDINGS BODY)" | ||
| 361 | (declare (indent 1) (debug let)) | ||
| 362 | (let* ((cl-closure-vars cl-closure-vars) | ||
| 363 | (vars (mapcar (function | ||
| 364 | (lambda (x) | ||
| 365 | (or (consp x) (setq x (list x))) | ||
| 366 | (push (make-symbol (format "--cl-%s--" (car x))) | ||
| 367 | cl-closure-vars) | ||
| 368 | (set (car cl-closure-vars) [bad-lexical-ref]) | ||
| 369 | (list (car x) (cadr x) (car cl-closure-vars)))) | ||
| 370 | bindings)) | ||
| 371 | (ebody | ||
| 372 | (macroexpand-all | ||
| 373 | `(cl-symbol-macrolet | ||
| 374 | ,(mapcar (lambda (x) | ||
| 375 | `(,(car x) (symbol-value ,(nth 2 x)))) | ||
| 376 | vars) | ||
| 377 | ,@body) | ||
| 378 | (cons (cons 'function #'cl--function-convert) | ||
| 379 | macroexpand-all-environment)))) | ||
| 380 | (if (not (get (car (last cl-closure-vars)) 'used)) | ||
| 381 | ;; Turn (let ((foo (cl-gensym))) | ||
| 382 | ;; (set foo <val>) ...(symbol-value foo)...) | ||
| 383 | ;; into (let ((foo <val>)) ...(symbol-value 'foo)...). | ||
| 384 | ;; This is good because it's more efficient but it only works with | ||
| 385 | ;; dynamic scoping, since with lexical scoping we'd need | ||
| 386 | ;; (let ((foo <val>)) ...foo...). | ||
| 387 | `(progn | ||
| 388 | ,@(mapcar (lambda (x) `(defvar ,(nth 2 x))) vars) | ||
| 389 | (let ,(mapcar (lambda (x) (list (nth 2 x) (nth 1 x))) vars) | ||
| 390 | ,(cl-sublis (mapcar (lambda (x) | ||
| 391 | (cons (nth 2 x) | ||
| 392 | `',(nth 2 x))) | ||
| 393 | vars) | ||
| 394 | ebody))) | ||
| 395 | `(let ,(mapcar (lambda (x) | ||
| 396 | (list (nth 2 x) | ||
| 397 | `(make-symbol ,(format "--%s--" (car x))))) | ||
| 398 | vars) | ||
| 399 | (setf ,@(apply #'append | ||
| 400 | (mapcar (lambda (x) | ||
| 401 | (list `(symbol-value ,(nth 2 x)) (nth 1 x))) | ||
| 402 | vars))) | ||
| 403 | ,ebody)))) | ||
| 404 | |||
| 405 | (defmacro lexical-let* (bindings &rest body) | ||
| 406 | "Like `let*', but lexically scoped. | ||
| 407 | The main visible difference is that lambdas inside BODY, and in | ||
| 408 | successive bindings within BINDINGS, will create lexical closures | ||
| 409 | as in Common Lisp. This is similar to the behavior of `let*' in | ||
| 410 | Common Lisp. | ||
| 411 | \n(fn BINDINGS BODY)" | ||
| 412 | (declare (indent 1) (debug let)) | ||
| 413 | (if (null bindings) (cons 'progn body) | ||
| 414 | (setq bindings (reverse bindings)) | ||
| 415 | (while bindings | ||
| 416 | (setq body (list `(lexical-let (,(pop bindings)) ,@body)))) | ||
| 417 | (car body))) | ||
| 418 | |||
| 419 | ;; This should really have some way to shadow 'byte-compile properties, etc. | ||
| 420 | (defmacro flet (bindings &rest body) | ||
| 421 | "Make temporary overriding function definitions. | ||
| 422 | This is an analogue of a dynamically scoped `let' that operates on the function | ||
| 423 | cell of FUNCs rather than their value cell. | ||
| 424 | If you want the Common-Lisp style of `flet', you should use `cl-flet'. | ||
| 425 | The FORMs are evaluated with the specified function definitions in place, | ||
| 426 | then the definitions are undone (the FUNCs go back to their previous | ||
| 427 | definitions, or lack thereof). | ||
| 428 | |||
| 429 | \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" | ||
| 430 | (declare (indent 1) (debug cl-flet) | ||
| 431 | (obsolete "use either `cl-flet' or `cl-letf'." "24.3")) | ||
| 432 | `(letf ,(mapcar | ||
| 433 | (lambda (x) | ||
| 434 | (if (or (and (fboundp (car x)) | ||
| 435 | (eq (car-safe (symbol-function (car x))) 'macro)) | ||
| 436 | (cdr (assq (car x) macroexpand-all-environment))) | ||
| 437 | (error "Use `labels', not `flet', to rebind macro names")) | ||
| 438 | (let ((func `(cl-function | ||
| 439 | (lambda ,(cadr x) | ||
| 440 | (cl-block ,(car x) ,@(cddr x)))))) | ||
| 441 | (when (cl--compiling-file) | ||
| 442 | ;; Bug#411. It would be nice to fix this. | ||
| 443 | (and (get (car x) 'byte-compile) | ||
| 444 | (error "Byte-compiling a redefinition of `%s' \ | ||
| 445 | will not work - use `labels' instead" (symbol-name (car x)))) | ||
| 446 | ;; FIXME This affects the rest of the file, when it | ||
| 447 | ;; should be restricted to the flet body. | ||
| 448 | (and (boundp 'byte-compile-function-environment) | ||
| 449 | (push (cons (car x) (eval func)) | ||
| 450 | byte-compile-function-environment))) | ||
| 451 | (list `(symbol-function ',(car x)) func))) | ||
| 452 | bindings) | ||
| 453 | ,@body)) | ||
| 454 | |||
| 455 | (defmacro labels (bindings &rest body) | ||
| 456 | "Make temporary function bindings. | ||
| 457 | Like `cl-labels' except that the lexical scoping is handled via `lexical-let' | ||
| 458 | rather than relying on `lexical-binding'." | ||
| 459 | (declare (indent 1) (debug cl-flet) (obsolete cl-labels "24.3")) | ||
| 460 | (let ((vars nil) (sets nil) (newenv macroexpand-all-environment)) | ||
| 461 | (dolist (binding bindings) | ||
| 462 | ;; It's important that (not (eq (symbol-name var1) (symbol-name var2))) | ||
| 463 | ;; because these var's *names* get added to the macro-environment. | ||
| 464 | (let ((var (make-symbol (format "--cl-%s--" (car binding))))) | ||
| 465 | (push var vars) | ||
| 466 | (push `(cl-function (lambda . ,(cdr binding))) sets) | ||
| 467 | (push var sets) | ||
| 468 | (push (cons (car binding) | ||
| 469 | `(lambda (&rest cl-labels-args) | ||
| 470 | (if (eq (car cl-labels-args) cl--labels-magic) | ||
| 471 | (list cl--labels-magic ',var) | ||
| 472 | (cl-list* 'funcall ',var cl-labels-args)))) | ||
| 473 | newenv))) | ||
| 474 | ;; `lexical-let' adds `cl--function-convert' (which calls | ||
| 475 | ;; `cl--labels-convert') as a macroexpander for `function'. | ||
| 476 | (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv))) | ||
| 477 | |||
| 478 | ;; Generalized variables are provided by gv.el, but some details are | ||
| 479 | ;; not 100% compatible: not worth the trouble to add them to cl-lib.el, but we | ||
| 480 | ;; still need to support old users of cl.el. | ||
| 481 | |||
| 482 | (defun cl--gv-adapt (cl-gv do) | ||
| 483 | ;; This function is used by all .elc files that use define-setf-expander and | ||
| 484 | ;; were compiled with Emacs>=24.3. | ||
| 485 | (let ((vars (nth 0 cl-gv)) | ||
| 486 | (vals (nth 1 cl-gv)) | ||
| 487 | (binds ()) | ||
| 488 | (substs ())) | ||
| 489 | ;; Use cl-sublis as was done in cl-setf-do-modify. | ||
| 490 | (while vars | ||
| 491 | (if (macroexp-copyable-p (car vals)) | ||
| 492 | (push (cons (pop vars) (pop vals)) substs) | ||
| 493 | (push (list (pop vars) (pop vals)) binds))) | ||
| 494 | (macroexp-let* | ||
| 495 | binds | ||
| 496 | (funcall do (cl-sublis substs (nth 4 cl-gv)) | ||
| 497 | ;; We'd like to do something like | ||
| 498 | ;; (lambda ,(nth 2 cl-gv) ,(nth 3 cl-gv)). | ||
| 499 | (lambda (exp) | ||
| 500 | (macroexp-let2 macroexp-copyable-p v exp | ||
| 501 | (cl-sublis (cons (cons (car (nth 2 cl-gv)) v) | ||
| 502 | substs) | ||
| 503 | (nth 3 cl-gv)))))))) | ||
| 504 | |||
| 505 | (defmacro define-setf-expander (name arglist &rest body) | ||
| 506 | "Define a `setf' method. | ||
| 507 | This method shows how to handle `setf's to places of the form | ||
| 508 | \(NAME ARGS...). The argument forms ARGS are bound according to | ||
| 509 | ARGLIST, as if NAME were going to be expanded as a macro, then | ||
| 510 | the BODY forms are executed and must return a list of five elements: | ||
| 511 | a temporary-variables list, a value-forms list, a store-variables list | ||
| 512 | \(of length one), a store-form, and an access- form. | ||
| 513 | |||
| 514 | See `gv-define-expander', and `gv-define-setter' for better and | ||
| 515 | simpler ways to define setf-methods." | ||
| 516 | (declare (debug | ||
| 517 | (&define name cl-lambda-list cl-declarations-or-string def-body))) | ||
| 518 | `(progn | ||
| 519 | ,@(if (stringp (car body)) | ||
| 520 | (list `(put ',name 'setf-documentation ,(pop body)))) | ||
| 521 | (gv-define-expander ,name | ||
| 522 | (cl-function | ||
| 523 | (lambda (do ,@arglist) | ||
| 524 | (cl--gv-adapt (progn ,@body) do)))))) | ||
| 525 | |||
| 526 | (defmacro defsetf (name arg1 &rest args) | ||
| 527 | "Define a `setf' method. | ||
| 528 | This macro is an easy-to-use substitute for `define-setf-expander' | ||
| 529 | that works well for simple place forms. | ||
| 530 | |||
| 531 | In the simple `defsetf' form, `setf's of the form (setf (NAME | ||
| 532 | ARGS...) VAL) are transformed to function or macro calls of the | ||
| 533 | form (FUNC ARGS... VAL). For example: | ||
| 534 | |||
| 535 | (defsetf aref aset) | ||
| 536 | |||
| 537 | You can replace this form with `gv-define-simple-setter'. | ||
| 538 | |||
| 539 | Alternate form: (defsetf NAME ARGLIST (STORE) BODY...). | ||
| 540 | |||
| 541 | Here, the above `setf' call is expanded by binding the argument | ||
| 542 | forms ARGS according to ARGLIST, binding the value form VAL to | ||
| 543 | STORE, then executing BODY, which must return a Lisp form that | ||
| 544 | does the necessary `setf' operation. Actually, ARGLIST and STORE | ||
| 545 | may be bound to temporary variables which are introduced | ||
| 546 | automatically to preserve proper execution order of the arguments. | ||
| 547 | For example: | ||
| 548 | |||
| 549 | (defsetf nth (n x) (v) \\=`(setcar (nthcdr ,n ,x) ,v)) | ||
| 550 | |||
| 551 | You can replace this form with `gv-define-setter'. | ||
| 552 | |||
| 553 | \(fn NAME [FUNC | ARGLIST (STORE) BODY...])" | ||
| 554 | (declare (debug | ||
| 555 | (&define name | ||
| 556 | [&or [symbolp &optional stringp] | ||
| 557 | [cl-lambda-list (symbolp)]] | ||
| 558 | cl-declarations-or-string def-body))) | ||
| 559 | (if (and (listp arg1) (consp args)) | ||
| 560 | ;; Like `gv-define-setter' but with `cl-function'. | ||
| 561 | `(gv-define-expander ,name | ||
| 562 | (lambda (do &rest args) | ||
| 563 | (gv--defsetter ',name | ||
| 564 | (cl-function | ||
| 565 | (lambda (,@(car args) ,@arg1) ,@(cdr args))) | ||
| 566 | do args))) | ||
| 567 | `(gv-define-simple-setter ,name ,arg1 ,(car args)))) | ||
| 568 | |||
| 569 | ;; FIXME: CL used to provide a setf method for `apply', but I haven't been able | ||
| 570 | ;; to find a case where it worked. The code below tries to handle it as well. | ||
| 571 | ;; (defun cl--setf-apply (form last-witness last) | ||
| 572 | ;; (cond | ||
| 573 | ;; ((not (consp form)) form) | ||
| 574 | ;; ((eq (ignore-errors (car (last form))) last-witness) | ||
| 575 | ;; `(apply #',(car form) ,@(butlast (cdr form)) ,last)) | ||
| 576 | ;; ((and (memq (car form) '(let let*)) | ||
| 577 | ;; (rassoc (list last-witness) (cadr form))) | ||
| 578 | ;; (let ((rebind (rassoc (list last-witness) (cadr form)))) | ||
| 579 | ;; `(,(car form) ,(remq rebind (cadr form)) | ||
| 580 | ;; ,@(mapcar (lambda (form) (cl--setf-apply form (car rebind) last)) | ||
| 581 | ;; (cddr form))))) | ||
| 582 | ;; (t (mapcar (lambda (form) (cl--setf-apply form last-witness last)) form)))) | ||
| 583 | ;; (gv-define-setter apply (val fun &rest args) | ||
| 584 | ;; (pcase fun (`#',(and (pred symbolp) f) (setq fun f)) | ||
| 585 | ;; (_ (error "First arg to apply in setf is not #'SYM: %S" fun))) | ||
| 586 | ;; (let* ((butlast (butlast args)) | ||
| 587 | ;; (last (car (last args))) | ||
| 588 | ;; (last-witness (make-symbol "--cl-tailarg--")) | ||
| 589 | ;; (setter (macroexpand `(setf (,fun ,@butlast ,last-witness) ,val) | ||
| 590 | ;; macroexpand-all-environment))) | ||
| 591 | ;; (cl--setf-apply setter last-witness last))) | ||
| 592 | |||
| 593 | |||
| 594 | ;; FIXME: CL used to provide get-setf-method, which was used by some | ||
| 595 | ;; setf-expanders, but now that we use gv.el, it is a lot more difficult | ||
| 596 | ;; and in general impossible to provide get-setf-method. Hopefully, it | ||
| 597 | ;; won't be needed. If needed, we'll have to do something nasty along the | ||
| 598 | ;; lines of | ||
| 599 | ;; (defun get-setf-method (place &optional env) | ||
| 600 | ;; (let* ((witness (list 'cl-gsm)) | ||
| 601 | ;; (expansion (gv-letplace (getter setter) place | ||
| 602 | ;; `(,witness ,getter ,(funcall setter witness))))) | ||
| 603 | ;; ...find "let prefix" of expansion, extract getter and setter from | ||
| 604 | ;; ...the rest, and build the 5-tuple)) | ||
| 605 | (make-obsolete 'get-setf-method 'gv-letplace "24.3") | ||
| 606 | |||
| 607 | (declare-function cl--arglist-args "cl-macs" (args)) | ||
| 608 | |||
| 609 | (defmacro define-modify-macro (name arglist func &optional doc) | ||
| 610 | "Define a `setf'-like modify macro. | ||
| 611 | If NAME is called, it combines its PLACE argument with the other | ||
| 612 | arguments from ARGLIST using FUNC. For example: | ||
| 613 | |||
| 614 | (define-modify-macro incf (&optional (n 1)) +) | ||
| 615 | |||
| 616 | You can replace this macro with `gv-letplace'." | ||
| 617 | (declare (debug | ||
| 618 | (&define name cl-lambda-list ;; should exclude &key | ||
| 619 | symbolp &optional stringp))) | ||
| 620 | (if (memq '&key arglist) | ||
| 621 | (error "&key not allowed in define-modify-macro")) | ||
| 622 | (require 'cl-macs) ;For cl--arglist-args. | ||
| 623 | (let ((place (make-symbol "--cl-place--"))) | ||
| 624 | `(cl-defmacro ,name (,place ,@arglist) | ||
| 625 | ,doc | ||
| 626 | (,(if (memq '&rest arglist) #'cl-list* #'list) | ||
| 627 | #'cl-callf ',func ,place | ||
| 628 | ,@(cl--arglist-args arglist))))) | ||
| 629 | |||
| 630 | ;;; Additional compatibility code. | ||
| 631 | ;; For names that were clean but really aren't needed any more. | ||
| 632 | |||
| 633 | (define-obsolete-function-alias 'cl-macroexpand 'macroexpand "24.3") | ||
| 634 | (define-obsolete-variable-alias 'cl-macro-environment | ||
| 635 | 'macroexpand-all-environment "24.3") | ||
| 636 | (define-obsolete-function-alias 'cl-macroexpand-all 'macroexpand-all "24.3") | ||
| 637 | |||
| 638 | ;;; Hash tables. | ||
| 639 | ;; This is just kept for compatibility with code byte-compiled by Emacs-20. | ||
| 640 | |||
| 641 | ;; No idea if this might still be needed. | ||
| 642 | (defun cl-not-hash-table (x &optional y &rest _z) | ||
| 643 | (declare (obsolete nil "24.3")) | ||
| 644 | (signal 'wrong-type-argument (list 'cl-hash-table-p (or y x)))) | ||
| 645 | |||
| 646 | (defvar cl-builtin-gethash (symbol-function 'gethash)) | ||
| 647 | (make-obsolete-variable 'cl-builtin-gethash nil "24.3") | ||
| 648 | (defvar cl-builtin-remhash (symbol-function 'remhash)) | ||
| 649 | (make-obsolete-variable 'cl-builtin-remhash nil "24.3") | ||
| 650 | (defvar cl-builtin-clrhash (symbol-function 'clrhash)) | ||
| 651 | (make-obsolete-variable 'cl-builtin-clrhash nil "24.3") | ||
| 652 | (defvar cl-builtin-maphash (symbol-function 'maphash)) | ||
| 653 | |||
| 654 | (make-obsolete-variable 'cl-builtin-maphash nil "24.3") | ||
| 655 | (define-obsolete-function-alias 'cl-map-keymap 'map-keymap "24.3") | ||
| 656 | (define-obsolete-function-alias 'cl-copy-tree 'copy-tree "24.3") | ||
| 657 | (define-obsolete-function-alias 'cl-gethash 'gethash "24.3") | ||
| 658 | (define-obsolete-function-alias 'cl-puthash 'puthash "24.3") | ||
| 659 | (define-obsolete-function-alias 'cl-remhash 'remhash "24.3") | ||
| 660 | (define-obsolete-function-alias 'cl-clrhash 'clrhash "24.3") | ||
| 661 | (define-obsolete-function-alias 'cl-maphash 'maphash "24.3") | ||
| 662 | (define-obsolete-function-alias 'cl-make-hash-table 'make-hash-table "24.3") | ||
| 663 | (define-obsolete-function-alias 'cl-hash-table-p 'hash-table-p "24.3") | ||
| 664 | (define-obsolete-function-alias 'cl-hash-table-count 'hash-table-count "24.3") | ||
| 665 | |||
| 666 | (define-obsolete-function-alias 'cl-map-keymap-recursively | ||
| 667 | 'cl--map-keymap-recursively "24.3") | ||
| 668 | (define-obsolete-function-alias 'cl-map-intervals 'cl--map-intervals "24.3") | ||
| 669 | (define-obsolete-function-alias 'cl-map-extents 'cl--map-overlays "24.3") | ||
| 670 | (define-obsolete-function-alias 'cl-set-getf 'cl--set-getf "24.3") | ||
| 671 | |||
| 672 | (defun cl-maclisp-member (item list) | ||
| 673 | (declare (obsolete member "24.3")) | ||
| 674 | (while (and list (not (equal item (car list)))) (setq list (cdr list))) | ||
| 675 | list) | ||
| 676 | |||
| 677 | ;; Used in the expansion of the old `defstruct'. | ||
| 678 | (defun cl-struct-setf-expander (x name accessor pred-form pos) | ||
| 679 | (declare (obsolete nil "24.3")) | ||
| 680 | (let* ((temp (make-symbol "--cl-x--")) (store (make-symbol "--cl-store--"))) | ||
| 681 | (list (list temp) (list x) (list store) | ||
| 682 | `(progn | ||
| 683 | ,@(and pred-form | ||
| 684 | (list `(or ,(cl-subst temp 'cl-x pred-form) | ||
| 685 | (error ,(format | ||
| 686 | "%s storing a non-%s" | ||
| 687 | accessor name))))) | ||
| 688 | ,(if (eq (car (get name 'cl-struct-type)) 'vector) | ||
| 689 | `(aset ,temp ,pos ,store) | ||
| 690 | `(setcar | ||
| 691 | ,(if (<= pos 5) | ||
| 692 | (let ((xx temp)) | ||
| 693 | (while (>= (setq pos (1- pos)) 0) | ||
| 694 | (setq xx `(cdr ,xx))) | ||
| 695 | xx) | ||
| 696 | `(nthcdr ,pos ,temp)) | ||
| 697 | ,store))) | ||
| 698 | (list accessor temp)))) | ||
| 699 | |||
| 700 | (provide 'cl) | ||
| 701 | |||
| 702 | (run-hooks 'cl-load-hook) | ||
| 703 | |||
| 704 | ;;; cl.el ends here | ||