Mercurial > hg > xemacs-beta
changeset 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 | 309e5631e4c8 |
files | lisp/ChangeLog lisp/bytecomp-runtime.el lisp/bytecomp.el lisp/cl-extra.el lisp/cl-macs.el lisp/cl.el lisp/obsolete.el |
diffstat | 7 files changed, 163 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/ChangeLog Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/ChangeLog Sun Sep 04 20:37:55 2011 +0100 @@ -1,3 +1,55 @@ +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. + 2011-09-04 Aidan Kehoe <kehoea@parhasard.net> * cl-macs.el (get-char-table): Add a defsetf for this.
--- a/lisp/bytecomp-runtime.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/bytecomp-runtime.el Sun Sep 04 20:37:55 2011 +0100 @@ -634,4 +634,9 @@ (file-format emacs19))" nil) +(defvar byte-compile-macro-environment nil + "Alist of macros defined in the file being compiled. +Each element looks like (MACRONAME . DEFINITION). It is +\(MACRONAME . nil) when a macro is redefined as a function.") + ;;; bytecomp-runtime.el ends here
--- a/lisp/bytecomp.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/bytecomp.el Sun Sep 04 20:37:55 2011 +0100 @@ -491,16 +491,71 @@ "%s is not of type %s" form type))) (if byte-compile-delete-errors form - (funcall (cdr (symbol-function 'the)) type form))))) + (funcall (cdr (symbol-function 'the)) type form)))) + (load-time-value + . ,#'(lambda (form &optional read-only) + (let* ((gensym (gensym)) + (byte-compile-bound-variables + (acons gensym byte-compile-global-bit + byte-compile-bound-variables))) + (setq byte-compile-output-preface + (byte-compile-top-level + `(progn (setq ,gensym ,form) ,byte-compile-output-preface) + t 'file)) + `(symbol-value ',gensym)))) + (labels + . ,#'(lambda (bindings &rest body) + (let* ((bindings + (mapcar (function* + (lambda ((name . binding)) + (list* name 'lambda + (cdr (cl-transform-lambda binding + name))))) + bindings)) + ;; These placeholders are to ensure that the + ;; lexically-scoped functions can be called from each + ;; other. + (placeholders + (mapcar #'(lambda (binding) + (cons (car binding) + (make-byte-code (third binding) + "\xc0\x87" [42] 1))) + bindings)) + (byte-compile-macro-environment + (nconc + (mapcar + (function* + (lambda ((name . placeholder)) + (cons name `(lambda (&rest cl-labels-args) + (list* 'funcall ,placeholder + cl-labels-args))))) + placeholders) + byte-compile-macro-environment)) + placeholder-map) + (setq bindings + (mapcar (function* + (lambda ((name . lambda)) + (cons name (byte-compile-lambda lambda)))) + bindings) + placeholder-map + (mapcar (function* + (lambda ((name . compiled-function)) + (cons (cdr (assq name placeholders)) + compiled-function))) + bindings)) + (loop + for (placeholder . compiled-function) + in placeholder-map + do (nsubst compiled-function placeholder bindings + :test 'eq :descend-structures t)) + (cl-macroexpand-all (cons 'progn body) + (sublis placeholder-map + byte-compile-macro-environment + :test 'eq)))))) "The default macro-environment passed to macroexpand by the compiler. Placing a macro here will cause a macro to have different semantics when expanded by the compiler as when expanded by the interpreter.") -(defvar byte-compile-macro-environment byte-compile-initial-macro-environment - "Alist of macros defined in the file being compiled. -Each element looks like (MACRONAME . DEFINITION). It is -\(MACRONAME . nil) when a macro is redefined as a function.") - (defvar byte-compile-function-environment nil "Alist of functions defined in the file being compiled. This is so we can inline them when necessary. @@ -3086,7 +3141,7 @@ (byte-defop-compiler car 1) (byte-defop-compiler cdr 1) (byte-defop-compiler length 1) -(byte-defop-compiler symbol-value) +(byte-defop-compiler symbol-value 1) (byte-defop-compiler symbol-function 1) (byte-defop-compiler (1+ byte-add1) 1) (byte-defop-compiler (1- byte-sub1) 1) @@ -4237,29 +4292,6 @@ (byte-compile-out 'byte-temp-output-buffer-setup 0) (byte-compile-body (cdr (cdr form))) (byte-compile-out 'byte-temp-output-buffer-show 0)) - -(defun byte-compile-symbol-value (form) - (symbol-macrolet ((not-present '#:not-present)) - (let ((cl-load-time-value-form not-present) - (byte-compile-bound-variables byte-compile-bound-variables) gensym) - (and (consp (cadr form)) - (eq 'quote (caadr form)) - (setq gensym (cadadr form)) - (symbolp gensym) - (setq cl-load-time-value-form - (get gensym 'cl-load-time-value-form not-present))) - (unless (eq cl-load-time-value-form not-present) - (setq byte-compile-bound-variables - (acons gensym byte-compile-global-bit - byte-compile-bound-variables) - byte-compile-output-preface - (byte-compile-top-level - (if byte-compile-output-preface - `(progn (setq ,gensym ,cl-load-time-value-form) - ,byte-compile-output-preface) - `(setq ,gensym ,cl-load-time-value-form)) - t 'file))) - (byte-compile-one-arg form)))) (defun byte-compile-multiple-value-call (form) (if (< (length form) 2)
--- a/lisp/cl-extra.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/cl-extra.el Sun Sep 04 20:37:55 2011 +0100 @@ -609,13 +609,18 @@ cl-closure-vars) '((quote --cl-rest--))))))) (list (car form) (list* 'lambda (cadadr form) body)))) - (let ((found (assq (cadr form) env))) - ;; XEmacs: cadr/caddr operate on nil without errors. But the - ;; macro definition may be compiled, in which case there's - ;; nothing for us to do. - (if (and (listp (cdr found)) - (eq (cadr (caddr found)) 'cl-labels-args)) - (cl-macroexpand-all (cadr (caddr (cadddr found))) env) + ;; This is a bit of a hack; special-case symbols with bindings as + ;; labels. + (let ((found (cdr (assq (cadr form) env)))) + (if (and (consp found) (eq (nth 1 (nth 1 found)) 'cl-labels-args)) + (if (consp (nth 2 (nth 2 found))) + ;; It's a cons; this is the implementation of + ;; labels in cl-macs.el. + (cl-macroexpand-all (nth 1 (nth 2 (nth 2 found))) env) + ;; It's an atom, almost certainly a compiled function; + ;; we're using the implementation of labels in + ;; bytecomp.el. + (nth 2 (nth 2 found))) form)))) ((memq (car form) '(defun defmacro)) (list* (car form) (nth 1 form) (cl-macroexpand-body (cddr form) env)))
--- a/lisp/cl-macs.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/cl-macs.el Sun Sep 04 20:37:55 2011 +0100 @@ -297,7 +297,6 @@ (defconst lambda-list-keywords '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) -(defvar cl-macro-environment nil) (defvar bind-block) (defvar bind-defs) (defvar bind-enquote) (defvar bind-lets) (defvar bind-forms) @@ -370,7 +369,7 @@ (if (memq '&whole args) (error "&whole not currently implemented")) (let* ((p (memq '&environment args)) (v (cadr p))) (if p (setq args (nconc (delq (car p) (delq v args)) - (list '&aux (list v 'cl-macro-environment)))))) + `(&aux (,v byte-compile-macro-environment)))))) (while (and args (symbolp (car args)) (not (memq (car args) '(nil &rest &body &key &aux))) (not (and (eq (car args) '&optional) @@ -626,15 +625,7 @@ (defmacro load-time-value (form &optional read-only) "Like `progn', but evaluates the body at load time. The result of the body appears to the compiler as a quoted constant." - (let ((gensym (gensym))) - ;; The body of this macro really should be (cons 'progn form), with the - ;; hairier stuff in a shadowed version in - ;; byte-compile-initial-macro-environment. That doesn't work because - ;; cl-macs.el doesn't respect byte-compile-macro-environment, which is - ;; something we should change. - (put gensym 'cl-load-time-value-form form) - (set gensym (eval form)) - `(symbol-value ',gensym))) + (list 'progn form)) ;;; Conditional control structures. @@ -746,7 +737,7 @@ ;; as such it can eliminate it if that's appropriate: (put (cdar cl-active-block-names) 'cl-block-name name) `(catch ',(cdar cl-active-block-names) - ,(cl-macroexpand-all body cl-macro-environment)))) + ,(cl-macroexpand-all body byte-compile-macro-environment)))) ;;;###autoload (defmacro return (&optional result) @@ -1738,7 +1729,7 @@ #'(lambda (x) (if (or (and (fboundp (car x)) (eq (car-safe (symbol-function (car x))) 'macro)) - (cdr (assq (car x) cl-macro-environment))) + (cdr (assq (car x) byte-compile-macro-environment))) (error "Use `labels', not `flet', to rebind macro names")) (let ((func (list 'function* (list 'lambda (cadr x) @@ -1758,18 +1749,20 @@ Unlike `flet', this macro is fully compliant with the Common Lisp standard. arguments: (((FUNC ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)" - (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment)) + (let ((vars nil) (sets nil) + (byte-compile-macro-environment byte-compile-macro-environment)) (while bindings (let ((var (gensym))) (push var vars) - (push (list 'function* (cons 'lambda (cdar bindings))) sets) + (push `#'(lambda ,@(cdr (cl-transform-lambda (cdar bindings) + (caar bindings)))) sets) (push var sets) (push (list (car (pop bindings)) 'lambda '(&rest cl-labels-args) (list 'list* '(quote funcall) (list 'quote var) 'cl-labels-args)) - cl-macro-environment))) + byte-compile-macro-environment))) (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body)) - cl-macro-environment))) + byte-compile-macro-environment))) ;; The following ought to have a better definition for use with newer ;; byte compilers. @@ -1785,7 +1778,7 @@ collect (list* name 'lambda (cdr (cl-transform-lambda details name)))) - cl-macro-environment))) + byte-compile-macro-environment))) ;;;###autoload (defmacro* symbol-macrolet ((&rest symbol-macros) &body form) @@ -1798,7 +1791,7 @@ for (name expansion) in symbol-macros do (check-type name symbol) collect (list (eq-hash name) expansion)) - cl-macro-environment))) + byte-compile-macro-environment))) (defvar cl-closure-vars nil) ;;;###autoload @@ -1824,7 +1817,7 @@ t)) vars) (list '(defun . cl-defun-expander)) - cl-macro-environment)))) + byte-compile-macro-environment)))) (if (not (get (car (last cl-closure-vars)) 'used)) (list 'let (mapcar #'(lambda (x) (list (caddr x) (cadr x))) vars) (sublis (mapcar #'(lambda (x) @@ -2336,14 +2329,14 @@ ;;; More complex setf-methods. ;;; These should take &environment arguments, but since full arglists aren't ;;; available while compiling cl-macs, we fake it by referring to the global -;;; variable cl-macro-environment directly. +;;; variable byte-compile-macro-environment directly. (define-setf-method apply (func arg1 &rest rest) (or (and (memq (car-safe func) '(quote function function*)) (symbolp (car-safe (cdr-safe func)))) (error "First arg to apply in setf is not (function SYM): %s" func)) (let* ((form (cons (nth 1 func) (cons arg1 rest))) - (method (get-setf-method form cl-macro-environment))) + (method (get-setf-method form byte-compile-macro-environment))) (list (car method) (nth 1 method) (nth 2 method) (cl-setf-make-apply (nth 3 method) (cadr func) (car method)) (cl-setf-make-apply (nth 4 method) (cadr func) (car method))))) @@ -2356,7 +2349,7 @@ (list* 'apply (list 'quote (car form)) (cdr form)))) (define-setf-method nthcdr (n place) - (let ((method (get-setf-method place cl-macro-environment)) + (let ((method (get-setf-method place byte-compile-macro-environment)) (n-temp (gensym "--nthcdr-n--")) (store-temp (gensym "--nthcdr-store--"))) (list (cons n-temp (car method)) @@ -2369,7 +2362,7 @@ (list 'nthcdr n-temp (nth 4 method))))) (define-setf-method getf (place tag &optional def) - (let ((method (get-setf-method place cl-macro-environment)) + (let ((method (get-setf-method place byte-compile-macro-environment)) (tag-temp (gensym "--getf-tag--")) (def-temp (gensym "--getf-def--")) (store-temp (gensym "--getf-store--"))) @@ -2383,7 +2376,7 @@ (list 'getf (nth 4 method) tag-temp def-temp)))) (define-setf-method substring (place from &optional to) - (let ((method (get-setf-method place cl-macro-environment)) + (let ((method (get-setf-method place byte-compile-macro-environment)) (from-temp (gensym "--substring-from--")) (to-temp (gensym "--substring-to--")) (store-temp (gensym "--substring-store--"))) @@ -2399,7 +2392,7 @@ ;; XEmacs addition (define-setf-method values (&rest args) (let ((methods (mapcar #'(lambda (x) - (get-setf-method x cl-macro-environment)) + (get-setf-method x byte-compile-macro-environment)) args)) (store-temp (gensym "--values-store--"))) (list (apply 'append (mapcar 'first methods)) @@ -2428,7 +2421,7 @@ (method (get func 'setf-method)) (case-fold-search nil)) (or (and method - (let ((cl-macro-environment env)) + (let ((byte-compile-macro-environment env)) (setq method (apply method (cdr place)))) (if (and (consp method) (eql (length method) 5)) method @@ -2449,7 +2442,7 @@ (get-setf-method place env))))) (defun cl-setf-do-modify (place opt-expr) - (let* ((method (get-setf-method place cl-macro-environment)) + (let* ((method (get-setf-method place byte-compile-macro-environment)) (temps (car method)) (values (nth 1 method)) (lets nil) (subs nil) (optimize (and (not (eq opt-expr 'no-opt))
--- a/lisp/cl.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/cl.el Sun Sep 04 20:37:55 2011 +0100 @@ -213,7 +213,6 @@ ;;; Macros. -(defvar cl-macro-environment nil) ;; XEmacs: we renamed the internal function to macroexpand-internal ;; to avoid doc-file problems. (defvar cl-old-macroexpand (prog1 (symbol-function 'macroexpand-internal) @@ -227,17 +226,19 @@ The second optional arg ENVIRONMENT specifies an environment of macro definitions to shadow the loaded ones for use in file byte-compilation." - (let ((cl-macro-environment - (if cl-macro-environment (append cl-env cl-macro-environment) cl-env)) + (let ((byte-compile-macro-environment + (if byte-compile-macro-environment + (append cl-env byte-compile-macro-environment) cl-env)) eq-hash) (while (progn (setq cl-macro - (macroexpand-internal cl-macro cl-macro-environment)) + (macroexpand-internal cl-macro + byte-compile-macro-environment)) (and (symbolp cl-macro) (setq eq-hash (eq-hash cl-macro)) (cdr (if (fixnump eq-hash) - (assq eq-hash cl-macro-environment) - (assoc eq-hash cl-macro-environment))))) - (setq cl-macro (cadr (assoc* eq-hash cl-macro-environment)))) + (assq eq-hash byte-compile-macro-environment) + (assoc eq-hash byte-compile-macro-environment))))) + (setq cl-macro (cadr (assoc* eq-hash byte-compile-macro-environment)))) cl-macro)) ;;; Declarations.
--- a/lisp/obsolete.el Sun Sep 04 20:35:31 2011 +0100 +++ b/lisp/obsolete.el Sun Sep 04 20:37:55 2011 +0100 @@ -449,5 +449,8 @@ (define-function 'memql 'member*) (make-compatible 'memql "use the more full-featured `member*' instead.") +(define-obsolete-variable-alias 'cl-macro-environment + 'byte-compile-macro-environment) + (provide 'obsolete) ;;; obsolete.el ends here