diff options
| author | Noam Postavsky | 2017-04-21 23:37:05 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2017-06-07 20:03:31 -0400 |
| commit | 0648edf3e05e224ee8410ab244df7364f919dc58 (patch) | |
| tree | d6adddb90e85ba1a7c37168cdfcd190e587de1e9 /lisp | |
| parent | b52e40d756af935a4f6dc46842d306b5493a7b73 (diff) | |
| download | emacs-0648edf3e05e224ee8410ab244df7364f919dc58.tar.gz emacs-0648edf3e05e224ee8410ab244df7364f919dc58.zip | |
Split variable macro env from function env
* lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand): Remove.
(cl-symbol-macrolet): Instead of adding each binding directly into the
main environment with a special key format, put all symbol macro
bindings into a single entry in the main environment under
`:cl-symbol-macros'.
(cl--sm-macroexpand): Look up symbol bindings in the
`:cl-symbol-macros' entry of the environment.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 64 |
1 files changed, 28 insertions, 36 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index db1518ce611..b1ada00f4a4 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2047,28 +2047,22 @@ This is like `cl-flet', but for macros instead of functions. | |||
| 2047 | cl--old-macroexpand | 2047 | cl--old-macroexpand |
| 2048 | (symbol-function 'macroexpand))) | 2048 | (symbol-function 'macroexpand))) |
| 2049 | 2049 | ||
| 2050 | (defun cl--symbol-macro-key (sym) | ||
| 2051 | "Return the key used in `macroexpand-all-environment' for symbol macro SYM." | ||
| 2052 | ;; In the past we've used `symbol-name' instead, but that doesn't | ||
| 2053 | ;; preserve the `eq'uality between different symbols of the same name. | ||
| 2054 | `(:cl-symbol-macro . ,sym)) | ||
| 2055 | |||
| 2056 | (defun cl--sm-macroexpand (exp &optional env) | 2050 | (defun cl--sm-macroexpand (exp &optional env) |
| 2057 | "Special macro expander used inside `cl-symbol-macrolet'. | 2051 | "Special macro expander used inside `cl-symbol-macrolet'. |
| 2058 | This function replaces `macroexpand' during macro expansion | 2052 | This function replaces `macroexpand' during macro expansion |
| 2059 | of `cl-symbol-macrolet', and does the same thing as `macroexpand' | 2053 | of `cl-symbol-macrolet', and does the same thing as `macroexpand' |
| 2060 | except that it additionally expands symbol macros." | 2054 | except that it additionally expands symbol macros." |
| 2061 | (let ((macroexpand-all-environment env)) | 2055 | (let ((macroexpand-all-environment env) |
| 2056 | (venv (alist-get :cl-symbol-macros env))) | ||
| 2062 | (while | 2057 | (while |
| 2063 | (progn | 2058 | (progn |
| 2064 | (setq exp (funcall cl--old-macroexpand exp env)) | 2059 | (setq exp (funcall cl--old-macroexpand exp env)) |
| 2065 | (pcase exp | 2060 | (pcase exp |
| 2066 | ((pred symbolp) | 2061 | ((pred symbolp) |
| 2067 | ;; Perform symbol-macro expansion. | 2062 | ;; Perform symbol-macro expansion. |
| 2068 | ;; FIXME: Calling `cl--symbol-macro-key' for every var reference | 2063 | (let ((symval (assq exp venv))) |
| 2069 | ;; is a bit more costly than I'd like. | 2064 | (when symval |
| 2070 | (when (cdr (assoc (cl--symbol-macro-key exp) env)) | 2065 | (setq exp (cadr symval))))) |
| 2071 | (setq exp (cadr (assoc (cl--symbol-macro-key exp) env))))) | ||
| 2072 | (`(setq . ,_) | 2066 | (`(setq . ,_) |
| 2073 | ;; Convert setq to setf if required by symbol-macro expansion. | 2067 | ;; Convert setq to setf if required by symbol-macro expansion. |
| 2074 | (let* ((args (mapcar (lambda (f) (cl--sm-macroexpand f env)) | 2068 | (let* ((args (mapcar (lambda (f) (cl--sm-macroexpand f env)) |
| @@ -2086,7 +2080,7 @@ except that it additionally expands symbol macros." | |||
| 2086 | (let ((letf nil) (found nil) (nbs ())) | 2080 | (let ((letf nil) (found nil) (nbs ())) |
| 2087 | (dolist (binding bindings) | 2081 | (dolist (binding bindings) |
| 2088 | (let* ((var (if (symbolp binding) binding (car binding))) | 2082 | (let* ((var (if (symbolp binding) binding (car binding))) |
| 2089 | (sm (assoc (cl--symbol-macro-key var) env))) | 2083 | (sm (assq var venv))) |
| 2090 | (push (if (not (cdr sm)) | 2084 | (push (if (not (cdr sm)) |
| 2091 | binding | 2085 | binding |
| 2092 | (let ((nexp (cadr sm))) | 2086 | (let ((nexp (cadr sm))) |
| @@ -2144,30 +2138,28 @@ by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). | |||
| 2144 | 2138 | ||
| 2145 | \(fn ((NAME EXPANSION) ...) FORM...)" | 2139 | \(fn ((NAME EXPANSION) ...) FORM...)" |
| 2146 | (declare (indent 1) (debug ((&rest (symbolp sexp)) cl-declarations body))) | 2140 | (declare (indent 1) (debug ((&rest (symbolp sexp)) cl-declarations body))) |
| 2147 | (cond | 2141 | (let ((previous-macroexpand (symbol-function 'macroexpand)) |
| 2148 | ((cdr bindings) | 2142 | (malformed-bindings nil)) |
| 2149 | `(cl-symbol-macrolet (,(car bindings)) | 2143 | (dolist (binding bindings) |
| 2150 | (cl-symbol-macrolet ,(cdr bindings) ,@body))) | 2144 | (unless (and (consp binding) (symbolp (car binding)) |
| 2151 | ((null bindings) (macroexp-progn body)) | 2145 | (consp (cdr binding)) (null (cddr binding))) |
| 2152 | (t | 2146 | (push binding malformed-bindings))) |
| 2153 | (let ((previous-macroexpand (symbol-function 'macroexpand))) | 2147 | (unwind-protect |
| 2154 | (unwind-protect | 2148 | (progn |
| 2155 | (progn | 2149 | (fset 'macroexpand #'cl--sm-macroexpand) |
| 2156 | (fset 'macroexpand #'cl--sm-macroexpand) | 2150 | (let* ((venv (cdr (assq :cl-symbol-macros macroexpand-all-environment))) |
| 2157 | (let ((expansion | 2151 | (expansion |
| 2158 | ;; FIXME: For N bindings, this will traverse `body' N times! | 2152 | (macroexpand-all (macroexp-progn body) |
| 2159 | (macroexpand-all (macroexp-progn body) | 2153 | (cons (cons :cl-symbol-macros |
| 2160 | (cons (list (cl--symbol-macro-key | 2154 | (append bindings venv)) |
| 2161 | (caar bindings)) | 2155 | macroexpand-all-environment)))) |
| 2162 | (cl-cadar bindings)) | 2156 | (if malformed-bindings |
| 2163 | macroexpand-all-environment)))) | 2157 | (macroexp--warn-and-return |
| 2164 | (if (or (null (cdar bindings)) (cl-cddar bindings)) | 2158 | (format-message "Malformed `cl-symbol-macrolet' binding(s): %S" |
| 2165 | (macroexp--warn-and-return | 2159 | (nreverse malformed-bindings)) |
| 2166 | (format-message "Malformed `cl-symbol-macrolet' binding: %S" | 2160 | expansion) |
| 2167 | (car bindings)) | 2161 | expansion))) |
| 2168 | expansion) | 2162 | (fset 'macroexpand previous-macroexpand)))) |
| 2169 | expansion))) | ||
| 2170 | (fset 'macroexpand previous-macroexpand)))))) | ||
| 2171 | 2163 | ||
| 2172 | ;;; Multiple values. | 2164 | ;;; Multiple values. |
| 2173 | 2165 | ||