diff options
| author | Stefan Monnier | 2013-09-27 21:07:18 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-09-27 21:07:18 -0400 |
| commit | 3b7b2692562700da696fcae01875017c6361d5e4 (patch) | |
| tree | bce94f0fc07a711fbde26e1118e934b48018937b | |
| parent | 529fb53f7ef1f8f6dbc97b8c41efbc542a9bef3b (diff) | |
| download | emacs-3b7b2692562700da696fcae01875017c6361d5e4.tar.gz emacs-3b7b2692562700da696fcae01875017c6361d5e4.zip | |
* lisp/emacs-lisp/cl-macs.el:
(cl--loop-destr-temps): Remove.
(cl--loop-iterator-function): Rename from cl--loop-map-form and change
its convention.
(cl--loop-set-iterator-function): New function.
(cl-loop): Adjust accordingly, so as not to use cl-subst.
(cl--parse-loop-clause): Adjust all uses of cl--loop-map-form.
Bind `it' with `let' instead of substituting it with `cl-subst'.
(cl--unused-var-p): New function.
(cl--loop-let): Don't use the cl--loop-destr-temps hack any more.
Eliminate some unused variable warnings.
Fixes: debbugs:15326
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 183 |
2 files changed, 129 insertions, 68 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 21bcfc0d9fb..7e1561b03fd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2013-09-28 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/cl-macs.el: | ||
| 4 | (cl--loop-destr-temps): Remove. | ||
| 5 | (cl--loop-iterator-function): Rename from cl--loop-map-form and change | ||
| 6 | its convention. | ||
| 7 | (cl--loop-set-iterator-function): New function. | ||
| 8 | (cl-loop): Adjust accordingly, so as not to use cl-subst. | ||
| 9 | (cl--parse-loop-clause): Adjust all uses of cl--loop-map-form. | ||
| 10 | Bind `it' with `let' instead of substituting it with `cl-subst'. | ||
| 11 | (cl--unused-var-p): New function. | ||
| 12 | (cl--loop-let): Don't use the cl--loop-destr-temps hack any more. | ||
| 13 | Eliminate some unused variable warnings (bug#15326). | ||
| 14 | |||
| 1 | 2013-09-27 Tassilo Horn <tsdh@gnu.org> | 15 | 2013-09-27 Tassilo Horn <tsdh@gnu.org> |
| 2 | 16 | ||
| 3 | * doc-view.el (doc-view-scale-reset): Rename from | 17 | * doc-view.el (doc-view-scale-reset): Rename from |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 031bf5553d0..60fdc09c053 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -756,14 +756,22 @@ This is compatible with Common Lisp, but note that `defun' and | |||
| 756 | ;;; The "cl-loop" macro. | 756 | ;;; The "cl-loop" macro. |
| 757 | 757 | ||
| 758 | (defvar cl--loop-args) (defvar cl--loop-accum-var) (defvar cl--loop-accum-vars) | 758 | (defvar cl--loop-args) (defvar cl--loop-accum-var) (defvar cl--loop-accum-vars) |
| 759 | (defvar cl--loop-bindings) (defvar cl--loop-body) (defvar cl--loop-destr-temps) | 759 | (defvar cl--loop-bindings) (defvar cl--loop-body) |
| 760 | (defvar cl--loop-finally) (defvar cl--loop-finish-flag) | 760 | (defvar cl--loop-finally) |
| 761 | (defvar cl--loop-finish-flag) ;Symbol set to nil to exit the loop? | ||
| 761 | (defvar cl--loop-first-flag) | 762 | (defvar cl--loop-first-flag) |
| 762 | (defvar cl--loop-initially) (defvar cl--loop-map-form) (defvar cl--loop-name) | 763 | (defvar cl--loop-initially) (defvar cl--loop-iterator-function) |
| 764 | (defvar cl--loop-name) | ||
| 763 | (defvar cl--loop-result) (defvar cl--loop-result-explicit) | 765 | (defvar cl--loop-result) (defvar cl--loop-result-explicit) |
| 764 | (defvar cl--loop-result-var) (defvar cl--loop-steps) | 766 | (defvar cl--loop-result-var) (defvar cl--loop-steps) |
| 765 | (defvar cl--loop-symbol-macs) | 767 | (defvar cl--loop-symbol-macs) |
| 766 | 768 | ||
| 769 | (defun cl--loop-set-iterator-function (kind iterator) | ||
| 770 | (if cl--loop-iterator-function | ||
| 771 | ;; FIXME: Of course, we could make it work, but why bother. | ||
| 772 | (error "Iteration on %S does not support this combination" kind) | ||
| 773 | (setq cl--loop-iterator-function iterator))) | ||
| 774 | |||
| 767 | ;;;###autoload | 775 | ;;;###autoload |
| 768 | (defmacro cl-loop (&rest loop-args) | 776 | (defmacro cl-loop (&rest loop-args) |
| 769 | "The Common Lisp `loop' macro. | 777 | "The Common Lisp `loop' macro. |
| @@ -817,13 +825,35 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 817 | (delq nil (delq t (cl-copy-list loop-args)))))) | 825 | (delq nil (delq t (cl-copy-list loop-args)))))) |
| 818 | `(cl-block nil (while t ,@loop-args)) | 826 | `(cl-block nil (while t ,@loop-args)) |
| 819 | (let ((cl--loop-args loop-args) (cl--loop-name nil) (cl--loop-bindings nil) | 827 | (let ((cl--loop-args loop-args) (cl--loop-name nil) (cl--loop-bindings nil) |
| 820 | (cl--loop-body nil) (cl--loop-steps nil) | 828 | (cl--loop-body nil) (cl--loop-steps nil) |
| 821 | (cl--loop-result nil) (cl--loop-result-explicit nil) | 829 | (cl--loop-result nil) (cl--loop-result-explicit nil) |
| 822 | (cl--loop-result-var nil) (cl--loop-finish-flag nil) | 830 | (cl--loop-result-var nil) (cl--loop-finish-flag nil) |
| 823 | (cl--loop-accum-var nil) (cl--loop-accum-vars nil) | 831 | (cl--loop-accum-var nil) (cl--loop-accum-vars nil) |
| 824 | (cl--loop-initially nil) (cl--loop-finally nil) | 832 | (cl--loop-initially nil) (cl--loop-finally nil) |
| 825 | (cl--loop-map-form nil) (cl--loop-first-flag nil) | 833 | (cl--loop-iterator-function nil) (cl--loop-first-flag nil) |
| 826 | (cl--loop-destr-temps nil) (cl--loop-symbol-macs nil)) | 834 | (cl--loop-symbol-macs nil)) |
| 835 | ;; Here is more or less how those dynbind vars are used after looping | ||
| 836 | ;; over cl--parse-loop-clause: | ||
| 837 | ;; | ||
| 838 | ;; (cl-block ,cl--loop-name | ||
| 839 | ;; (cl-symbol-macrolet ,cl--loop-symbol-macs | ||
| 840 | ;; (foldl #'cl--loop-let | ||
| 841 | ;; `((,cl--loop-result-var) | ||
| 842 | ;; ((,cl--loop-first-flag t)) | ||
| 843 | ;; ((,cl--loop-finish-flag t)) | ||
| 844 | ;; ,@cl--loop-bindings) | ||
| 845 | ;; ,@(nreverse cl--loop-initially) | ||
| 846 | ;; (while ;(well: cl--loop-iterator-function) | ||
| 847 | ;; ,(car (cl--loop-build-ands (nreverse cl--loop-body))) | ||
| 848 | ;; ,@(cadr (cl--loop-build-ands (nreverse cl--loop-body))) | ||
| 849 | ;; ,@(nreverse cl--loop-steps) | ||
| 850 | ;; (setq ,cl--loop-first-flag nil)) | ||
| 851 | ;; (if (not ,cl--loop-finish-flag) ;FIXME: Why `if' vs `progn'? | ||
| 852 | ;; ,cl--loop-result-var | ||
| 853 | ;; ,@(nreverse cl--loop-finally) | ||
| 854 | ;; ,(or cl--loop-result-explicit | ||
| 855 | ;; cl--loop-result))))) | ||
| 856 | ;; | ||
| 827 | (setq cl--loop-args (append cl--loop-args '(cl-end-loop))) | 857 | (setq cl--loop-args (append cl--loop-args '(cl-end-loop))) |
| 828 | (while (not (eq (car cl--loop-args) 'cl-end-loop)) | 858 | (while (not (eq (car cl--loop-args) 'cl-end-loop)) |
| 829 | (cl--parse-loop-clause)) | 859 | (cl--parse-loop-clause)) |
| @@ -839,15 +869,15 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 839 | (while-body (nconc (cadr ands) (nreverse cl--loop-steps))) | 869 | (while-body (nconc (cadr ands) (nreverse cl--loop-steps))) |
| 840 | (body (append | 870 | (body (append |
| 841 | (nreverse cl--loop-initially) | 871 | (nreverse cl--loop-initially) |
| 842 | (list (if cl--loop-map-form | 872 | (list (if cl--loop-iterator-function |
| 843 | `(cl-block --cl-finish-- | 873 | `(cl-block --cl-finish-- |
| 844 | ,(cl-subst | 874 | ,(funcall cl--loop-iterator-function |
| 845 | (if (eq (car ands) t) while-body | 875 | (if (eq (car ands) t) while-body |
| 846 | (cons `(or ,(car ands) | 876 | (cons `(or ,(car ands) |
| 847 | (cl-return-from --cl-finish-- | 877 | (cl-return-from |
| 848 | nil)) | 878 | --cl-finish-- |
| 849 | while-body)) | 879 | nil)) |
| 850 | '--cl-map cl--loop-map-form)) | 880 | while-body)))) |
| 851 | `(while ,(car ands) ,@while-body))) | 881 | `(while ,(car ands) ,@while-body))) |
| 852 | (if cl--loop-finish-flag | 882 | (if cl--loop-finish-flag |
| 853 | (if (equal epilogue '(nil)) (list cl--loop-result-var) | 883 | (if (equal epilogue '(nil)) (list cl--loop-result-var) |
| @@ -1216,15 +1246,18 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1216 | (make-symbol "--cl-var--")))) | 1246 | (make-symbol "--cl-var--")))) |
| 1217 | (if (memq word '(hash-value hash-values)) | 1247 | (if (memq word '(hash-value hash-values)) |
| 1218 | (setq var (prog1 other (setq other var)))) | 1248 | (setq var (prog1 other (setq other var)))) |
| 1219 | (setq cl--loop-map-form | 1249 | (cl--loop-set-iterator-function |
| 1220 | `(maphash (lambda (,var ,other) . --cl-map) ,table)))) | 1250 | 'hash-tables (lambda (body) |
| 1251 | `(maphash (lambda (,var ,other) . ,body) | ||
| 1252 | ,table))))) | ||
| 1221 | 1253 | ||
| 1222 | ((memq word '(symbol present-symbol external-symbol | 1254 | ((memq word '(symbol present-symbol external-symbol |
| 1223 | symbols present-symbols external-symbols)) | 1255 | symbols present-symbols external-symbols)) |
| 1224 | (let ((ob (and (memq (car cl--loop-args) '(in of)) | 1256 | (let ((ob (and (memq (car cl--loop-args) '(in of)) |
| 1225 | (cl--pop2 cl--loop-args)))) | 1257 | (cl--pop2 cl--loop-args)))) |
| 1226 | (setq cl--loop-map-form | 1258 | (cl--loop-set-iterator-function |
| 1227 | `(mapatoms (lambda (,var) . --cl-map) ,ob)))) | 1259 | 'symbols (lambda (body) |
| 1260 | `(mapatoms (lambda (,var) . ,body) ,ob))))) | ||
| 1228 | 1261 | ||
| 1229 | ((memq word '(overlay overlays extent extents)) | 1262 | ((memq word '(overlay overlays extent extents)) |
| 1230 | (let ((buf nil) (from nil) (to nil)) | 1263 | (let ((buf nil) (from nil) (to nil)) |
| @@ -1234,11 +1267,12 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1234 | ((eq (car cl--loop-args) 'to) | 1267 | ((eq (car cl--loop-args) 'to) |
| 1235 | (setq to (cl--pop2 cl--loop-args))) | 1268 | (setq to (cl--pop2 cl--loop-args))) |
| 1236 | (t (setq buf (cl--pop2 cl--loop-args))))) | 1269 | (t (setq buf (cl--pop2 cl--loop-args))))) |
| 1237 | (setq cl--loop-map-form | 1270 | (cl--loop-set-iterator-function |
| 1238 | `(cl--map-overlays | 1271 | 'overlays (lambda (body) |
| 1239 | (lambda (,var ,(make-symbol "--cl-var--")) | 1272 | `(cl--map-overlays |
| 1240 | (progn . --cl-map) nil) | 1273 | (lambda (,var ,(make-symbol "--cl-var--")) |
| 1241 | ,buf ,from ,to)))) | 1274 | (progn . ,body) nil) |
| 1275 | ,buf ,from ,to))))) | ||
| 1242 | 1276 | ||
| 1243 | ((memq word '(interval intervals)) | 1277 | ((memq word '(interval intervals)) |
| 1244 | (let ((buf nil) (prop nil) (from nil) (to nil) | 1278 | (let ((buf nil) (prop nil) (from nil) (to nil) |
| @@ -1255,10 +1289,11 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1255 | (if (and (consp var) (symbolp (car var)) (symbolp (cdr var))) | 1289 | (if (and (consp var) (symbolp (car var)) (symbolp (cdr var))) |
| 1256 | (setq var1 (car var) var2 (cdr var)) | 1290 | (setq var1 (car var) var2 (cdr var)) |
| 1257 | (push (list var `(cons ,var1 ,var2)) loop-for-sets)) | 1291 | (push (list var `(cons ,var1 ,var2)) loop-for-sets)) |
| 1258 | (setq cl--loop-map-form | 1292 | (cl--loop-set-iterator-function |
| 1259 | `(cl--map-intervals | 1293 | 'intervals (lambda (body) |
| 1260 | (lambda (,var1 ,var2) . --cl-map) | 1294 | `(cl--map-intervals |
| 1261 | ,buf ,prop ,from ,to)))) | 1295 | (lambda (,var1 ,var2) . ,body) |
| 1296 | ,buf ,prop ,from ,to))))) | ||
| 1262 | 1297 | ||
| 1263 | ((memq word key-types) | 1298 | ((memq word key-types) |
| 1264 | (or (memq (car cl--loop-args) '(in of)) | 1299 | (or (memq (car cl--loop-args) '(in of)) |
| @@ -1274,10 +1309,11 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1274 | (make-symbol "--cl-var--")))) | 1309 | (make-symbol "--cl-var--")))) |
| 1275 | (if (memq word '(key-binding key-bindings)) | 1310 | (if (memq word '(key-binding key-bindings)) |
| 1276 | (setq var (prog1 other (setq other var)))) | 1311 | (setq var (prog1 other (setq other var)))) |
| 1277 | (setq cl--loop-map-form | 1312 | (cl--loop-set-iterator-function |
| 1278 | `(,(if (memq word '(key-seq key-seqs)) | 1313 | 'keys (lambda (body) |
| 1279 | 'cl--map-keymap-recursively 'map-keymap) | 1314 | `(,(if (memq word '(key-seq key-seqs)) |
| 1280 | (lambda (,var ,other) . --cl-map) ,cl-map)))) | 1315 | 'cl--map-keymap-recursively 'map-keymap) |
| 1316 | (lambda (,var ,other) . ,body) ,cl-map))))) | ||
| 1281 | 1317 | ||
| 1282 | ((memq word '(frame frames screen screens)) | 1318 | ((memq word '(frame frames screen screens)) |
| 1283 | (let ((temp (make-symbol "--cl-var--"))) | 1319 | (let ((temp (make-symbol "--cl-var--"))) |
| @@ -1448,12 +1484,9 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1448 | (if (eq word 'unless) (setq then (prog1 else (setq else then)))) | 1484 | (if (eq word 'unless) (setq then (prog1 else (setq else then)))) |
| 1449 | (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then)) | 1485 | (let ((form (cons (if simple (cons 'progn (nth 1 then)) (nth 2 then)) |
| 1450 | (if simple (nth 1 else) (list (nth 2 else)))))) | 1486 | (if simple (nth 1 else) (list (nth 2 else)))))) |
| 1451 | (if (cl--expr-contains form 'it) | 1487 | (setq form (if (cl--expr-contains form 'it) |
| 1452 | (let ((temp (make-symbol "--cl-var--"))) | 1488 | `(let ((it ,cond)) (if it ,@form)) |
| 1453 | (push (list temp) cl--loop-bindings) | 1489 | `(if ,cond ,@form))) |
| 1454 | (setq form `(if (setq ,temp ,cond) | ||
| 1455 | ,@(cl-subst temp 'it form)))) | ||
| 1456 | (setq form `(if ,cond ,@form))) | ||
| 1457 | (push (if simple `(progn ,form t) form) cl--loop-body)))) | 1490 | (push (if simple `(progn ,form t) form) cl--loop-body)))) |
| 1458 | 1491 | ||
| 1459 | ((memq word '(do doing)) | 1492 | ((memq word '(do doing)) |
| @@ -1478,36 +1511,50 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1478 | (if (eq (car cl--loop-args) 'and) | 1511 | (if (eq (car cl--loop-args) 'and) |
| 1479 | (progn (pop cl--loop-args) (cl--parse-loop-clause))))) | 1512 | (progn (pop cl--loop-args) (cl--parse-loop-clause))))) |
| 1480 | 1513 | ||
| 1481 | (defun cl--loop-let (specs body par) ; uses loop-* | 1514 | (defun cl--unused-var-p (sym) |
| 1482 | (let ((p specs) (temps nil) (new nil)) | 1515 | (or (null sym) (eq ?_ (aref (symbol-name sym) 0)))) |
| 1483 | (while (and p (or (symbolp (car-safe (car p))) (null (cl-cadar p)))) | 1516 | |
| 1484 | (setq p (cdr p))) | 1517 | (defun cl--loop-let (specs body par) ; modifies cl--loop-bindings |
| 1485 | (and par p | 1518 | "Build an expression equivalent to (let SPECS BODY). |
| 1486 | (progn | 1519 | SPECS can include bindings using `cl-loop's destructuring (not to be |
| 1487 | (setq par nil p specs) | 1520 | confused with the patterns of `cl-destructuring-bind'). |
| 1488 | (while p | 1521 | If PAR is nil, do the bindings step by step, like `let*'. |
| 1489 | (or (macroexp-const-p (cl-cadar p)) | 1522 | If BODY is `setq', then use SPECS for assignments rather than for bindings." |
| 1490 | (let ((temp (make-symbol "--cl-var--"))) | 1523 | (let ((temps nil) (new nil)) |
| 1491 | (push (list temp (cl-cadar p)) temps) | 1524 | (when par |
| 1492 | (setcar (cdar p) temp))) | 1525 | (let ((p specs)) |
| 1493 | (setq p (cdr p))))) | 1526 | (while (and p (or (symbolp (car-safe (car p))) (null (cl-cadar p)))) |
| 1527 | (setq p (cdr p))) | ||
| 1528 | (when p | ||
| 1529 | (setq par nil) | ||
| 1530 | (dolist (spec specs) | ||
| 1531 | (or (macroexp-const-p (cadr spec)) | ||
| 1532 | (let ((temp (make-symbol "--cl-var--"))) | ||
| 1533 | (push (list temp (cadr spec)) temps) | ||
| 1534 | (setcar (cdr spec) temp))))))) | ||
| 1494 | (while specs | 1535 | (while specs |
| 1495 | (if (and (consp (car specs)) (listp (caar specs))) | 1536 | (let* ((binding (pop specs)) |
| 1496 | (let* ((spec (caar specs)) (nspecs nil) | 1537 | (spec (car-safe binding))) |
| 1497 | (expr (cadr (pop specs))) | 1538 | (if (and (consp binding) (or (consp spec) (cl--unused-var-p spec))) |
| 1498 | (temp | 1539 | (let* ((nspecs nil) |
| 1499 | (cdr (or (assq spec cl--loop-destr-temps) | 1540 | (expr (car (cdr-safe binding))) |
| 1500 | (car (push (cons spec | 1541 | (temp (last spec 0))) |
| 1501 | (or (last spec 0) | 1542 | (if (and (cl--unused-var-p temp) (null expr)) |
| 1502 | (make-symbol "--cl-var--"))) | 1543 | nil ;; Don't bother declaring/setting `temp' since it won't |
| 1503 | cl--loop-destr-temps)))))) | 1544 | ;; be used when `expr' is nil, anyway. |
| 1504 | (push (list temp expr) new) | 1545 | (when (and (eq body 'setq) (cl--unused-var-p temp)) |
| 1505 | (while (consp spec) | 1546 | ;; Prefer a fresh uninterned symbol over "_to", to avoid |
| 1506 | (push (list (pop spec) | 1547 | ;; warnings that we set an unused variable. |
| 1507 | (and expr (list (if spec 'pop 'car) temp))) | 1548 | (setq temp (make-symbol "--cl-var--")) |
| 1508 | nspecs)) | 1549 | ;; Make sure this temp variable is locally declared. |
| 1509 | (setq specs (nconc (nreverse nspecs) specs))) | 1550 | (push (list (list temp)) cl--loop-bindings)) |
| 1510 | (push (pop specs) new))) | 1551 | (push (list temp expr) new)) |
| 1552 | (while (consp spec) | ||
| 1553 | (push (list (pop spec) | ||
| 1554 | (and expr (list (if spec 'pop 'car) temp))) | ||
| 1555 | nspecs)) | ||
| 1556 | (setq specs (nconc (nreverse nspecs) specs))) | ||
| 1557 | (push binding new)))) | ||
| 1511 | (if (eq body 'setq) | 1558 | (if (eq body 'setq) |
| 1512 | (let ((set (cons (if par 'cl-psetq 'setq) | 1559 | (let ((set (cons (if par 'cl-psetq 'setq) |
| 1513 | (apply 'nconc (nreverse new))))) | 1560 | (apply 'nconc (nreverse new))))) |