aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-09-27 21:07:18 -0400
committerStefan Monnier2013-09-27 21:07:18 -0400
commit3b7b2692562700da696fcae01875017c6361d5e4 (patch)
treebce94f0fc07a711fbde26e1118e934b48018937b
parent529fb53f7ef1f8f6dbc97b8c41efbc542a9bef3b (diff)
downloademacs-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/ChangeLog14
-rw-r--r--lisp/emacs-lisp/cl-macs.el183
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 @@
12013-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
12013-09-27 Tassilo Horn <tsdh@gnu.org> 152013-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 1519SPECS can include bindings using `cl-loop's destructuring (not to be
1487 (setq par nil p specs) 1520confused with the patterns of `cl-destructuring-bind').
1488 (while p 1521If PAR is nil, do the bindings step by step, like `let*'.
1489 (or (macroexp-const-p (cl-cadar p)) 1522If 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)))))