aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorNoam Postavsky2017-04-21 23:37:05 -0400
committerNoam Postavsky2017-06-07 20:03:31 -0400
commit0648edf3e05e224ee8410ab244df7364f919dc58 (patch)
treed6adddb90e85ba1a7c37168cdfcd190e587de1e9 /lisp
parentb52e40d756af935a4f6dc46842d306b5493a7b73 (diff)
downloademacs-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.el64
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'.
2058This function replaces `macroexpand' during macro expansion 2052This function replaces `macroexpand' during macro expansion
2059of `cl-symbol-macrolet', and does the same thing as `macroexpand' 2053of `cl-symbol-macrolet', and does the same thing as `macroexpand'
2060except that it additionally expands symbol macros." 2054except 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