From 5e9d390c3a5c4ac2b3ddabeab77bd6e2e9319c7b Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Thu, 6 Oct 2016 23:58:36 -0400 Subject: [PATCH] Make prog2 a macro rather than a special form * src/eval.c (Sprog2): Remove. * lisp/subr.el (prog2): Define a prog2 macro. * lisp/emacs-lisp/generator.el (cps--transform-1): prog2 no longer exists after macro expansion, so we don't need to transform it * lisp/emacs-lisp/bytecomp.el: Remove special treatment of prog2 in byte-compilation, as it's macro-expanded away. * lisp/emacs-lisp/unsafep.el: Update comments to reflect that prog2 is now a macro. * lisp/emacs-lisp/cl-macs.el (cl--simple-funcs): prog2 is no longer special form and does not need special treatment * doc/lispref/control.texi (Sequencing): prog2 is now a macro. * doc/lispref/functions.texi (Function Safety): prog2 is no longer a special form. --- doc/lispref/control.texi | 2 +- doc/lispref/functions.texi | 2 +- lisp/emacs-lisp/bytecomp.el | 1 - lisp/emacs-lisp/cl-macs.el | 2 +- lisp/emacs-lisp/generator.el | 7 ------- lisp/emacs-lisp/unsafep.el | 9 +++++---- lisp/subr.el | 11 +++++++++++ src/eval.c | 12 ------------ 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 0cdb035..bdcbd19 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -125,7 +125,7 @@ Sequencing @end defspec @defspec prog2 form1 form2 address@hidden -This special form evaluates @var{form1}, @var{form2}, and all of the +This macro evaluates @var{form1}, @var{form2}, and all of the following @var{forms}, in textual order, returning the result of @var{form2}. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index fff4ac0..37f3a18 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -2294,7 +2294,7 @@ Function Safety safe expressions. @item One of the special forms @code{and}, @code{catch}, @code{cond}, address@hidden, @code{or}, @code{prog1}, @code{prog2}, @code{progn}, address@hidden, @code{or}, @code{prog1}, @code{progn}, @code{while}, and @code{unwind-protect}], if all its arguments are safe. @item diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index c34ec5c..8d90aa7 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2406,7 +2406,6 @@ byte-compile-file-form-require (put 'progn 'byte-hunk-handler 'byte-compile-file-form-progn) (put 'prog1 'byte-hunk-handler 'byte-compile-file-form-progn) -(put 'prog2 'byte-hunk-handler 'byte-compile-file-form-progn) (defun byte-compile-file-form-progn (form) (mapc 'byte-compile-file-form (cdr form)) ;; Return nil so the forms are not output twice. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index f5b7b82..33a9f65 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -82,7 +82,7 @@ 'cl--compiler-macro-cXXr ;; macro expanders to optimize the results in certain common cases. (defconst cl--simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max - car-safe cdr-safe progn prog1 prog2)) + car-safe cdr-safe progn prog1)) (defconst cl--safe-funcs '(* / % length memq list vector vectorp < > <= >= = error)) diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index 49af240..f326b8e 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -379,13 +379,6 @@ cps--transform-1 `(setf ,cps--value-symbol ,temp-var-symbol ,cps--state-symbol ,next-state)))))))) - ;; Process `prog2'. - - (`(prog2 ,form1 ,form2 . ,body) - (cps--transform-1 - `(progn ,form1 (prog1 ,form2 ,@body)) - next-state)) - ;; Process `unwind-protect': If we're inside an unwind-protect, we ;; have a block of code UNWINDFORMS which we would like to run ;; whenever control flows away from the main piece of code, diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el index 584684f..bfdd58d 100644 --- a/lisp/emacs-lisp/unsafep.el +++ b/lisp/emacs-lisp/unsafep.el @@ -33,8 +33,9 @@ ;; 1. It's an atom. ;; 2. It's a function call to a safe function and all arguments are safe ;; formulas. -;; 3. It's a special form whose arguments are like a function's (and, -;; catch, if, or, prog1, prog2, progn, while, unwind-protect). +;; 3. It's a special form or macro whose arguments are like a +;; function's (and, catch, if, or, prog1, prog2, progn, while, +;; unwind-protect). ;; 4. It's a special form or macro that creates safe temporary bindings ;; (condition-case, dolist, dotimes, lambda, let, let*). ;; 4. It's one of (cond, quote) that have special parsing. @@ -99,13 +100,13 @@ unsafep-vars ;;Other safe functions (dolist (x '(;;Special forms - and catch if or prog1 prog2 progn while unwind-protect + and catch if or prog1 progn while unwind-protect ;;Safe subrs that have some side-effects ding error random signal sleep-for string-match throw ;;Defsubst functions from subr.el caar cadr cdar cddr ;;Macros from subr.el - save-match-data unless when + prog2 save-match-data unless when ;;Functions from subr.el that have side effects split-string replace-regexp-in-string play-sound-file)) (put x 'safe-function t)) diff --git a/lisp/subr.el b/lisp/subr.el index b143812..47e2050 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -174,6 +174,17 @@ pop (macroexp-let2 macroexp-copyable-p x getter `(prog1 ,x ,(funcall setter `(cdr ,x)))))))) +(defmacro prog2 (form1 form2 &rest body) + "Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. +The value of FORM2 is saved during the evaluation of the +remaining args, whose values are discarded. + +\(fn FORM1 FORM2 BODY...)" + (declare (indent 2) (debug t)) + (cons 'prog1 + (cons (list 'progn form1 form2) + body))) + (defmacro when (cond &rest body) "If COND yields non-nil, do BODY, else return nil. When COND yields non-nil, eval BODY forms sequentially and return diff --git a/src/eval.c b/src/eval.c index 2fedbf3..c823530 100644 --- a/src/eval.c +++ b/src/eval.c @@ -465,17 +465,6 @@ usage: (prog1 FIRST BODY...) */) return val; } -DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0, - doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. -The value of FORM2 is saved during the evaluation of the -remaining args, whose values are discarded. -usage: (prog2 FORM1 FORM2 BODY...) */) - (Lisp_Object args) -{ - eval_sub (XCAR (args)); - return Fprog1 (XCDR (args)); -} - DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0, doc: /* Set each SYM to the value of its VAL. The symbols SYM are variables; they are literal (not evaluated). @@ -3917,7 +3906,6 @@ alist of active lexical bindings. */); defsubr (&Scond); defsubr (&Sprogn); defsubr (&Sprog1); - defsubr (&Sprog2); defsubr (&Ssetq); defsubr (&Squote); defsubr (&Sfunction); -- 2.10.0