diff options
| author | Stefan Monnier | 2011-02-11 17:30:02 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2011-02-11 17:30:02 -0500 |
| commit | 295fb2ac59b66c0e2470325a42c8e58c135ed044 (patch) | |
| tree | 79a1ad28fff71252a5d19b49b1d2a6827849039c | |
| parent | 43e67019dfc4fb7d3474e0fbedcfec60f2300521 (diff) | |
| download | emacs-295fb2ac59b66c0e2470325a42c8e58c135ed044.tar.gz emacs-295fb2ac59b66c0e2470325a42c8e58c135ed044.zip | |
Let cconv use :fun-body in special forms that need it.
* lisp/emacs-lisp/cconv.el (cconv-closure-convert): Drop `toplevel' arg.
(cconv-closure-convert-toplevel): Remove.
(cconv-lookup-let): New fun.
(cconv-closure-convert-rec): Don't bother with defs-are-legal.
Use :fun-body to handle special forms that require closing their forms.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file-form, byte-compile):
Use cconv-closure-convert instead of cconv-closure-convert-toplevel.
(byte-compile-lambda, byte-compile-make-closure):
* lisp/emacs-lisp/byte-lexbind.el (byte-compile-maybe-push-heap-environment):
Make sure cconv did its job.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Check stack-depth
before using it.
* lisp/dired.el (dired-desktop-buffer-misc-data): Don't use a dynamic var as
function argument.
| -rw-r--r-- | lisp/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/dired.el | 11 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-lexbind.el | 1 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 11 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 10 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cconv.el | 347 | ||||
| -rw-r--r-- | lisp/mpc.el | 3 |
7 files changed, 201 insertions, 202 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6a47a2626a5..c3451d9b269 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,25 @@ | |||
| 1 | 2011-02-11 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2011-02-11 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/cconv.el (cconv-closure-convert): Drop `toplevel' arg. | ||
| 4 | (cconv-closure-convert-toplevel): Remove. | ||
| 5 | (cconv-lookup-let): New fun. | ||
| 6 | (cconv-closure-convert-rec): Don't bother with defs-are-legal. | ||
| 7 | Use :fun-body to handle special forms that require closing their forms. | ||
| 8 | |||
| 9 | * emacs-lisp/bytecomp.el (byte-compile-file-form, byte-compile): | ||
| 10 | Use cconv-closure-convert instead of cconv-closure-convert-toplevel. | ||
| 11 | (byte-compile-lambda, byte-compile-make-closure): | ||
| 12 | * emacs-lisp/byte-lexbind.el (byte-compile-maybe-push-heap-environment): | ||
| 13 | Make sure cconv did its job. | ||
| 14 | |||
| 15 | * emacs-lisp/byte-opt.el (byte-optimize-lapcode): Check stack-depth | ||
| 16 | before using it. | ||
| 17 | |||
| 18 | * dired.el (dired-desktop-buffer-misc-data): Don't use a dynamic var as | ||
| 19 | function argument. | ||
| 20 | |||
| 21 | 2011-02-11 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 22 | |||
| 3 | * emacs-lisp/bytecomp.el (byte-compile-lambda): Fix `fun' that was not | 23 | * emacs-lisp/bytecomp.el (byte-compile-lambda): Fix `fun' that was not |
| 4 | renamed to `bytecomp-fun'. | 24 | renamed to `bytecomp-fun'. |
| 5 | 25 | ||
diff --git a/lisp/dired.el b/lisp/dired.el index f98ad641fe3..92cbdd32c8d 100644 --- a/lisp/dired.el +++ b/lisp/dired.el | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | ;;; -*- lexical-binding: t -*- | 1 | ;;; dired.el --- directory-browsing commands -*- lexical-binding: t -*- |
| 2 | ;;; dired.el --- directory-browsing commands | ||
| 3 | 2 | ||
| 4 | ;; Copyright (C) 1985-1986, 1992-1997, 2000-2011 | 3 | ;; Copyright (C) 1985-1986, 1992-1997, 2000-2011 |
| 5 | ;; Free Software Foundation, Inc. | 4 | ;; Free Software Foundation, Inc. |
| @@ -3507,21 +3506,21 @@ Ask means pop up a menu for the user to select one of copy, move or link." | |||
| 3507 | 3506 | ||
| 3508 | (eval-when-compile (require 'desktop)) | 3507 | (eval-when-compile (require 'desktop)) |
| 3509 | 3508 | ||
| 3510 | (defun dired-desktop-buffer-misc-data (desktop-dirname) | 3509 | (defun dired-desktop-buffer-misc-data (dirname) |
| 3511 | "Auxiliary information to be saved in desktop file." | 3510 | "Auxiliary information to be saved in desktop file." |
| 3512 | (cons | 3511 | (cons |
| 3513 | ;; Value of `dired-directory'. | 3512 | ;; Value of `dired-directory'. |
| 3514 | (if (consp dired-directory) | 3513 | (if (consp dired-directory) |
| 3515 | ;; Directory name followed by list of files. | 3514 | ;; Directory name followed by list of files. |
| 3516 | (cons (desktop-file-name (car dired-directory) desktop-dirname) | 3515 | (cons (desktop-file-name (car dired-directory) dirname) |
| 3517 | (cdr dired-directory)) | 3516 | (cdr dired-directory)) |
| 3518 | ;; Directory name, optionally with shell wildcard. | 3517 | ;; Directory name, optionally with shell wildcard. |
| 3519 | (desktop-file-name dired-directory desktop-dirname)) | 3518 | (desktop-file-name dired-directory dirname)) |
| 3520 | ;; Subdirectories in `dired-subdir-alist'. | 3519 | ;; Subdirectories in `dired-subdir-alist'. |
| 3521 | (cdr | 3520 | (cdr |
| 3522 | (nreverse | 3521 | (nreverse |
| 3523 | (mapcar | 3522 | (mapcar |
| 3524 | (function (lambda (f) (desktop-file-name (car f) desktop-dirname))) | 3523 | (function (lambda (f) (desktop-file-name (car f) dirname))) |
| 3525 | dired-subdir-alist))))) | 3524 | dired-subdir-alist))))) |
| 3526 | 3525 | ||
| 3527 | (defun dired-restore-desktop-buffer (desktop-buffer-file-name | 3526 | (defun dired-restore-desktop-buffer (desktop-buffer-file-name |
diff --git a/lisp/emacs-lisp/byte-lexbind.el b/lisp/emacs-lisp/byte-lexbind.el index 313c4b6ad0f..06353e2eea8 100644 --- a/lisp/emacs-lisp/byte-lexbind.el +++ b/lisp/emacs-lisp/byte-lexbind.el | |||
| @@ -585,6 +585,7 @@ proper scope)." | |||
| 585 | (= nclosures byte-compile-current-num-closures)) | 585 | (= nclosures byte-compile-current-num-closures)) |
| 586 | ;; No need to push a heap environment. | 586 | ;; No need to push a heap environment. |
| 587 | nil | 587 | nil |
| 588 | (error "Should have been handled by cconv") | ||
| 588 | ;; Have to push one. A heap environment is really just a vector, so | 589 | ;; Have to push one. A heap environment is really just a vector, so |
| 589 | ;; we emit bytecodes to create a vector. However, the size is not | 590 | ;; we emit bytecodes to create a vector. However, the size is not |
| 590 | ;; fixed yet (the vector can grow if subforms use it to store | 591 | ;; fixed yet (the vector can grow if subforms use it to store |
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 02107b0e11f..97ed6a01c2f 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -1863,7 +1863,7 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | |||
| 1863 | ;; | 1863 | ;; |
| 1864 | ;; stack-ref-N --> dup ; where N is TOS | 1864 | ;; stack-ref-N --> dup ; where N is TOS |
| 1865 | ;; | 1865 | ;; |
| 1866 | ((and (eq (car lap0) 'byte-stack-ref) | 1866 | ((and stack-depth (eq (car lap0) 'byte-stack-ref) |
| 1867 | (= (cdr lap0) (1- stack-depth))) | 1867 | (= (cdr lap0) (1- stack-depth))) |
| 1868 | (setcar lap0 'byte-dup) | 1868 | (setcar lap0 'byte-dup) |
| 1869 | (setcdr lap0 nil) | 1869 | (setcdr lap0 nil) |
| @@ -2093,7 +2093,8 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | |||
| 2093 | ;; stack-set-M [discard/discardN ...] --> discardN-preserve-tos | 2093 | ;; stack-set-M [discard/discardN ...] --> discardN-preserve-tos |
| 2094 | ;; stack-set-M [discard/discardN ...] --> discardN | 2094 | ;; stack-set-M [discard/discardN ...] --> discardN |
| 2095 | ;; | 2095 | ;; |
| 2096 | ((and (eq (car lap0) 'byte-stack-set) | 2096 | ((and stack-depth ;Make sure we know the stack depth. |
| 2097 | (eq (car lap0) 'byte-stack-set) | ||
| 2097 | (memq (car lap1) '(byte-discard byte-discardN)) | 2098 | (memq (car lap1) '(byte-discard byte-discardN)) |
| 2098 | (progn | 2099 | (progn |
| 2099 | ;; See if enough discard operations follow to expose or | 2100 | ;; See if enough discard operations follow to expose or |
| @@ -2161,7 +2162,8 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | |||
| 2161 | ;; dup return --> return | 2162 | ;; dup return --> return |
| 2162 | ;; stack-set-N return --> return ; where N is TOS-1 | 2163 | ;; stack-set-N return --> return ; where N is TOS-1 |
| 2163 | ;; | 2164 | ;; |
| 2164 | ((and (eq (car lap1) 'byte-return) | 2165 | ((and stack-depth ;Make sure we know the stack depth. |
| 2166 | (eq (car lap1) 'byte-return) | ||
| 2165 | (or (memq (car lap0) '(byte-discardN-preserve-tos byte-dup)) | 2167 | (or (memq (car lap0) '(byte-discardN-preserve-tos byte-dup)) |
| 2166 | (and (eq (car lap0) 'byte-stack-set) | 2168 | (and (eq (car lap0) 'byte-stack-set) |
| 2167 | (= (cdr lap0) (- stack-depth 2))))) | 2169 | (= (cdr lap0) (- stack-depth 2))))) |
| @@ -2174,7 +2176,8 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | |||
| 2174 | ;; | 2176 | ;; |
| 2175 | ;; dup stack-set-N return --> return ; where N is TOS | 2177 | ;; dup stack-set-N return --> return ; where N is TOS |
| 2176 | ;; | 2178 | ;; |
| 2177 | ((and (eq (car lap0) 'byte-dup) | 2179 | ((and stack-depth ;Make sure we know the stack depth. |
| 2180 | (eq (car lap0) 'byte-dup) | ||
| 2178 | (eq (car lap1) 'byte-stack-set) | 2181 | (eq (car lap1) 'byte-stack-set) |
| 2179 | (eq (car (car (cdr (cdr rest)))) 'byte-return) | 2182 | (eq (car (car (cdr (cdr rest)))) 'byte-return) |
| 2180 | (= (cdr lap1) (1- stack-depth))) | 2183 | (= (cdr lap1) (1- stack-depth))) |
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index f37d7489e9a..33940ec160e 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -134,7 +134,7 @@ | |||
| 134 | ;; `eval-when-compile' is defined in byte-run.el, so it must come after the | 134 | ;; `eval-when-compile' is defined in byte-run.el, so it must come after the |
| 135 | ;; preceding load expression. | 135 | ;; preceding load expression. |
| 136 | (provide 'bytecomp-preload) | 136 | (provide 'bytecomp-preload) |
| 137 | (eval-when-compile (require 'byte-lexbind)) | 137 | (eval-when-compile (require 'byte-lexbind nil 'noerror)) |
| 138 | 138 | ||
| 139 | ;; The feature of compiling in a specific target Emacs version | 139 | ;; The feature of compiling in a specific target Emacs version |
| 140 | ;; has been turned off because compile time options are a bad idea. | 140 | ;; has been turned off because compile time options are a bad idea. |
| @@ -2240,7 +2240,7 @@ list that represents a doc string reference. | |||
| 2240 | bytecomp-handler) | 2240 | bytecomp-handler) |
| 2241 | (setq form (macroexpand-all form byte-compile-macro-environment)) | 2241 | (setq form (macroexpand-all form byte-compile-macro-environment)) |
| 2242 | (if lexical-binding | 2242 | (if lexical-binding |
| 2243 | (setq form (cconv-closure-convert-toplevel form))) | 2243 | (setq form (cconv-closure-convert form))) |
| 2244 | (cond ((not (consp form)) | 2244 | (cond ((not (consp form)) |
| 2245 | (byte-compile-keep-pending form)) | 2245 | (byte-compile-keep-pending form)) |
| 2246 | ((and (symbolp (car form)) | 2246 | ((and (symbolp (car form)) |
| @@ -2592,7 +2592,7 @@ If FORM is a lambda or a macro, byte-compile it as a function." | |||
| 2592 | (macroexpand-all fun | 2592 | (macroexpand-all fun |
| 2593 | byte-compile-initial-macro-environment)) | 2593 | byte-compile-initial-macro-environment)) |
| 2594 | (if lexical-binding | 2594 | (if lexical-binding |
| 2595 | (setq fun (cconv-closure-convert-toplevel fun))) | 2595 | (setq fun (cconv-closure-convert fun))) |
| 2596 | ;; get rid of the `function' quote added by the `lambda' macro | 2596 | ;; get rid of the `function' quote added by the `lambda' macro |
| 2597 | (setq fun (cadr fun)) | 2597 | (setq fun (cadr fun)) |
| 2598 | (setq fun (if macro | 2598 | (setq fun (if macro |
| @@ -2753,7 +2753,8 @@ If FORM is a lambda or a macro, byte-compile it as a function." | |||
| 2753 | ;; containing lexical environment are closed over). | 2753 | ;; containing lexical environment are closed over). |
| 2754 | (and lexical-binding | 2754 | (and lexical-binding |
| 2755 | (byte-compile-closure-initial-lexenv-p | 2755 | (byte-compile-closure-initial-lexenv-p |
| 2756 | byte-compile-lexical-environment))) | 2756 | byte-compile-lexical-environment) |
| 2757 | (error "Should have been handled by cconv"))) | ||
| 2757 | (byte-compile-current-heap-environment nil) | 2758 | (byte-compile-current-heap-environment nil) |
| 2758 | (byte-compile-current-num-closures 0) | 2759 | (byte-compile-current-num-closures 0) |
| 2759 | (compiled | 2760 | (compiled |
| @@ -2791,6 +2792,7 @@ If FORM is a lambda or a macro, byte-compile it as a function." | |||
| 2791 | (eq (car-safe code) 'closure)) | 2792 | (eq (car-safe code) 'closure)) |
| 2792 | 2793 | ||
| 2793 | (defun byte-compile-make-closure (code) | 2794 | (defun byte-compile-make-closure (code) |
| 2795 | (error "Should have been handled by cconv") | ||
| 2794 | ;; A real closure requires that the constant be curried with an | 2796 | ;; A real closure requires that the constant be curried with an |
| 2795 | ;; environment vector to make a closure object. | 2797 | ;; environment vector to make a closure object. |
| 2796 | (if for-effect | 2798 | (if for-effect |
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index af42a2864c9..efb9d061b5c 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el | |||
| @@ -87,7 +87,9 @@ Each candidate has the form (VAR INCLOSURE BINDER PARENTFORM).") | |||
| 87 | 87 | ||
| 88 | (defun cconv-not-lexical-var-p (var) | 88 | (defun cconv-not-lexical-var-p (var) |
| 89 | (or (not (symbolp var)) ; form is not a list | 89 | (or (not (symbolp var)) ; form is not a list |
| 90 | (special-variable-p var) | 90 | (if (eval-when-compile (fboundp 'special-variable-p)) |
| 91 | (special-variable-p var) | ||
| 92 | (boundp var)) | ||
| 91 | ;; byte-compile-bound-variables normally holds both the | 93 | ;; byte-compile-bound-variables normally holds both the |
| 92 | ;; dynamic and lexical vars, but the bytecomp.el should | 94 | ;; dynamic and lexical vars, but the bytecomp.el should |
| 93 | ;; only call us at the top-level so there shouldn't be | 95 | ;; only call us at the top-level so there shouldn't be |
| @@ -192,14 +194,8 @@ Returns a list of free variables." | |||
| 192 | (cons form fvrs))))) | 194 | (cons form fvrs))))) |
| 193 | 195 | ||
| 194 | ;;;###autoload | 196 | ;;;###autoload |
| 195 | (defun cconv-closure-convert (form &optional toplevel) | 197 | (defun cconv-closure-convert (form) |
| 196 | ;; cconv-closure-convert-rec has a lot of parameters that are | 198 | "Main entry point for closure conversion. |
| 197 | ;; whether useless for user, whether they should contain | ||
| 198 | ;; specific data like a list of closure mutables or the list | ||
| 199 | ;; of lambdas suitable for lifting. | ||
| 200 | ;; | ||
| 201 | ;; That's why this function exists. | ||
| 202 | "Main entry point for non-toplevel forms. | ||
| 203 | -- FORM is a piece of Elisp code after macroexpansion. | 199 | -- FORM is a piece of Elisp code after macroexpansion. |
| 204 | -- TOPLEVEL(optional) is a boolean variable, true if we are at the root of AST | 200 | -- TOPLEVEL(optional) is a boolean variable, true if we are at the root of AST |
| 205 | 201 | ||
| @@ -221,19 +217,21 @@ Returns a form where all lambdas don't have any free variables." | |||
| 221 | '() ; fvrs initially empty | 217 | '() ; fvrs initially empty |
| 222 | '() ; envs initially empty | 218 | '() ; envs initially empty |
| 223 | '() | 219 | '() |
| 224 | toplevel))) ; true if the tree is a toplevel form | 220 | ))) |
| 225 | 221 | ||
| 226 | ;;;###autoload | 222 | (defun cconv-lookup-let (table var binder form) |
| 227 | (defun cconv-closure-convert-toplevel (form) | 223 | (let ((res nil)) |
| 228 | "Entry point for toplevel forms. | 224 | (dolist (elem table) |
| 229 | -- FORM is a piece of Elisp code after macroexpansion. | 225 | (when (and (eq (nth 2 elem) binder) |
| 226 | (eq (nth 3 elem) form)) | ||
| 227 | (assert (eq (car elem) var)) | ||
| 228 | (setq res elem))) | ||
| 229 | res)) | ||
| 230 | 230 | ||
| 231 | Returns a form where all lambdas don't have any free variables." | 231 | (defconst cconv--dummy-var (make-symbol "ignored")) |
| 232 | ;; we distinguish toplevel forms to treat def(un|var|const) correctly. | ||
| 233 | (cconv-closure-convert form t)) | ||
| 234 | 232 | ||
| 235 | (defun cconv-closure-convert-rec | 233 | (defun cconv-closure-convert-rec |
| 236 | (form emvrs fvrs envs lmenvs defs-are-legal) | 234 | (form emvrs fvrs envs lmenvs) |
| 237 | ;; This function actually rewrites the tree. | 235 | ;; This function actually rewrites the tree. |
| 238 | "Eliminates all free variables of all lambdas in given forms. | 236 | "Eliminates all free variables of all lambdas in given forms. |
| 239 | Arguments: | 237 | Arguments: |
| @@ -245,8 +243,6 @@ within current environment. | |||
| 245 | Initially empty. | 243 | Initially empty. |
| 246 | -- FVRS is a list of variables to substitute in each context. | 244 | -- FVRS is a list of variables to substitute in each context. |
| 247 | Initially empty. | 245 | Initially empty. |
| 248 | -- DEFS-ARE-LEGAL is a boolean variable, true if def(un|var|const) | ||
| 249 | can be used in this form(e.g. toplevel form) | ||
| 250 | 246 | ||
| 251 | Returns a form where all lambdas don't have any free variables." | 247 | Returns a form where all lambdas don't have any free variables." |
| 252 | ;; What's the difference between fvrs and envs? | 248 | ;; What's the difference between fvrs and envs? |
| @@ -261,11 +257,11 @@ Returns a form where all lambdas don't have any free variables." | |||
| 261 | ;; so we never touch it(unless we enter to the other closure). | 257 | ;; so we never touch it(unless we enter to the other closure). |
| 262 | ;;(if (listp form) (print (car form)) form) | 258 | ;;(if (listp form) (print (car form)) form) |
| 263 | (pcase form | 259 | (pcase form |
| 264 | (`(,(and letsym (or `let* `let)) ,varsvalues . ,body-forms) | 260 | (`(,(and letsym (or `let* `let)) ,binders . ,body-forms) |
| 265 | 261 | ||
| 266 | ; let and let* special forms | 262 | ; let and let* special forms |
| 267 | (let ((body-forms-new '()) | 263 | (let ((body-forms-new '()) |
| 268 | (varsvalues-new '()) | 264 | (binders-new '()) |
| 269 | ;; next for variables needed for delayed push | 265 | ;; next for variables needed for delayed push |
| 270 | ;; because we should process <value(s)> | 266 | ;; because we should process <value(s)> |
| 271 | ;; before we change any arguments | 267 | ;; before we change any arguments |
| @@ -274,83 +270,58 @@ Returns a form where all lambdas don't have any free variables." | |||
| 274 | (emvr-push) ;needed only in case of let* | 270 | (emvr-push) ;needed only in case of let* |
| 275 | (lmenv-push)) ;needed only in case of let* | 271 | (lmenv-push)) ;needed only in case of let* |
| 276 | 272 | ||
| 277 | (dolist (elm varsvalues) ;begin of dolist over varsvalues | 273 | (dolist (binder binders) |
| 278 | (let (var value elm-new iscandidate ismutated) | 274 | (let* ((value nil) |
| 279 | (if (consp elm) ; (let (v1) ...) => (let ((v1 nil)) ...) | 275 | (var (if (not (consp binder)) |
| 280 | (progn | 276 | binder |
| 281 | (setq var (car elm)) | 277 | (setq value (cadr binder)) |
| 282 | (setq value (cadr elm))) | 278 | (car binder))) |
| 283 | (setq var elm)) | 279 | (new-val |
| 284 | 280 | (cond | |
| 285 | ;; Check if var is a candidate for lambda lifting | 281 | ;; Check if var is a candidate for lambda lifting. |
| 286 | (let ((lcandid cconv-lambda-candidates)) | 282 | ((cconv-lookup-let cconv-lambda-candidates var binder form) |
| 287 | (while (and lcandid (not iscandidate)) | 283 | |
| 288 | (when (and (eq (caar lcandid) var) | 284 | (let* ((fv (delete-dups (cconv-freevars value '()))) |
| 289 | (eq (caddar lcandid) elm) | 285 | (funargs (cadr (cadr value))) |
| 290 | (eq (cadr (cddar lcandid)) form)) | 286 | (funcvars (append fv funargs)) |
| 291 | (setq iscandidate t)) | 287 | (funcbodies (cddadr value)) ; function bodies |
| 292 | (setq lcandid (cdr lcandid)))) | 288 | (funcbodies-new '())) |
| 293 | |||
| 294 | ; declared variable is a candidate | ||
| 295 | ; for lambda lifting | ||
| 296 | (if iscandidate | ||
| 297 | (let* ((func (cadr elm)) ; function(lambda) itself | ||
| 298 | ; free variables | ||
| 299 | (fv (delete-dups (cconv-freevars func '()))) | ||
| 300 | (funcvars (append fv (cadadr func))) ;function args | ||
| 301 | (funcbodies (cddadr func)) ; function bodies | ||
| 302 | (funcbodies-new '())) | ||
| 303 | ; lambda lifting condition | 289 | ; lambda lifting condition |
| 304 | (if (or (not fv) (< cconv-liftwhen (length funcvars))) | 290 | (if (or (not fv) (< cconv-liftwhen (length funcvars))) |
| 305 | ; do not lift | 291 | ; do not lift |
| 306 | (setq | 292 | (cconv-closure-convert-rec |
| 307 | elm-new | 293 | value emvrs fvrs envs lmenvs) |
| 308 | `(,var | ||
| 309 | ,(cconv-closure-convert-rec | ||
| 310 | func emvrs fvrs envs lmenvs nil))) | ||
| 311 | ; lift | 294 | ; lift |
| 312 | (progn | 295 | (progn |
| 313 | (dolist (elm2 funcbodies) | 296 | (dolist (elm2 funcbodies) |
| 314 | (push ; convert function bodies | 297 | (push ; convert function bodies |
| 315 | (cconv-closure-convert-rec | 298 | (cconv-closure-convert-rec |
| 316 | elm2 emvrs nil envs lmenvs nil) | 299 | elm2 emvrs nil envs lmenvs) |
| 317 | funcbodies-new)) | 300 | funcbodies-new)) |
| 318 | (if (eq letsym 'let*) | 301 | (if (eq letsym 'let*) |
| 319 | (setq lmenv-push (cons var fv)) | 302 | (setq lmenv-push (cons var fv)) |
| 320 | (push (cons var fv) lmenvs-new)) | 303 | (push (cons var fv) lmenvs-new)) |
| 321 | ; push lifted function | 304 | ; push lifted function |
| 322 | 305 | ||
| 323 | (setq elm-new | 306 | `(function . |
| 324 | `(,var | 307 | ((lambda ,funcvars . |
| 325 | (function . | 308 | ,(reverse funcbodies-new)))))))) |
| 326 | ((lambda ,funcvars . | 309 | |
| 327 | ,(reverse funcbodies-new))))))))) | 310 | ;; Check if it needs to be turned into a "ref-cell". |
| 328 | 311 | ((cconv-lookup-let cconv-captured+mutated var binder form) | |
| 329 | ;declared variable is not a function | 312 | ;; Declared variable is mutated and captured. |
| 330 | (progn | 313 | (prog1 |
| 331 | ;; Check if var is mutated | 314 | `(list ,(cconv-closure-convert-rec |
| 332 | (let ((lmutated cconv-captured+mutated)) | 315 | value emvrs |
| 333 | (while (and lmutated (not ismutated)) | 316 | fvrs envs lmenvs)) |
| 334 | (when (and (eq (caar lmutated) var) | ||
| 335 | (eq (caddar lmutated) elm) | ||
| 336 | (eq (cadr (cddar lmutated)) form)) | ||
| 337 | (setq ismutated t)) | ||
| 338 | (setq lmutated (cdr lmutated)))) | ||
| 339 | (if ismutated | ||
| 340 | (progn ; declared variable is mutated | ||
| 341 | (setq elm-new | ||
| 342 | `(,var (list ,(cconv-closure-convert-rec | ||
| 343 | value emvrs | ||
| 344 | fvrs envs lmenvs nil)))) | ||
| 345 | (if (eq letsym 'let*) | 317 | (if (eq letsym 'let*) |
| 346 | (setq emvr-push var) | 318 | (setq emvr-push var) |
| 347 | (push var emvrs-new))) | 319 | (push var emvrs-new)))) |
| 348 | (progn | 320 | |
| 349 | (setq | 321 | ;; Normal default case. |
| 350 | elm-new | 322 | (t |
| 351 | `(,var ; else | 323 | (cconv-closure-convert-rec |
| 352 | ,(cconv-closure-convert-rec | 324 | value emvrs fvrs envs lmenvs))))) |
| 353 | value emvrs fvrs envs lmenvs nil))))))) | ||
| 354 | 325 | ||
| 355 | ;; this piece of code below letbinds free | 326 | ;; this piece of code below letbinds free |
| 356 | ;; variables of a lambda lifted function | 327 | ;; variables of a lambda lifted function |
| @@ -384,12 +355,12 @@ Returns a form where all lambdas don't have any free variables." | |||
| 384 | (when new-lmenv | 355 | (when new-lmenv |
| 385 | (setq lmenvs (remq old-lmenv lmenvs)) | 356 | (setq lmenvs (remq old-lmenv lmenvs)) |
| 386 | (push new-lmenv lmenvs) | 357 | (push new-lmenv lmenvs) |
| 387 | (push `(,closedsym ,var) varsvalues-new)))) | 358 | (push `(,closedsym ,var) binders-new)))) |
| 388 | ;; we push the element after redefined free variables | 359 | ;; we push the element after redefined free variables |
| 389 | ;; are processes. this is important to avoid the bug | 360 | ;; are processes. this is important to avoid the bug |
| 390 | ;; when free variable and the function have the same | 361 | ;; when free variable and the function have the same |
| 391 | ;; name | 362 | ;; name |
| 392 | (push elm-new varsvalues-new) | 363 | (push (list var new-val) binders-new) |
| 393 | 364 | ||
| 394 | (when (eq letsym 'let*) ; update fvrs | 365 | (when (eq letsym 'let*) ; update fvrs |
| 395 | (setq fvrs (remq var fvrs)) | 366 | (setq fvrs (remq var fvrs)) |
| @@ -405,23 +376,23 @@ Returns a form where all lambdas don't have any free variables." | |||
| 405 | (when lmenv-push | 376 | (when lmenv-push |
| 406 | (push lmenv-push lmenvs) | 377 | (push lmenv-push lmenvs) |
| 407 | (setq lmenv-push nil))) | 378 | (setq lmenv-push nil))) |
| 408 | )) ; end of dolist over varsvalues | 379 | )) ; end of dolist over binders |
| 409 | (when (eq letsym 'let) | 380 | (when (eq letsym 'let) |
| 410 | 381 | ||
| 411 | (let (var fvrs-1 emvrs-1 lmenvs-1) | 382 | (let (var fvrs-1 emvrs-1 lmenvs-1) |
| 412 | ;; Here we update emvrs, fvrs and lmenvs lists | 383 | ;; Here we update emvrs, fvrs and lmenvs lists |
| 413 | (dolist (vr fvrs) | 384 | (dolist (vr fvrs) |
| 414 | ; safely remove | 385 | ; safely remove |
| 415 | (when (not (assq vr varsvalues-new)) (push vr fvrs-1))) | 386 | (when (not (assq vr binders-new)) (push vr fvrs-1))) |
| 416 | (setq fvrs fvrs-1) | 387 | (setq fvrs fvrs-1) |
| 417 | (dolist (vr emvrs) | 388 | (dolist (vr emvrs) |
| 418 | ; safely remove | 389 | ; safely remove |
| 419 | (when (not (assq vr varsvalues-new)) (push vr emvrs-1))) | 390 | (when (not (assq vr binders-new)) (push vr emvrs-1))) |
| 420 | (setq emvrs emvrs-1) | 391 | (setq emvrs emvrs-1) |
| 421 | ; push new | 392 | ; push new |
| 422 | (setq emvrs (append emvrs emvrs-new)) | 393 | (setq emvrs (append emvrs emvrs-new)) |
| 423 | (dolist (vr lmenvs) | 394 | (dolist (vr lmenvs) |
| 424 | (when (not (assq (car vr) varsvalues-new)) | 395 | (when (not (assq (car vr) binders-new)) |
| 425 | (push vr lmenvs-1))) | 396 | (push vr lmenvs-1))) |
| 426 | (setq lmenvs (append lmenvs lmenvs-new))) | 397 | (setq lmenvs (append lmenvs lmenvs-new))) |
| 427 | 398 | ||
| @@ -432,10 +403,9 @@ Returns a form where all lambdas don't have any free variables." | |||
| 432 | (let ((new-lmenv) | 403 | (let ((new-lmenv) |
| 433 | (var nil) | 404 | (var nil) |
| 434 | (closedsym nil) | 405 | (closedsym nil) |
| 435 | (letbinds '()) | 406 | (letbinds '())) |
| 436 | (fvrs-new)) ; list of (closed-var var) | 407 | (dolist (binder binders) |
| 437 | (dolist (elm varsvalues) | 408 | (setq var (if (consp binder) (car binder) binder)) |
| 438 | (setq var (if (consp elm) (car elm) elm)) | ||
| 439 | 409 | ||
| 440 | (let ((lmenvs-1 lmenvs)) ; just to avoid manipulating | 410 | (let ((lmenvs-1 lmenvs)) ; just to avoid manipulating |
| 441 | (dolist (lmenv lmenvs-1) ; the counter inside the loop | 411 | (dolist (lmenv lmenvs-1) ; the counter inside the loop |
| @@ -453,13 +423,13 @@ Returns a form where all lambdas don't have any free variables." | |||
| 453 | (push new-lmenv lmenvs) | 423 | (push new-lmenv lmenvs) |
| 454 | (push `(,closedsym ,var) letbinds) | 424 | (push `(,closedsym ,var) letbinds) |
| 455 | )))) | 425 | )))) |
| 456 | (setq varsvalues-new (append varsvalues-new letbinds)))) | 426 | (setq binders-new (append binders-new letbinds)))) |
| 457 | 427 | ||
| 458 | (dolist (elm body-forms) ; convert body forms | 428 | (dolist (elm body-forms) ; convert body forms |
| 459 | (push (cconv-closure-convert-rec | 429 | (push (cconv-closure-convert-rec |
| 460 | elm emvrs fvrs envs lmenvs nil) | 430 | elm emvrs fvrs envs lmenvs) |
| 461 | body-forms-new)) | 431 | body-forms-new)) |
| 462 | `(,letsym ,(reverse varsvalues-new) . ,(reverse body-forms-new)))) | 432 | `(,letsym ,(reverse binders-new) . ,(reverse body-forms-new)))) |
| 463 | ;end of let let* forms | 433 | ;end of let let* forms |
| 464 | 434 | ||
| 465 | ; first element is lambda expression | 435 | ; first element is lambda expression |
| @@ -468,13 +438,12 @@ Returns a form where all lambdas don't have any free variables." | |||
| 468 | (let ((other-body-forms-new '())) | 438 | (let ((other-body-forms-new '())) |
| 469 | (dolist (elm other-body-forms) | 439 | (dolist (elm other-body-forms) |
| 470 | (push (cconv-closure-convert-rec | 440 | (push (cconv-closure-convert-rec |
| 471 | elm emvrs fvrs envs lmenvs nil) | 441 | elm emvrs fvrs envs lmenvs) |
| 472 | other-body-forms-new)) | 442 | other-body-forms-new)) |
| 473 | (cons | 443 | `(funcall |
| 474 | (cadr | 444 | ,(cconv-closure-convert-rec |
| 475 | (cconv-closure-convert-rec | 445 | (list 'function fun) emvrs fvrs envs lmenvs) |
| 476 | (list 'function fun) emvrs fvrs envs lmenvs nil)) | 446 | ,@(nreverse other-body-forms-new)))) |
| 477 | (reverse other-body-forms-new)))) | ||
| 478 | 447 | ||
| 479 | (`(cond . ,cond-forms) ; cond special form | 448 | (`(cond . ,cond-forms) ; cond special form |
| 480 | (let ((cond-forms-new '())) | 449 | (let ((cond-forms-new '())) |
| @@ -483,7 +452,7 @@ Returns a form where all lambdas don't have any free variables." | |||
| 483 | (dolist (elm-2 elm) | 452 | (dolist (elm-2 elm) |
| 484 | (push | 453 | (push |
| 485 | (cconv-closure-convert-rec | 454 | (cconv-closure-convert-rec |
| 486 | elm-2 emvrs fvrs envs lmenvs nil) | 455 | elm-2 emvrs fvrs envs lmenvs) |
| 487 | elm-new)) | 456 | elm-new)) |
| 488 | (reverse elm-new)) | 457 | (reverse elm-new)) |
| 489 | cond-forms-new)) | 458 | cond-forms-new)) |
| @@ -523,7 +492,7 @@ Returns a form where all lambdas don't have any free variables." | |||
| 523 | (dolist (elm fv) | 492 | (dolist (elm fv) |
| 524 | (push | 493 | (push |
| 525 | (cconv-closure-convert-rec | 494 | (cconv-closure-convert-rec |
| 526 | elm (remq elm emvrs) fvrs envs lmenvs nil) | 495 | elm (remq elm emvrs) fvrs envs lmenvs) |
| 527 | envector)) ; process vars for closure vector | 496 | envector)) ; process vars for closure vector |
| 528 | (setq envector (reverse envector)) | 497 | (setq envector (reverse envector)) |
| 529 | (setq envs fv)) | 498 | (setq envs fv)) |
| @@ -539,7 +508,7 @@ Returns a form where all lambdas don't have any free variables." | |||
| 539 | (push `(,mv (list ,mv)) letbind)))) | 508 | (push `(,mv (list ,mv)) letbind)))) |
| 540 | (dolist (elm body-forms) ; convert function body | 509 | (dolist (elm body-forms) ; convert function body |
| 541 | (push (cconv-closure-convert-rec | 510 | (push (cconv-closure-convert-rec |
| 542 | elm emvrs fvrs envs lmenvs nil) | 511 | elm emvrs fvrs envs lmenvs) |
| 543 | body-forms-new)) | 512 | body-forms-new)) |
| 544 | 513 | ||
| 545 | (setq body-forms-new | 514 | (setq body-forms-new |
| @@ -566,83 +535,89 @@ Returns a form where all lambdas don't have any free variables." | |||
| 566 | ;defconst, defvar | 535 | ;defconst, defvar |
| 567 | (`(,(and sym (or `defconst `defvar)) ,definedsymbol . ,body-forms) | 536 | (`(,(and sym (or `defconst `defvar)) ,definedsymbol . ,body-forms) |
| 568 | 537 | ||
| 569 | (if defs-are-legal | 538 | (let ((body-forms-new '())) |
| 570 | (let ((body-forms-new '())) | 539 | (dolist (elm body-forms) |
| 571 | (dolist (elm body-forms) | 540 | (push (cconv-closure-convert-rec |
| 572 | (push (cconv-closure-convert-rec | 541 | elm emvrs fvrs envs lmenvs) |
| 573 | elm emvrs fvrs envs lmenvs nil) | 542 | body-forms-new)) |
| 574 | body-forms-new)) | 543 | (setq body-forms-new (reverse body-forms-new)) |
| 575 | (setq body-forms-new (reverse body-forms-new)) | 544 | `(,sym ,definedsymbol . ,body-forms-new))) |
| 576 | `(,sym ,definedsymbol . ,body-forms-new)) | ||
| 577 | (error "Invalid form: %s inside a function" sym))) | ||
| 578 | 545 | ||
| 579 | ;defun, defmacro | 546 | ;defun, defmacro |
| 580 | (`(,(and sym (or `defun `defmacro)) | 547 | (`(,(and sym (or `defun `defmacro)) |
| 581 | ,func ,vars . ,body-forms) | 548 | ,func ,vars . ,body-forms) |
| 582 | (if defs-are-legal | 549 | (let ((body-new '()) ; the whole body |
| 583 | (let ((body-new '()) ; the whole body | 550 | (body-forms-new '()) ; body w\o docstring and interactive |
| 584 | (body-forms-new '()) ; body w\o docstring and interactive | 551 | (letbind '())) |
| 585 | (letbind '())) | ||
| 586 | ; find mutable arguments | 552 | ; find mutable arguments |
| 587 | (let ((lmutated cconv-captured+mutated) ismutated) | 553 | (let ((lmutated cconv-captured+mutated) ismutated) |
| 588 | (dolist (elm vars) | 554 | (dolist (elm vars) |
| 589 | (setq ismutated nil) | 555 | (setq ismutated nil) |
| 590 | (while (and lmutated (not ismutated)) | 556 | (while (and lmutated (not ismutated)) |
| 591 | (when (and (eq (caar lmutated) elm) | 557 | (when (and (eq (caar lmutated) elm) |
| 592 | (eq (cadar lmutated) form)) | 558 | (eq (cadar lmutated) form)) |
| 593 | (setq ismutated t)) | 559 | (setq ismutated t)) |
| 594 | (setq lmutated (cdr lmutated))) | 560 | (setq lmutated (cdr lmutated))) |
| 595 | (when ismutated | 561 | (when ismutated |
| 596 | (push elm letbind) | 562 | (push elm letbind) |
| 597 | (push elm emvrs)))) | 563 | (push elm emvrs)))) |
| 598 | ;transform body-forms | 564 | ;transform body-forms |
| 599 | (when (stringp (car body-forms)) ; treat docstring well | 565 | (when (stringp (car body-forms)) ; treat docstring well |
| 600 | (push (car body-forms) body-new) | 566 | (push (car body-forms) body-new) |
| 601 | (setq body-forms (cdr body-forms))) | 567 | (setq body-forms (cdr body-forms))) |
| 602 | (when (eq (car-safe (car body-forms)) 'interactive) | 568 | (when (eq (car-safe (car body-forms)) 'interactive) |
| 603 | (push | 569 | (push (cconv-closure-convert-rec |
| 604 | (cconv-closure-convert-rec | 570 | (car body-forms) |
| 605 | (car body-forms) | 571 | emvrs fvrs envs lmenvs) |
| 606 | emvrs fvrs envs lmenvs nil) body-new) | 572 | body-new) |
| 607 | (setq body-forms (cdr body-forms))) | 573 | (setq body-forms (cdr body-forms))) |
| 608 | 574 | ||
| 609 | (dolist (elm body-forms) | 575 | (dolist (elm body-forms) |
| 610 | (push (cconv-closure-convert-rec | 576 | (push (cconv-closure-convert-rec |
| 611 | elm emvrs fvrs envs lmenvs nil) | 577 | elm emvrs fvrs envs lmenvs) |
| 612 | body-forms-new)) | 578 | body-forms-new)) |
| 613 | (setq body-forms-new (reverse body-forms-new)) | 579 | (setq body-forms-new (reverse body-forms-new)) |
| 614 | 580 | ||
| 615 | (if letbind | 581 | (if letbind |
| 616 | ; letbind mutable arguments | 582 | ; letbind mutable arguments |
| 617 | (let ((varsvalues-new '())) | 583 | (let ((binders-new '())) |
| 618 | (dolist (elm letbind) (push `(,elm (list ,elm)) | 584 | (dolist (elm letbind) (push `(,elm (list ,elm)) |
| 619 | varsvalues-new)) | 585 | binders-new)) |
| 620 | (push `(let ,(reverse varsvalues-new) . | 586 | (push `(let ,(reverse binders-new) . |
| 621 | ,body-forms-new) body-new) | 587 | ,body-forms-new) body-new) |
| 622 | (setq body-new (reverse body-new))) | 588 | (setq body-new (reverse body-new))) |
| 623 | (setq body-new (append (reverse body-new) body-forms-new))) | 589 | (setq body-new (append (reverse body-new) body-forms-new))) |
| 624 | 590 | ||
| 625 | `(,sym ,func ,vars . ,body-new)) | 591 | `(,sym ,func ,vars . ,body-new))) |
| 626 | 592 | ||
| 627 | (error "Invalid form: defun inside a function"))) | ||
| 628 | ;condition-case | 593 | ;condition-case |
| 629 | (`(condition-case ,var ,protected-form . ,conditions-bodies) | 594 | (`(condition-case ,var ,protected-form . ,handlers) |
| 630 | (let ((conditions-bodies-new '())) | 595 | (let ((handlers-new '()) |
| 596 | (newform (cconv-closure-convert-rec | ||
| 597 | `(function (lambda () ,protected-form)) | ||
| 598 | emvrs fvrs envs lmenvs))) | ||
| 631 | (setq fvrs (remq var fvrs)) | 599 | (setq fvrs (remq var fvrs)) |
| 632 | (dolist (elm conditions-bodies) | 600 | (dolist (handler handlers) |
| 633 | (push (let ((elm-new '())) | 601 | (push (list (car handler) |
| 634 | (dolist (elm-2 (cdr elm)) | 602 | (cconv-closure-convert-rec |
| 635 | (push | 603 | `(function (lambda (,(or var cconv--dummy-var)) |
| 636 | (cconv-closure-convert-rec | 604 | ,@(cdr handler))) |
| 637 | elm-2 emvrs fvrs envs lmenvs nil) | 605 | emvrs fvrs envs lmenvs)) |
| 638 | elm-new)) | 606 | handlers-new)) |
| 639 | (cons (car elm) (reverse elm-new))) | 607 | `(condition-case :fun-body ,newform |
| 640 | conditions-bodies-new)) | 608 | ,@(nreverse handlers-new)))) |
| 641 | `(condition-case | 609 | |
| 642 | ,var | 610 | (`(,(and head (or `catch `unwind-protect)) ,form . ,body) |
| 643 | ,(cconv-closure-convert-rec | 611 | `(,head ,(cconv-closure-convert-rec form emvrs fvrs envs lmenvs) |
| 644 | protected-form emvrs fvrs envs lmenvs nil) | 612 | :fun-body |
| 645 | . ,(reverse conditions-bodies-new)))) | 613 | ,(cconv-closure-convert-rec `(function (lambda () ,@body)) |
| 614 | emvrs fvrs envs lmenvs))) | ||
| 615 | |||
| 616 | (`(,(and head (or `save-window-excursion `track-mouse)) . ,body) | ||
| 617 | `(,head | ||
| 618 | :fun-body | ||
| 619 | ,(cconv-closure-convert-rec `(function (lambda () ,@body)) | ||
| 620 | emvrs fvrs envs lmenvs))) | ||
| 646 | 621 | ||
| 647 | (`(setq . ,forms) ; setq special form | 622 | (`(setq . ,forms) ; setq special form |
| 648 | (let (prognlist sym sym-new value) | 623 | (let (prognlist sym sym-new value) |
| @@ -650,10 +625,10 @@ Returns a form where all lambdas don't have any free variables." | |||
| 650 | (setq sym (car forms)) | 625 | (setq sym (car forms)) |
| 651 | (setq sym-new (cconv-closure-convert-rec | 626 | (setq sym-new (cconv-closure-convert-rec |
| 652 | sym | 627 | sym |
| 653 | (remq sym emvrs) fvrs envs lmenvs nil)) | 628 | (remq sym emvrs) fvrs envs lmenvs)) |
| 654 | (setq value | 629 | (setq value |
| 655 | (cconv-closure-convert-rec | 630 | (cconv-closure-convert-rec |
| 656 | (cadr forms) emvrs fvrs envs lmenvs nil)) | 631 | (cadr forms) emvrs fvrs envs lmenvs)) |
| 657 | (if (memq sym emvrs) | 632 | (if (memq sym emvrs) |
| 658 | (push `(setcar ,sym-new ,value) prognlist) | 633 | (push `(setcar ,sym-new ,value) prognlist) |
| 659 | (if (symbolp sym-new) | 634 | (if (symbolp sym-new) |
| @@ -678,21 +653,21 @@ Returns a form where all lambdas don't have any free variables." | |||
| 678 | (dolist (fvr fv) | 653 | (dolist (fvr fv) |
| 679 | (push (cconv-closure-convert-rec | 654 | (push (cconv-closure-convert-rec |
| 680 | fvr (remq fvr emvrs) | 655 | fvr (remq fvr emvrs) |
| 681 | fvrs envs lmenvs nil) | 656 | fvrs envs lmenvs) |
| 682 | processed-fv)) | 657 | processed-fv)) |
| 683 | (setq processed-fv (reverse processed-fv)) | 658 | (setq processed-fv (reverse processed-fv)) |
| 684 | (dolist (elm args) | 659 | (dolist (elm args) |
| 685 | (push (cconv-closure-convert-rec | 660 | (push (cconv-closure-convert-rec |
| 686 | elm emvrs fvrs envs lmenvs nil) | 661 | elm emvrs fvrs envs lmenvs) |
| 687 | args-new)) | 662 | args-new)) |
| 688 | (setq args-new (append processed-fv (reverse args-new))) | 663 | (setq args-new (append processed-fv (reverse args-new))) |
| 689 | (setq fun (cconv-closure-convert-rec | 664 | (setq fun (cconv-closure-convert-rec |
| 690 | fun emvrs fvrs envs lmenvs nil)) | 665 | fun emvrs fvrs envs lmenvs)) |
| 691 | `(,callsym ,fun . ,args-new)) | 666 | `(,callsym ,fun . ,args-new)) |
| 692 | (let ((cdr-new '())) | 667 | (let ((cdr-new '())) |
| 693 | (dolist (elm (cdr form)) | 668 | (dolist (elm (cdr form)) |
| 694 | (push (cconv-closure-convert-rec | 669 | (push (cconv-closure-convert-rec |
| 695 | elm emvrs fvrs envs lmenvs nil) | 670 | elm emvrs fvrs envs lmenvs) |
| 696 | cdr-new)) | 671 | cdr-new)) |
| 697 | `(,callsym . ,(reverse cdr-new)))))) | 672 | `(,callsym . ,(reverse cdr-new)))))) |
| 698 | 673 | ||
| @@ -703,7 +678,7 @@ Returns a form where all lambdas don't have any free variables." | |||
| 703 | (let ((body-forms-new '())) | 678 | (let ((body-forms-new '())) |
| 704 | (dolist (elm body-forms) | 679 | (dolist (elm body-forms) |
| 705 | (push (cconv-closure-convert-rec | 680 | (push (cconv-closure-convert-rec |
| 706 | elm emvrs fvrs envs lmenvs defs-are-legal) | 681 | elm emvrs fvrs envs lmenvs) |
| 707 | body-forms-new)) | 682 | body-forms-new)) |
| 708 | (setq body-forms-new (reverse body-forms-new)) | 683 | (setq body-forms-new (reverse body-forms-new)) |
| 709 | `(,func . ,body-forms-new))) | 684 | `(,func . ,body-forms-new))) |
diff --git a/lisp/mpc.el b/lisp/mpc.el index 4f21a162c08..548fd17d038 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | ;;; -*- lexical-binding: t -*- | 1 | ;;; mpc.el --- A client for the Music Player Daemon -*- coding: utf-8; lexical-binding: t -*- |
| 2 | ;;; mpc.el --- A client for the Music Player Daemon -*- coding: utf-8 -*- | ||
| 3 | 2 | ||
| 4 | ;; Copyright (C) 2006-2011 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2006-2011 Free Software Foundation, Inc. |
| 5 | 4 | ||