diff options
| author | Stefan Monnier | 2012-12-06 22:56:57 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2012-12-06 22:56:57 -0500 |
| commit | 4611a3cce757d835a812820e2a65bdc56441463a (patch) | |
| tree | f4fdb4b9adb828aff1f60a18d8cb27affb5a6732 | |
| parent | f24f2e22aab32f2ec9613bcce95d995052f78009 (diff) | |
| download | emacs-4611a3cce757d835a812820e2a65bdc56441463a.tar.gz emacs-4611a3cce757d835a812820e2a65bdc56441463a.zip | |
* lisp/emacs-lisp/cl-macs.el (cl-tagbody): New macro.
| -rw-r--r-- | etc/NEWS | 1 | ||||
| -rw-r--r-- | lisp/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-loaddefs.el | 21 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 46 |
4 files changed, 68 insertions, 4 deletions
| @@ -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 @@ | |||
| 1 | 2012-12-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/cl-macs.el (cl-tagbody): New macro. | ||
| 4 | |||
| 1 | 2012-12-06 Stefan Monnier <monnier@iro.umontreal.ca> | 5 | 2012-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" "\ | ||
| 469 | Execute statements while providing for control transfers to labels. | ||
| 470 | Each element of LABELS-OR-STMTS can be either a label (integer or symbol) | ||
| 471 | or a `cons' cell, in which case it's taken to be a statement. | ||
| 472 | This distinction is made before performing macroexpansion. | ||
| 473 | Statements are executed in sequence left to right, discarding any return value, | ||
| 474 | stopping only when reaching the end of LABELS-OR-STMTS. | ||
| 475 | Any statement can transfer control at any time to the statements that follow | ||
| 476 | one of the labels with the special form (go LABEL). | ||
| 477 | Labels 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" "\ |
| 469 | Loop over all symbols. | 482 | Loop over all symbols. |
| 470 | Evaluate BODY with VAR bound to each interned symbol, or to each symbol | 483 | Evaluate 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. | ||
| 1619 | Each element of LABELS-OR-STMTS can be either a label (integer or symbol) | ||
| 1620 | or a `cons' cell, in which case it's taken to be a statement. | ||
| 1621 | This distinction is made before performing macroexpansion. | ||
| 1622 | Statements are executed in sequence left to right, discarding any return value, | ||
| 1623 | stopping only when reaching the end of LABELS-OR-STMTS. | ||
| 1624 | Any statement can transfer control at any time to the statements that follow | ||
| 1625 | one of the labels with the special form (go LABEL). | ||
| 1626 | Labels 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. |