* 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.
This commit is contained in:
parent
ebe0c9b6b0
commit
f488fb6528
4 changed files with 56 additions and 23 deletions
|
@ -1,3 +1,13 @@
|
|||
2011-03-30 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* 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.
|
||||
|
||||
* emacs-lisp/edebug.el (edebug-eval-top-level-form):
|
||||
Use eval-sexp-add-defvars.
|
||||
|
||||
2011-03-30 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* makefile.w32-in (COMPILE_FIRST): Remove pcase.
|
||||
|
|
|
@ -566,7 +566,8 @@ already is one.)"
|
|||
;; but this causes problems while edebugging edebug.
|
||||
(let ((edebug-all-forms t)
|
||||
(edebug-all-defs t))
|
||||
(edebug-read-top-level-form))))
|
||||
(eval-sexp-add-defvars
|
||||
(edebug-read-top-level-form)))))
|
||||
|
||||
|
||||
(defun edebug-read-top-level-form ()
|
||||
|
|
65
lisp/subr.el
65
lisp/subr.el
|
@ -124,7 +124,7 @@ ARGS is a list of the first N arguments to pass to FUN.
|
|||
The result is a new function which does the same as FUN, except that
|
||||
the first N arguments are fixed at the values with which this function
|
||||
was called."
|
||||
`(closure () (&rest args)
|
||||
`(closure (t) (&rest args)
|
||||
(apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args)))
|
||||
|
||||
(if (null (featurep 'cl))
|
||||
|
@ -174,8 +174,6 @@ value of last one, or nil if there are none.
|
|||
;; If we reload subr.el after having loaded CL, be careful not to
|
||||
;; overwrite CL's extended definition of `dolist', `dotimes',
|
||||
;; `declare', `push' and `pop'.
|
||||
(defvar --dolist-tail-- nil
|
||||
"Temporary variable used in `dolist' expansion.")
|
||||
|
||||
(defmacro dolist (spec &rest body)
|
||||
"Loop over a list.
|
||||
|
@ -189,19 +187,27 @@ Then evaluate RESULT to get return value, default nil.
|
|||
;; use dolist.
|
||||
;; FIXME: This cost disappears in byte-compiled lexical-binding files.
|
||||
(let ((temp '--dolist-tail--))
|
||||
`(let ((,temp ,(nth 1 spec))
|
||||
,(car spec))
|
||||
(while ,temp
|
||||
;; FIXME: In lexical-binding code, a `let' inside the loop might
|
||||
;; turn out to be faster than the an outside `let' this `setq'.
|
||||
(setq ,(car spec) (car ,temp))
|
||||
,@body
|
||||
(setq ,temp (cdr ,temp)))
|
||||
,@(if (cdr (cdr spec))
|
||||
`((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))
|
||||
|
||||
(defvar --dotimes-limit-- nil
|
||||
"Temporary variable used in `dotimes' expansion.")
|
||||
;; This is not a reliable test, but it does not matter because both
|
||||
;; semantics are acceptable, tho one is slightly faster with dynamic
|
||||
;; scoping and the other is slightly faster (and has cleaner semantics)
|
||||
;; with lexical scoping.
|
||||
(if lexical-binding
|
||||
`(let ((,temp ,(nth 1 spec)))
|
||||
(while ,temp
|
||||
(let ((,(car spec) (car ,temp)))
|
||||
,@body
|
||||
(setq ,temp (cdr ,temp))))
|
||||
,@(if (cdr (cdr spec))
|
||||
;; FIXME: This let often leads to "unused var" warnings.
|
||||
`((let ((,(car spec) nil)) ,@(cdr (cdr spec))))))
|
||||
`(let ((,temp ,(nth 1 spec))
|
||||
,(car spec))
|
||||
(while ,temp
|
||||
(setq ,(car spec) (car ,temp))
|
||||
,@body
|
||||
(setq ,temp (cdr ,temp)))
|
||||
,@(if (cdr (cdr spec))
|
||||
`((setq ,(car spec) nil) ,@(cdr (cdr spec))))))))
|
||||
|
||||
(defmacro dotimes (spec &rest body)
|
||||
"Loop a certain number of times.
|
||||
|
@ -214,15 +220,30 @@ the return value (nil if RESULT is omitted).
|
|||
;; It would be cleaner to create an uninterned symbol,
|
||||
;; but that uses a lot more space when many functions in many files
|
||||
;; use dotimes.
|
||||
;; FIXME: This cost disappears in byte-compiled lexical-binding files.
|
||||
(let ((temp '--dotimes-limit--)
|
||||
(start 0)
|
||||
(end (nth 1 spec)))
|
||||
`(let ((,temp ,end)
|
||||
(,(car spec) ,start))
|
||||
(while (< ,(car spec) ,temp)
|
||||
,@body
|
||||
(setq ,(car spec) (1+ ,(car spec))))
|
||||
,@(cdr (cdr spec)))))
|
||||
;; This is not a reliable test, but it does not matter because both
|
||||
;; semantics are acceptable, tho one is slightly faster with dynamic
|
||||
;; scoping and the other has cleaner semantics.
|
||||
(if lexical-binding
|
||||
(let ((counter '--dotimes-counter--))
|
||||
`(let ((,temp ,end)
|
||||
(,counter ,start))
|
||||
(while (< ,counter ,temp)
|
||||
(let ((,(car spec) ,counter))
|
||||
,@body)
|
||||
(setq ,counter (1+ ,counter)))
|
||||
,@(if (cddr spec)
|
||||
;; FIXME: This let often leads to "unused var" warnings.
|
||||
`((let ((,(car spec) ,counter)) ,@(cddr spec))))))
|
||||
`(let ((,temp ,end)
|
||||
(,(car spec) ,start))
|
||||
(while (< ,(car spec) ,temp)
|
||||
,@body
|
||||
(setq ,(car spec) (1+ ,(car spec))))
|
||||
,@(cdr (cdr spec))))))
|
||||
|
||||
(defmacro declare (&rest specs)
|
||||
"Do not evaluate any arguments and return nil.
|
||||
|
|
|
@ -1889,6 +1889,7 @@ which is the input stream for reading characters.
|
|||
This function does not move point. */)
|
||||
(Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function)
|
||||
{
|
||||
/* FIXME: Do the eval-sexp-add-defvars danse! */
|
||||
int count = SPECPDL_INDEX ();
|
||||
Lisp_Object tem, cbuf;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue