aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-12-06 22:56:57 -0500
committerStefan Monnier2012-12-06 22:56:57 -0500
commit4611a3cce757d835a812820e2a65bdc56441463a (patch)
treef4fdb4b9adb828aff1f60a18d8cb27affb5a6732
parentf24f2e22aab32f2ec9613bcce95d995052f78009 (diff)
downloademacs-4611a3cce757d835a812820e2a65bdc56441463a.tar.gz
emacs-4611a3cce757d835a812820e2a65bdc56441463a.zip
* lisp/emacs-lisp/cl-macs.el (cl-tagbody): New macro.
-rw-r--r--etc/NEWS1
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/emacs-lisp/cl-loaddefs.el21
-rw-r--r--lisp/emacs-lisp/cl-macs.el46
4 files changed, 68 insertions, 4 deletions
diff --git a/etc/NEWS b/etc/NEWS
index d65ec5d9806..39b04da387c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -29,6 +29,7 @@ so we will look at it and add it to the manual.
29 29
30* Changes in Specialized Modes and Packages in Emacs 24.4 30* Changes in Specialized Modes and Packages in Emacs 24.4
31 31
32** New macro cl-tagbody in cl-lib.
32** Calc 33** Calc
33 34
34*** Calc by default now uses the Gregorian calendar for all dates, and 35*** Calc by default now uses the Gregorian calendar for all dates, and
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c2649b77321..51d2ec6cbd1 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
12012-12-07 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/cl-macs.el (cl-tagbody): New macro.
4
12012-12-06 Stefan Monnier <monnier@iro.umontreal.ca> 52012-12-06 Stefan Monnier <monnier@iro.umontreal.ca>
2 6
3 Further cleanup of the "cl-" namespace. Fit CL in 80 columns. 7 Further cleanup of the "cl-" namespace. Fit CL in 80 columns.
diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el
index 73759857aca..f699ee7fb8e 100644
--- a/lisp/emacs-lisp/cl-loaddefs.el
+++ b/lisp/emacs-lisp/cl-loaddefs.el
@@ -262,12 +262,12 @@ including `cl-block' and `cl-eval-when'.
262;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally 262;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally
263;;;;;; cl-multiple-value-setq cl-multiple-value-bind cl-symbol-macrolet 263;;;;;; cl-multiple-value-setq cl-multiple-value-bind cl-symbol-macrolet
264;;;;;; cl-macrolet cl-labels cl-flet* cl-flet cl-progv cl-psetq 264;;;;;; cl-macrolet cl-labels cl-flet* cl-flet cl-progv cl-psetq
265;;;;;; cl-do-all-symbols cl-do-symbols cl-dotimes cl-dolist cl-do* 265;;;;;; cl-do-all-symbols cl-do-symbols cl-tagbody cl-dotimes cl-dolist
266;;;;;; cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase 266;;;;;; cl-do* cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase
267;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when 267;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when
268;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp 268;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp
269;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*) 269;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*)
270;;;;;; "cl-macs" "cl-macs.el" "5df0692d7c4bffb2cc353f802d94f796") 270;;;;;; "cl-macs" "cl-macs.el" "d3af72b1cff3398fa1480065fc2887a2")
271;;; Generated autoloads from cl-macs.el 271;;; Generated autoloads from cl-macs.el
272 272
273(autoload 'cl--compiler-macro-list* "cl-macs" "\ 273(autoload 'cl--compiler-macro-list* "cl-macs" "\
@@ -465,6 +465,19 @@ nil.
465 465
466(put 'cl-dotimes 'lisp-indent-function '1) 466(put 'cl-dotimes 'lisp-indent-function '1)
467 467
468(autoload 'cl-tagbody "cl-macs" "\
469Execute statements while providing for control transfers to labels.
470Each element of LABELS-OR-STMTS can be either a label (integer or symbol)
471or a `cons' cell, in which case it's taken to be a statement.
472This distinction is made before performing macroexpansion.
473Statements are executed in sequence left to right, discarding any return value,
474stopping only when reaching the end of LABELS-OR-STMTS.
475Any statement can transfer control at any time to the statements that follow
476one of the labels with the special form (go LABEL).
477Labels have lexical scope and dynamic extent.
478
479\(fn &rest LABELS-OR-STMTS)" nil t)
480
468(autoload 'cl-do-symbols "cl-macs" "\ 481(autoload 'cl-do-symbols "cl-macs" "\
469Loop over all symbols. 482Loop over all symbols.
470Evaluate BODY with VAR bound to each interned symbol, or to each symbol 483Evaluate BODY with VAR bound to each interned symbol, or to each symbol
@@ -759,7 +772,7 @@ surrounded by (cl-block NAME ...).
759;;;;;; cl-nsubstitute-if cl-nsubstitute cl-substitute-if-not cl-substitute-if 772;;;;;; cl-nsubstitute-if cl-nsubstitute cl-substitute-if-not cl-substitute-if
760;;;;;; cl-substitute cl-delete-duplicates cl-remove-duplicates cl-delete-if-not 773;;;;;; cl-substitute cl-delete-duplicates cl-remove-duplicates cl-delete-if-not
761;;;;;; cl-delete-if cl-delete cl-remove-if-not cl-remove-if cl-remove 774;;;;;; cl-delete-if cl-delete cl-remove-if-not cl-remove-if cl-remove
762;;;;;; cl-replace cl-fill cl-reduce) "cl-seq" "cl-seq.el" "697d04e7ae0a9b9c15eea705b359b1bb") 775;;;;;; cl-replace cl-fill cl-reduce) "cl-seq" "cl-seq.el" "4b8ddc5bea2fcc626526ce3644071568")
763;;; Generated autoloads from cl-seq.el 776;;; Generated autoloads from cl-seq.el
764 777
765(autoload 'cl-reduce "cl-seq" "\ 778(autoload 'cl-reduce "cl-seq" "\
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 829357cbbe0..39df7befcd2 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1611,6 +1611,52 @@ nil.
1611 (if (advice-member-p #'cl--wrap-in-nil-block 'dotimes) 1611 (if (advice-member-p #'cl--wrap-in-nil-block 'dotimes)
1612 loop `(cl-block nil ,loop)))) 1612 loop `(cl-block nil ,loop))))
1613 1613
1614(defvar cl--tagbody-alist nil)
1615
1616;;;###autoload
1617(defmacro cl-tagbody (&rest labels-or-stmts)
1618 "Execute statements while providing for control transfers to labels.
1619Each element of LABELS-OR-STMTS can be either a label (integer or symbol)
1620or a `cons' cell, in which case it's taken to be a statement.
1621This distinction is made before performing macroexpansion.
1622Statements are executed in sequence left to right, discarding any return value,
1623stopping only when reaching the end of LABELS-OR-STMTS.
1624Any statement can transfer control at any time to the statements that follow
1625one of the labels with the special form (go LABEL).
1626Labels have lexical scope and dynamic extent."
1627 (let ((blocks '())
1628 (first-label (if (consp (car labels-or-stmts))
1629 'cl--preamble (pop labels-or-stmts))))
1630 (let ((block (list first-label)))
1631 (dolist (label-or-stmt labels-or-stmts)
1632 (if (consp label-or-stmt) (push label-or-stmt block)
1633 ;; Add a "go to next block" to implement the fallthrough.
1634 (unless (eq 'go (car-safe (car-safe block)))
1635 (push `(go ,label-or-stmt) block))
1636 (push (nreverse block) blocks)
1637 (setq block (list label-or-stmt))))
1638 (unless (eq 'go (car-safe (car-safe block)))
1639 (push `(go cl--exit) block))
1640 (push (nreverse block) blocks))
1641 (let ((catch-tag (make-symbol "cl--tagbody-tag")))
1642 (push (cons 'cl--exit catch-tag) cl--tagbody-alist)
1643 (dolist (block blocks)
1644 (push (cons (car block) catch-tag) cl--tagbody-alist))
1645 (macroexpand-all
1646 `(let ((next-label ',first-label))
1647 (while
1648 (not (eq (setq next-label
1649 (catch ',catch-tag
1650 (cl-case next-label
1651 ,@blocks)))
1652 'cl--exit))))
1653 `((go . ,(lambda (label)
1654 (let ((catch-tag (cdr (assq label cl--tagbody-alist))))
1655 (unless catch-tag
1656 (error "Unknown cl-tagbody go label `%S'" label))
1657 `(throw ',catch-tag ',label))))
1658 ,@macroexpand-all-environment)))))
1659
1614;;;###autoload 1660;;;###autoload
1615(defmacro cl-do-symbols (spec &rest body) 1661(defmacro cl-do-symbols (spec &rest body)
1616 "Loop over all symbols. 1662 "Loop over all symbols.