aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-03-30 14:40:00 -0400
committerStefan Monnier2011-03-30 14:40:00 -0400
commitf488fb6528738131ef41859e1f04125f2e50efce (patch)
treee064dd58457d2242e581544c3d43a0690ae403ab
parentebe0c9b6b02cfb328457156c25387c3e2b7ba961 (diff)
downloademacs-f488fb6528738131ef41859e1f04125f2e50efce.tar.gz
emacs-f488fb6528738131ef41859e1f04125f2e50efce.zip
* lisp/subr.el (apply-partially): Use a non-nil static environment.
(--dolist-tail--, --dotimes-limit--): Don't declare dynamically bound. (dolist): Use a more efficient form for lexical-binding. (dotimes): Use a cleaner semantics for lexical-binding. * lisp/emacs-lisp/edebug.el (edebug-eval-top-level-form): Use eval-sexp-add-defvars.
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/emacs-lisp/edebug.el3
-rw-r--r--lisp/subr.el65
-rw-r--r--src/lread.c1
4 files changed, 56 insertions, 23 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c1e12152f11..b517c48738f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12011-03-30 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * subr.el (apply-partially): Use a non-nil static environment.
4 (--dolist-tail--, --dotimes-limit--): Don't declare dynamically bound.
5 (dolist): Use a more efficient form for lexical-binding.
6 (dotimes): Use a cleaner semantics for lexical-binding.
7
8 * emacs-lisp/edebug.el (edebug-eval-top-level-form):
9 Use eval-sexp-add-defvars.
10
12011-03-30 Juanma Barranquero <lekktu@gmail.com> 112011-03-30 Juanma Barranquero <lekktu@gmail.com>
2 12
3 * makefile.w32-in (COMPILE_FIRST): Remove pcase. 13 * makefile.w32-in (COMPILE_FIRST): Remove pcase.
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index dfc268421e7..8135b5c4f24 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -566,7 +566,8 @@ already is one.)"
566 ;; but this causes problems while edebugging edebug. 566 ;; but this causes problems while edebugging edebug.
567 (let ((edebug-all-forms t) 567 (let ((edebug-all-forms t)
568 (edebug-all-defs t)) 568 (edebug-all-defs t))
569 (edebug-read-top-level-form)))) 569 (eval-sexp-add-defvars
570 (edebug-read-top-level-form)))))
570 571
571 572
572(defun edebug-read-top-level-form () 573(defun edebug-read-top-level-form ()
diff --git a/lisp/subr.el b/lisp/subr.el
index c5fedae2bfc..205828b4169 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -124,7 +124,7 @@ ARGS is a list of the first N arguments to pass to FUN.
124The result is a new function which does the same as FUN, except that 124The result is a new function which does the same as FUN, except that
125the first N arguments are fixed at the values with which this function 125the first N arguments are fixed at the values with which this function
126was called." 126was called."
127 `(closure () (&rest args) 127 `(closure (t) (&rest args)
128 (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args))) 128 (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args)))
129 129
130(if (null (featurep 'cl)) 130(if (null (featurep 'cl))
@@ -174,8 +174,6 @@ value of last one, or nil if there are none.
174 ;; If we reload subr.el after having loaded CL, be careful not to 174 ;; If we reload subr.el after having loaded CL, be careful not to
175 ;; overwrite CL's extended definition of `dolist', `dotimes', 175 ;; overwrite CL's extended definition of `dolist', `dotimes',
176 ;; `declare', `push' and `pop'. 176 ;; `declare', `push' and `pop'.
177(defvar --dolist-tail-- nil
178 "Temporary variable used in `dolist' expansion.")
179 177
180(defmacro dolist (spec &rest body) 178(defmacro dolist (spec &rest body)
181 "Loop over a list. 179 "Loop over a list.
@@ -189,19 +187,27 @@ Then evaluate RESULT to get return value, default nil.
189 ;; use dolist. 187 ;; use dolist.
190 ;; FIXME: This cost disappears in byte-compiled lexical-binding files. 188 ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
191 (let ((temp '--dolist-tail--)) 189 (let ((temp '--dolist-tail--))
192 `(let ((,temp ,(nth 1 spec)) 190 ;; This is not a reliable test, but it does not matter because both
193 ,(car spec)) 191 ;; semantics are acceptable, tho one is slightly faster with dynamic
194 (while ,temp 192 ;; scoping and the other is slightly faster (and has cleaner semantics)
195 ;; FIXME: In lexical-binding code, a `let' inside the loop might 193 ;; with lexical scoping.
196 ;; turn out to be faster than the an outside `let' this `setq'. 194 (if lexical-binding
197 (setq ,(car spec) (car ,temp)) 195 `(let ((,temp ,(nth 1 spec)))
198 ,@body 196 (while ,temp
199 (setq ,temp (cdr ,temp))) 197 (let ((,(car spec) (car ,temp)))
200 ,@(if (cdr (cdr spec)) 198 ,@body
201 `((setq ,(car spec) nil) ,@(cdr (cdr spec))))))) 199 (setq ,temp (cdr ,temp))))
202 200 ,@(if (cdr (cdr spec))
203(defvar --dotimes-limit-- nil 201 ;; FIXME: This let often leads to "unused var" warnings.
204 "Temporary variable used in `dotimes' expansion.") 202 `((let ((,(car spec) nil)) ,@(cdr (cdr spec))))))
203 `(let ((,temp ,(nth 1 spec))
204 ,(car spec))
205 (while ,temp
206 (setq ,(car spec) (car ,temp))
207 ,@body
208 (setq ,temp (cdr ,temp)))
209 ,@(if (cdr (cdr spec))
210 `((setq ,(car spec) nil) ,@(cdr (cdr spec))))))))
205 211
206(defmacro dotimes (spec &rest body) 212(defmacro dotimes (spec &rest body)
207 "Loop a certain number of times. 213 "Loop a certain number of times.
@@ -214,15 +220,30 @@ the return value (nil if RESULT is omitted).
214 ;; It would be cleaner to create an uninterned symbol, 220 ;; It would be cleaner to create an uninterned symbol,
215 ;; but that uses a lot more space when many functions in many files 221 ;; but that uses a lot more space when many functions in many files
216 ;; use dotimes. 222 ;; use dotimes.
223 ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
217 (let ((temp '--dotimes-limit--) 224 (let ((temp '--dotimes-limit--)
218 (start 0) 225 (start 0)
219 (end (nth 1 spec))) 226 (end (nth 1 spec)))
220 `(let ((,temp ,end) 227 ;; This is not a reliable test, but it does not matter because both
221 (,(car spec) ,start)) 228 ;; semantics are acceptable, tho one is slightly faster with dynamic
222 (while (< ,(car spec) ,temp) 229 ;; scoping and the other has cleaner semantics.
223 ,@body 230 (if lexical-binding
224 (setq ,(car spec) (1+ ,(car spec)))) 231 (let ((counter '--dotimes-counter--))
225 ,@(cdr (cdr spec))))) 232 `(let ((,temp ,end)
233 (,counter ,start))
234 (while (< ,counter ,temp)
235 (let ((,(car spec) ,counter))
236 ,@body)
237 (setq ,counter (1+ ,counter)))
238 ,@(if (cddr spec)
239 ;; FIXME: This let often leads to "unused var" warnings.
240 `((let ((,(car spec) ,counter)) ,@(cddr spec))))))
241 `(let ((,temp ,end)
242 (,(car spec) ,start))
243 (while (< ,(car spec) ,temp)
244 ,@body
245 (setq ,(car spec) (1+ ,(car spec))))
246 ,@(cdr (cdr spec))))))
226 247
227(defmacro declare (&rest specs) 248(defmacro declare (&rest specs)
228 "Do not evaluate any arguments and return nil. 249 "Do not evaluate any arguments and return nil.
diff --git a/src/lread.c b/src/lread.c
index 7a8d7cf9a6a..24183532527 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1889,6 +1889,7 @@ which is the input stream for reading characters.
1889This function does not move point. */) 1889This function does not move point. */)
1890 (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function) 1890 (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function)
1891{ 1891{
1892 /* FIXME: Do the eval-sexp-add-defvars danse! */
1892 int count = SPECPDL_INDEX (); 1893 int count = SPECPDL_INDEX ();
1893 Lisp_Object tem, cbuf; 1894 Lisp_Object tem, cbuf;
1894 1895