Mercurial > hg > xemacs-beta
comparison lisp/cl-macs.el @ 5562:855b667dea13
Drop cl-macro-environment in favour of byte-compile-macro-environment.
lisp/ChangeLog addition:
2011-09-04 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp-runtime.el:
* bytecomp-runtime.el (byte-compile-macro-environment): Moved from
bytecomp.el.
* bytecomp.el:
* bytecomp.el (byte-compile-initial-macro-environment):
Add implementations for #'load-time-value, #'labels here, now
cl-macs respects byte-compile-macro-environment.
* bytecomp.el (byte-compile-function-environment):
* bytecomp.el (byte-compile-macro-environment): Removed.
* bytecomp.el (symbol-value):
* bytecomp.el (byte-compile-symbol-value): Removed.
* cl-extra.el (cl-macroexpand-all):
* cl-macs.el:
* cl-macs.el (bind-block):
* cl-macs.el (cl-macro-environment): Removed.
* cl-macs.el (cl-transform-lambda):
* cl-macs.el (load-time-value):
* cl-macs.el (block):
* cl-macs.el (flet):
* cl-macs.el (labels):
* cl-macs.el (macrolet):
* cl-macs.el (symbol-macrolet):
* cl-macs.el (lexical-let):
* cl-macs.el (apply):
* cl-macs.el (nthcdr):
* cl-macs.el (getf):
* cl-macs.el (substring):
* cl-macs.el (values):
* cl-macs.el (get-setf-method):
* cl-macs.el (cl-setf-do-modify):
* cl.el:
* cl.el (cl-macro-environment): Removed.
* cl.el (cl-macroexpand):
* obsolete.el (cl-macro-environment): Moved here.
Drop cl-macro-environment, in favour of
byte-compile-macro-environment; make the latter available in
bytecomp-runtime.el. This makes byte-compile-macro-environment far
less useless, since previously code that used cl-macs would ignore
it when calling #'cl-macroexpand-all.
Add byte-compiler-specific implementations for #'load-time-value,
#'labels. The latter is very nice indeed; it avoids the run-time
consing of the current implementation, is fully lexical and avoids
the run-time shadowing of symbol function slots that flet uses. It
would now be reasonable to move most core uses of flet to use
labels instead. Non-core code can't rely on print-circle for
mutually recursive functions, though, so it's less of an evident
win.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 04 Sep 2011 20:37:55 +0100 |
parents | 9a93bc90b3bd |
children | 4654c01af32b |
comparison
equal
deleted
inserted
replaced
5561:9a93bc90b3bd | 5562:855b667dea13 |
---|---|
295 `(put ',func ',prop #'(lambda ,@(cdr (cl-transform-lambda form func))))) | 295 `(put ',func ',prop #'(lambda ,@(cdr (cl-transform-lambda form func))))) |
296 | 296 |
297 (defconst lambda-list-keywords | 297 (defconst lambda-list-keywords |
298 '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) | 298 '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) |
299 | 299 |
300 (defvar cl-macro-environment nil) | |
301 (defvar bind-block) (defvar bind-defs) (defvar bind-enquote) | 300 (defvar bind-block) (defvar bind-defs) (defvar bind-enquote) |
302 (defvar bind-lets) (defvar bind-forms) | 301 (defvar bind-lets) (defvar bind-forms) |
303 | 302 |
304 ;; npak@ispras.ru | 303 ;; npak@ispras.ru |
305 (defun cl-upcase-arg (arg) | 304 (defun cl-upcase-arg (arg) |
368 (if (setq bind-enquote (memq '&cl-quote args)) | 367 (if (setq bind-enquote (memq '&cl-quote args)) |
369 (setq args (delq '&cl-quote args))) | 368 (setq args (delq '&cl-quote args))) |
370 (if (memq '&whole args) (error "&whole not currently implemented")) | 369 (if (memq '&whole args) (error "&whole not currently implemented")) |
371 (let* ((p (memq '&environment args)) (v (cadr p))) | 370 (let* ((p (memq '&environment args)) (v (cadr p))) |
372 (if p (setq args (nconc (delq (car p) (delq v args)) | 371 (if p (setq args (nconc (delq (car p) (delq v args)) |
373 (list '&aux (list v 'cl-macro-environment)))))) | 372 `(&aux (,v byte-compile-macro-environment)))))) |
374 (while (and args (symbolp (car args)) | 373 (while (and args (symbolp (car args)) |
375 (not (memq (car args) '(nil &rest &body &key &aux))) | 374 (not (memq (car args) '(nil &rest &body &key &aux))) |
376 (not (and (eq (car args) '&optional) | 375 (not (and (eq (car args) '&optional) |
377 (or bind-defs (consp (cadr args)))))) | 376 (or bind-defs (consp (cadr args)))))) |
378 (push (pop args) simple-args)) | 377 (push (pop args) simple-args)) |
624 | 623 |
625 ;;;###autoload | 624 ;;;###autoload |
626 (defmacro load-time-value (form &optional read-only) | 625 (defmacro load-time-value (form &optional read-only) |
627 "Like `progn', but evaluates the body at load time. | 626 "Like `progn', but evaluates the body at load time. |
628 The result of the body appears to the compiler as a quoted constant." | 627 The result of the body appears to the compiler as a quoted constant." |
629 (let ((gensym (gensym))) | 628 (list 'progn form)) |
630 ;; The body of this macro really should be (cons 'progn form), with the | |
631 ;; hairier stuff in a shadowed version in | |
632 ;; byte-compile-initial-macro-environment. That doesn't work because | |
633 ;; cl-macs.el doesn't respect byte-compile-macro-environment, which is | |
634 ;; something we should change. | |
635 (put gensym 'cl-load-time-value-form form) | |
636 (set gensym (eval form)) | |
637 `(symbol-value ',gensym))) | |
638 | 629 |
639 ;;; Conditional control structures. | 630 ;;; Conditional control structures. |
640 | 631 |
641 ;;;###autoload | 632 ;;;###autoload |
642 (defmacro case (expr &rest clauses) | 633 (defmacro case (expr &rest clauses) |
744 (body (cons 'progn body))) | 735 (body (cons 'progn body))) |
745 ;; Tell the byte-compiler this is a block, not a normal catch call, and | 736 ;; Tell the byte-compiler this is a block, not a normal catch call, and |
746 ;; as such it can eliminate it if that's appropriate: | 737 ;; as such it can eliminate it if that's appropriate: |
747 (put (cdar cl-active-block-names) 'cl-block-name name) | 738 (put (cdar cl-active-block-names) 'cl-block-name name) |
748 `(catch ',(cdar cl-active-block-names) | 739 `(catch ',(cdar cl-active-block-names) |
749 ,(cl-macroexpand-all body cl-macro-environment)))) | 740 ,(cl-macroexpand-all body byte-compile-macro-environment)))) |
750 | 741 |
751 ;;;###autoload | 742 ;;;###autoload |
752 (defmacro return (&optional result) | 743 (defmacro return (&optional result) |
753 "Return from the block named nil. | 744 "Return from the block named nil. |
754 This is equivalent to `(return-from nil RESULT)'." | 745 This is equivalent to `(return-from nil RESULT)'." |
1736 (list* 'letf* | 1727 (list* 'letf* |
1737 (mapcar | 1728 (mapcar |
1738 #'(lambda (x) | 1729 #'(lambda (x) |
1739 (if (or (and (fboundp (car x)) | 1730 (if (or (and (fboundp (car x)) |
1740 (eq (car-safe (symbol-function (car x))) 'macro)) | 1731 (eq (car-safe (symbol-function (car x))) 'macro)) |
1741 (cdr (assq (car x) cl-macro-environment))) | 1732 (cdr (assq (car x) byte-compile-macro-environment))) |
1742 (error "Use `labels', not `flet', to rebind macro names")) | 1733 (error "Use `labels', not `flet', to rebind macro names")) |
1743 (let ((func (list 'function* | 1734 (let ((func (list 'function* |
1744 (list 'lambda (cadr x) | 1735 (list 'lambda (cadr x) |
1745 (list* 'block (car x) (cddr x)))))) | 1736 (list* 'block (car x) (cddr x)))))) |
1746 (if (and (cl-compiling-file) | 1737 (if (and (cl-compiling-file) |
1756 "Make temporary func bindings. | 1747 "Make temporary func bindings. |
1757 This is like `flet', except the bindings are lexical instead of dynamic. | 1748 This is like `flet', except the bindings are lexical instead of dynamic. |
1758 Unlike `flet', this macro is fully compliant with the Common Lisp standard. | 1749 Unlike `flet', this macro is fully compliant with the Common Lisp standard. |
1759 | 1750 |
1760 arguments: (((FUNC ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)" | 1751 arguments: (((FUNC ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)" |
1761 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment)) | 1752 (let ((vars nil) (sets nil) |
1753 (byte-compile-macro-environment byte-compile-macro-environment)) | |
1762 (while bindings | 1754 (while bindings |
1763 (let ((var (gensym))) | 1755 (let ((var (gensym))) |
1764 (push var vars) | 1756 (push var vars) |
1765 (push (list 'function* (cons 'lambda (cdar bindings))) sets) | 1757 (push `#'(lambda ,@(cdr (cl-transform-lambda (cdar bindings) |
1758 (caar bindings)))) sets) | |
1766 (push var sets) | 1759 (push var sets) |
1767 (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args) | 1760 (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args) |
1768 (list 'list* '(quote funcall) (list 'quote var) | 1761 (list 'list* '(quote funcall) (list 'quote var) |
1769 'cl-labels-args)) | 1762 'cl-labels-args)) |
1770 cl-macro-environment))) | 1763 byte-compile-macro-environment))) |
1771 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body)) | 1764 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body)) |
1772 cl-macro-environment))) | 1765 byte-compile-macro-environment))) |
1773 | 1766 |
1774 ;; The following ought to have a better definition for use with newer | 1767 ;; The following ought to have a better definition for use with newer |
1775 ;; byte compilers. | 1768 ;; byte compilers. |
1776 ;;;###autoload | 1769 ;;;###autoload |
1777 (defmacro* macrolet ((&rest macros) &body form) | 1770 (defmacro* macrolet ((&rest macros) &body form) |
1783 for (name . details) | 1776 for (name . details) |
1784 in macros | 1777 in macros |
1785 collect | 1778 collect |
1786 (list* name 'lambda (cdr (cl-transform-lambda details | 1779 (list* name 'lambda (cdr (cl-transform-lambda details |
1787 name)))) | 1780 name)))) |
1788 cl-macro-environment))) | 1781 byte-compile-macro-environment))) |
1789 | 1782 |
1790 ;;;###autoload | 1783 ;;;###autoload |
1791 (defmacro* symbol-macrolet ((&rest symbol-macros) &body form) | 1784 (defmacro* symbol-macrolet ((&rest symbol-macros) &body form) |
1792 "Make temporary symbol macro definitions. | 1785 "Make temporary symbol macro definitions. |
1793 Elements in SYMBOL-MACROS look like (NAME EXPANSION). | 1786 Elements in SYMBOL-MACROS look like (NAME EXPANSION). |
1796 (cl-macroexpand-all (cons 'progn form) | 1789 (cl-macroexpand-all (cons 'progn form) |
1797 (nconc (loop | 1790 (nconc (loop |
1798 for (name expansion) in symbol-macros | 1791 for (name expansion) in symbol-macros |
1799 do (check-type name symbol) | 1792 do (check-type name symbol) |
1800 collect (list (eq-hash name) expansion)) | 1793 collect (list (eq-hash name) expansion)) |
1801 cl-macro-environment))) | 1794 byte-compile-macro-environment))) |
1802 | 1795 |
1803 (defvar cl-closure-vars nil) | 1796 (defvar cl-closure-vars nil) |
1804 ;;;###autoload | 1797 ;;;###autoload |
1805 (defmacro lexical-let (bindings &rest body) | 1798 (defmacro lexical-let (bindings &rest body) |
1806 "Like `let', but lexically scoped. | 1799 "Like `let', but lexically scoped. |
1822 (list (eq-hash (car x)) | 1815 (list (eq-hash (car x)) |
1823 (list 'symbol-value (caddr x)) | 1816 (list 'symbol-value (caddr x)) |
1824 t)) | 1817 t)) |
1825 vars) | 1818 vars) |
1826 (list '(defun . cl-defun-expander)) | 1819 (list '(defun . cl-defun-expander)) |
1827 cl-macro-environment)))) | 1820 byte-compile-macro-environment)))) |
1828 (if (not (get (car (last cl-closure-vars)) 'used)) | 1821 (if (not (get (car (last cl-closure-vars)) 'used)) |
1829 (list 'let (mapcar #'(lambda (x) (list (caddr x) (cadr x))) vars) | 1822 (list 'let (mapcar #'(lambda (x) (list (caddr x) (cadr x))) vars) |
1830 (sublis (mapcar #'(lambda (x) | 1823 (sublis (mapcar #'(lambda (x) |
1831 (cons (caddr x) (list 'quote (caddr x)))) | 1824 (cons (caddr x) (list 'quote (caddr x)))) |
1832 vars) | 1825 vars) |
2334 (defsetf get-selection own-selection t) | 2327 (defsetf get-selection own-selection t) |
2335 | 2328 |
2336 ;;; More complex setf-methods. | 2329 ;;; More complex setf-methods. |
2337 ;;; These should take &environment arguments, but since full arglists aren't | 2330 ;;; These should take &environment arguments, but since full arglists aren't |
2338 ;;; available while compiling cl-macs, we fake it by referring to the global | 2331 ;;; available while compiling cl-macs, we fake it by referring to the global |
2339 ;;; variable cl-macro-environment directly. | 2332 ;;; variable byte-compile-macro-environment directly. |
2340 | 2333 |
2341 (define-setf-method apply (func arg1 &rest rest) | 2334 (define-setf-method apply (func arg1 &rest rest) |
2342 (or (and (memq (car-safe func) '(quote function function*)) | 2335 (or (and (memq (car-safe func) '(quote function function*)) |
2343 (symbolp (car-safe (cdr-safe func)))) | 2336 (symbolp (car-safe (cdr-safe func)))) |
2344 (error "First arg to apply in setf is not (function SYM): %s" func)) | 2337 (error "First arg to apply in setf is not (function SYM): %s" func)) |
2345 (let* ((form (cons (nth 1 func) (cons arg1 rest))) | 2338 (let* ((form (cons (nth 1 func) (cons arg1 rest))) |
2346 (method (get-setf-method form cl-macro-environment))) | 2339 (method (get-setf-method form byte-compile-macro-environment))) |
2347 (list (car method) (nth 1 method) (nth 2 method) | 2340 (list (car method) (nth 1 method) (nth 2 method) |
2348 (cl-setf-make-apply (nth 3 method) (cadr func) (car method)) | 2341 (cl-setf-make-apply (nth 3 method) (cadr func) (car method)) |
2349 (cl-setf-make-apply (nth 4 method) (cadr func) (car method))))) | 2342 (cl-setf-make-apply (nth 4 method) (cadr func) (car method))))) |
2350 | 2343 |
2351 (defun cl-setf-make-apply (form func temps) | 2344 (defun cl-setf-make-apply (form func temps) |
2354 (or (equal (last form) (last temps)) | 2347 (or (equal (last form) (last temps)) |
2355 (error "%s is not suitable for use with setf-of-apply" func)) | 2348 (error "%s is not suitable for use with setf-of-apply" func)) |
2356 (list* 'apply (list 'quote (car form)) (cdr form)))) | 2349 (list* 'apply (list 'quote (car form)) (cdr form)))) |
2357 | 2350 |
2358 (define-setf-method nthcdr (n place) | 2351 (define-setf-method nthcdr (n place) |
2359 (let ((method (get-setf-method place cl-macro-environment)) | 2352 (let ((method (get-setf-method place byte-compile-macro-environment)) |
2360 (n-temp (gensym "--nthcdr-n--")) | 2353 (n-temp (gensym "--nthcdr-n--")) |
2361 (store-temp (gensym "--nthcdr-store--"))) | 2354 (store-temp (gensym "--nthcdr-store--"))) |
2362 (list (cons n-temp (car method)) | 2355 (list (cons n-temp (car method)) |
2363 (cons n (nth 1 method)) | 2356 (cons n (nth 1 method)) |
2364 (list store-temp) | 2357 (list store-temp) |
2367 store-temp))) | 2360 store-temp))) |
2368 (nth 3 method) store-temp) | 2361 (nth 3 method) store-temp) |
2369 (list 'nthcdr n-temp (nth 4 method))))) | 2362 (list 'nthcdr n-temp (nth 4 method))))) |
2370 | 2363 |
2371 (define-setf-method getf (place tag &optional def) | 2364 (define-setf-method getf (place tag &optional def) |
2372 (let ((method (get-setf-method place cl-macro-environment)) | 2365 (let ((method (get-setf-method place byte-compile-macro-environment)) |
2373 (tag-temp (gensym "--getf-tag--")) | 2366 (tag-temp (gensym "--getf-tag--")) |
2374 (def-temp (gensym "--getf-def--")) | 2367 (def-temp (gensym "--getf-def--")) |
2375 (store-temp (gensym "--getf-store--"))) | 2368 (store-temp (gensym "--getf-store--"))) |
2376 (list (append (car method) (list tag-temp def-temp)) | 2369 (list (append (car method) (list tag-temp def-temp)) |
2377 (append (nth 1 method) (list tag def)) | 2370 (append (nth 1 method) (list tag def)) |
2381 tag-temp store-temp))) | 2374 tag-temp store-temp))) |
2382 (nth 3 method) store-temp) | 2375 (nth 3 method) store-temp) |
2383 (list 'getf (nth 4 method) tag-temp def-temp)))) | 2376 (list 'getf (nth 4 method) tag-temp def-temp)))) |
2384 | 2377 |
2385 (define-setf-method substring (place from &optional to) | 2378 (define-setf-method substring (place from &optional to) |
2386 (let ((method (get-setf-method place cl-macro-environment)) | 2379 (let ((method (get-setf-method place byte-compile-macro-environment)) |
2387 (from-temp (gensym "--substring-from--")) | 2380 (from-temp (gensym "--substring-from--")) |
2388 (to-temp (gensym "--substring-to--")) | 2381 (to-temp (gensym "--substring-to--")) |
2389 (store-temp (gensym "--substring-store--"))) | 2382 (store-temp (gensym "--substring-store--"))) |
2390 (list (append (car method) (list from-temp to-temp)) | 2383 (list (append (car method) (list from-temp to-temp)) |
2391 (append (nth 1 method) (list from to)) | 2384 (append (nth 1 method) (list from to)) |
2397 (list 'substring (nth 4 method) from-temp to-temp)))) | 2390 (list 'substring (nth 4 method) from-temp to-temp)))) |
2398 | 2391 |
2399 ;; XEmacs addition | 2392 ;; XEmacs addition |
2400 (define-setf-method values (&rest args) | 2393 (define-setf-method values (&rest args) |
2401 (let ((methods (mapcar #'(lambda (x) | 2394 (let ((methods (mapcar #'(lambda (x) |
2402 (get-setf-method x cl-macro-environment)) | 2395 (get-setf-method x byte-compile-macro-environment)) |
2403 args)) | 2396 args)) |
2404 (store-temp (gensym "--values-store--"))) | 2397 (store-temp (gensym "--values-store--"))) |
2405 (list (apply 'append (mapcar 'first methods)) | 2398 (list (apply 'append (mapcar 'first methods)) |
2406 (apply 'append (mapcar 'second methods)) | 2399 (apply 'append (mapcar 'second methods)) |
2407 `((,store-temp | 2400 `((,store-temp |
2426 (let* ((func (car place)) | 2419 (let* ((func (car place)) |
2427 (name (symbol-name func)) | 2420 (name (symbol-name func)) |
2428 (method (get func 'setf-method)) | 2421 (method (get func 'setf-method)) |
2429 (case-fold-search nil)) | 2422 (case-fold-search nil)) |
2430 (or (and method | 2423 (or (and method |
2431 (let ((cl-macro-environment env)) | 2424 (let ((byte-compile-macro-environment env)) |
2432 (setq method (apply method (cdr place)))) | 2425 (setq method (apply method (cdr place)))) |
2433 (if (and (consp method) (eql (length method) 5)) | 2426 (if (and (consp method) (eql (length method) 5)) |
2434 method | 2427 method |
2435 (error "Setf-method for %s returns malformed method" | 2428 (error "Setf-method for %s returns malformed method" |
2436 func))) | 2429 func))) |
2447 (cdr place)) env) | 2440 (cdr place)) env) |
2448 (error "No setf-method known for %s" (car place))) | 2441 (error "No setf-method known for %s" (car place))) |
2449 (get-setf-method place env))))) | 2442 (get-setf-method place env))))) |
2450 | 2443 |
2451 (defun cl-setf-do-modify (place opt-expr) | 2444 (defun cl-setf-do-modify (place opt-expr) |
2452 (let* ((method (get-setf-method place cl-macro-environment)) | 2445 (let* ((method (get-setf-method place byte-compile-macro-environment)) |
2453 (temps (car method)) (values (nth 1 method)) | 2446 (temps (car method)) (values (nth 1 method)) |
2454 (lets nil) (subs nil) | 2447 (lets nil) (subs nil) |
2455 (optimize (and (not (eq opt-expr 'no-opt)) | 2448 (optimize (and (not (eq opt-expr 'no-opt)) |
2456 (or (and (not (eq opt-expr 'unsafe)) | 2449 (or (and (not (eq opt-expr 'unsafe)) |
2457 (cl-safe-expr-p opt-expr)) | 2450 (cl-safe-expr-p opt-expr)) |