From b3f5d832c2009362d62af9ce98be505abb3a946d Mon Sep 17 00:00:00 2001 From: yamaoka Date: Mon, 29 Jul 2002 10:46:13 +0000 Subject: [PATCH] * pym.el (defun-maybe): Use `defalias' instead of `defun'; don't handle `current-load-list'; always return a function symbol. (defmacro-maybe): Set a symbol to a macro definition itself; don't handle `current-load-list'; always return a macro symbol. (defsubst-maybe): Set a symbol to a function definition itself; don't handle `current-load-list'; always return a function symbol. (defalias-maybe): Always return a new definition. (defvar-maybe): Always return a variable symbol. (defconst-maybe): Ditto. (defun-maybe-cond): Use `defalias' instead of `defun'; don't handle `current-load-list'; always return a function symbol. (defmacro-maybe-cond): Set a symbol to a macro definition itself; don't handle `current-load-list'; always return a macro symbol. (defsubst-maybe-cond): Set a symbol to a function definition itself; don't handle `current-load-list'; always return a function symbol. (defun-when-void): Always return a function symbol. (defmacro-when-void): New macro. (defsubst-when-void): New macro. (defalias-when-void): New macro. (defvar-when-void): New macro. (defconst-maybe): New macro. --- ChangeLog | 38 ++++++- pym.el | 366 +++++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 287 insertions(+), 117 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b50a8e..eab8117 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,43 @@ +2002-07-29 Katsumi Yamaoka + + * pym.el (defun-maybe): Use `defalias' instead of `defun'; don't + handle `current-load-list'; always return a function symbol. + (defmacro-maybe): Set a symbol to a macro definition itself; don't + handle `current-load-list'; always return a macro symbol. + (defsubst-maybe): Set a symbol to a function definition itself; + don't handle `current-load-list'; always return a function symbol. + (defalias-maybe): Always return a new definition. + (defvar-maybe): Always return a variable symbol. + (defconst-maybe): Ditto. + (defun-maybe-cond): Use `defalias' instead of `defun'; don't + handle `current-load-list'; always return a function symbol. + (defmacro-maybe-cond): Set a symbol to a macro definition itself; + don't handle `current-load-list'; always return a macro symbol. + (defsubst-maybe-cond): Set a symbol to a function definition + itself; don't handle `current-load-list'; always return a function + symbol. + (defun-when-void): Always return a function symbol. + (defmacro-when-void): New macro. + (defsubst-when-void): New macro. + (defalias-when-void): New macro. + (defvar-when-void): New macro. + (defconst-maybe): New macro. + +2002-07-26 Katsumi Yamaoka + + * pym.el (defun-maybe): Doc fix. + (defun-when-void): New macro. + +2002-07-24 Shuhei KOBAYASHI + + * pym.el (def*-maybe-enable-compile-time-hack): New variable; + default to nil. + (defun-maybe): Use it. + 2002-07-13 Daiki Ueno * mcs-xm.el (encode-mime-charset-string): Use `defun' instead of - `defsubst' + `defsubst'. 2002-07-10 Adrian Aichner diff --git a/pym.el b/pym.el index c895ef2..11c70bb 100644 --- a/pym.el +++ b/pym.el @@ -1,9 +1,11 @@ -;;; pym.el --- Macros for Your Poe. +;;; pym.el --- Macros for Your Poe -;; Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc. +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002 +;; Free Software Foundation, Inc. ;; Author: MORIOKA Tomohiko ;; Shuhei KOBAYASHI +;; Katsumi Yamaoka ;; Keywords: byte-compile, evaluation, edebug, internal ;; This file is part of APEL (A Portable Emacs Library). @@ -49,142 +51,194 @@ ;;; Code: -;; for `load-history'. -(or (boundp 'current-load-list) (setq current-load-list nil)) - (require 'static) ;;; Conditional define. +(defvar def*-maybe-enable-compile-time-hack nil + "If non-nil, `def*-maybe' macros will do compile-time check. +`def*-maybe' macro normally checks existence of its target function or +variable at load-time. But if this variable is non-nil at compile-time, +existence of its target is first checked at compile-time, and if exists, +it will emit no compiled code at all! +You should set this variable to non-nil only when you really know what +you are doing.") + (put 'defun-maybe 'lisp-indent-function 'defun) (defmacro defun-maybe (name &rest everything-else) "Define NAME as a function if NAME is not defined. -See also the function `defun'." - (or (and (fboundp name) - (not (get name 'defun-maybe))) - (` (or (fboundp (quote (, name))) - (prog1 - (defun (, name) (,@ everything-else)) - ;; This `defun' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defun-maybe t)))))) +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of NAME, use `defun-when-void' instead. See +also the function `defun'." + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defun-maybe)) + (let ((qname (` (quote (, name))))) + (` (prog1 + (, qname) + (if (not (fboundp (, qname))) + (progn + ;; Use `defalias' to update `load-history'. + (defalias (, qname) + (function (lambda (,@ everything-else)))) + (put (, qname) 'defun-maybe t)))))))) (put 'defmacro-maybe 'lisp-indent-function 'defun) (defmacro defmacro-maybe (name &rest everything-else) "Define NAME as a macro if NAME is not defined. +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of NAME, use `defmacro-when-void' instead. See also the function `defmacro'." - (or (and (fboundp name) - (not (get name 'defmacro-maybe))) - (` (or (fboundp (quote (, name))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defmacro-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) (prog1 (defmacro (, name) (,@ everything-else)) - ;; This `defmacro' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defmacro-maybe t)))))) + ;; Use `defalias' to update `load-history'. + (defalias (, qname) (symbol-function (, qname))) + (put (, qname) 'defmacro-maybe t))))))) (put 'defsubst-maybe 'lisp-indent-function 'defun) (defmacro defsubst-maybe (name &rest everything-else) "Define NAME as an inline function if NAME is not defined. +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of NAME, use `defsubst-when-void' instead. See also the macro `defsubst'." - (or (and (fboundp name) - (not (get name 'defsubst-maybe))) - (` (or (fboundp (quote (, name))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defsubst-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) (prog1 (defsubst (, name) (,@ everything-else)) - ;; This `defsubst' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defsubst-maybe t)))))) + ;; Use `defalias' to update `load-history'. + (defalias (, qname) (symbol-function (, qname))) + (put (, qname) 'defsubst-maybe t))))))) (defmacro defalias-maybe (symbol definition) "Define SYMBOL as an alias for DEFINITION if SYMBOL is not defined. +Note that it will never produce a byte-compiled code when SYMBOL has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of SYMBOL, use `defalias-when-void' instead. See also the function `defalias'." (setq symbol (eval symbol)) - (or (and (fboundp symbol) - (not (get symbol 'defalias-maybe))) - (` (or (fboundp (quote (, symbol))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp symbol)) + (get symbol 'defalias-maybe)) + (let ((qsymbol (` (quote (, symbol))))) + (` (if (fboundp (, qsymbol)) + (symbol-function (, qsymbol)) (prog1 - (defalias (quote (, symbol)) (, definition)) - ;; `defalias' updates `load-history' internally. - (put (quote (, symbol)) 'defalias-maybe t)))))) + ;; `defalias' updates `load-history' internally. + (defalias (, qsymbol) (, definition)) + (put (, qsymbol) 'defalias-maybe t))))))) (defmacro defvar-maybe (name &rest everything-else) "Define NAME as a variable if NAME is not defined. -See also the function `defvar'." - (or (and (boundp name) - (not (get name 'defvar-maybe))) - (` (or (boundp (quote (, name))) +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of NAME, use `defvar-when-void' instead. See +also the function `defvar'." + (if (or (null def*-maybe-enable-compile-time-hack) + (not (boundp name)) + (get name 'defvar-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (boundp (, qname)) + (, qname) (prog1 + ;; byte-compiler will generate code to update + ;; `load-history'. (defvar (, name) (,@ everything-else)) - ;; byte-compiler will generate code to update - ;; `load-history'. - (put (quote (, name)) 'defvar-maybe t)))))) + (put (, qname) 'defvar-maybe t))))))) (defmacro defconst-maybe (name &rest everything-else) "Define NAME as a constant variable if NAME is not defined. +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. In order to always +check for the existence of NAME, use `defconst-when-void' instead. See also the function `defconst'." - (or (and (boundp name) - (not (get name 'defconst-maybe))) - (` (or (boundp (quote (, name))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (boundp name)) + (get name 'defconst-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (boundp (, qname)) + (, qname) (prog1 + ;; byte-compiler will generate code to update + ;; `load-history'. (defconst (, name) (,@ everything-else)) - ;; byte-compiler will generate code to update - ;; `load-history'. - (put (quote (, name)) 'defconst-maybe t)))))) + (put (, qname) 'defconst-maybe t))))))) (defmacro defun-maybe-cond (name args &optional doc &rest clauses) "Define NAME as a function if NAME is not defined. -CLAUSES are like those of `cond' expression, but each condition is evaluated -at compile-time and, if the value is non-nil, the body of the clause is used -for function definition of NAME. -See also the function `defun'." +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. +CLAUSES are like those of `cond' expression, but each condition is +evaluated at compile-time and, if the value is non-nil, the body of +the clause is used for function definition of NAME. See also the +function `defun'." (or (stringp doc) (setq clauses (cons doc clauses) doc nil)) - (or (and (fboundp name) - (not (get name 'defun-maybe))) - (` (or (fboundp (quote (, name))) - (prog1 - (static-cond - (,@ (mapcar - (function - (lambda (case) - (list (car case) - (if doc - (` (defun (, name) (, args) - (, doc) - (,@ (cdr case)))) - (` (defun (, name) (, args) - (,@ (cdr case)))))))) - clauses))) - ;; This `defun' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defun-maybe t)))))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defun-maybe)) + (let ((qname (` (quote (, name))))) + (` (prog1 + (, qname) + (if (not (fboundp (, qname))) + (progn + (static-cond + (,@ (mapcar + (function + (lambda (case) + (list (car case) + (if doc + (` (defalias (, qname) + (function + (lambda (, args) + (, doc) + (,@ (cdr case)))))) + (` (defalias (, qname) + (function + (lambda (, args) + (,@ (cdr case)))))))))) + clauses))) + (put (, qname) 'defun-maybe t)))))))) (defmacro defmacro-maybe-cond (name args &optional doc &rest clauses) "Define NAME as a macro if NAME is not defined. -CLAUSES are like those of `cond' expression, but each condition is evaluated -at compile-time and, if the value is non-nil, the body of the clause is used -for macro definition of NAME. -See also the function `defmacro'." +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. +CLAUSES are like those of `cond' expression, but each condition is +evaluated at compile-time and, if the value is non-nil, the body of +the clause is used for macro definition of NAME. See also the +function `defmacro'." (or (stringp doc) (setq clauses (cons doc clauses) doc nil)) - (or (and (fboundp name) - (not (get name 'defmacro-maybe))) - (` (or (fboundp (quote (, name))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defmacro-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) (prog1 (static-cond (,@ (mapcar @@ -192,31 +246,38 @@ See also the function `defmacro'." (lambda (case) (list (car case) (if doc - (` (defmacro (, name) (, args) - (, doc) - (,@ (cdr case)))) - (` (defmacro (, name) (, args) - (,@ (cdr case)))))))) + (` (prog1 + (defmacro (, name) (, args) + (, doc) + (,@ (cdr case))) + (defalias (, qname) + (symbol-function (, qname))))) + (` (prog1 + (defmacro (, name) (, args) + (,@ (cdr case))) + (defalias (, qname) + (symbol-function (, qname))))))))) clauses))) - ;; This `defmacro' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defmacro-maybe t)))))) + (put (, qname) 'defmacro-maybe t))))))) (defmacro defsubst-maybe-cond (name args &optional doc &rest clauses) "Define NAME as an inline function if NAME is not defined. -CLAUSES are like those of `cond' expression, but each condition is evaluated -at compile-time and, if the value is non-nil, the body of the clause is used -for function definition of NAME. -See also the macro `defsubst'." +Note that it will never produce a byte-compiled code when NAME has +already been defined at the compile-time and the value for +`def*-maybe-enable-compile-time-hack' is non-nil. +CLAUSES are like those of `cond' expression, but each condition is +evaluated at compile-time and, if the value is non-nil, the body of +the clause is used for function definition of NAME. See also the +macro `defsubst'." (or (stringp doc) (setq clauses (cons doc clauses) doc nil)) - (or (and (fboundp name) - (not (get name 'defsubst-maybe))) - (` (or (fboundp (quote (, name))) + (if (or (null def*-maybe-enable-compile-time-hack) + (not (fboundp name)) + (get name 'defsubst-maybe)) + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) (prog1 (static-cond (,@ (mapcar @@ -224,18 +285,91 @@ See also the macro `defsubst'." (lambda (case) (list (car case) (if doc - (` (defsubst (, name) (, args) - (, doc) - (,@ (cdr case)))) - (` (defsubst (, name) (, args) - (,@ (cdr case)))))))) + (` (prog1 + (defsubst (, name) (, args) + (, doc) + (,@ (cdr case))) + (defalias (, qname) + (symbol-function (, qname))))) + (` (prog1 + (defsubst (, name) (, args) + (,@ (cdr case))) + (defalias (, qname) + (symbol-function (, qname))))))))) clauses))) - ;; This `defsubst' will be compiled to `fset', - ;; which does not update `load-history'. - ;; We must update `current-load-list' explicitly. - (setq current-load-list - (cons (quote (, name)) current-load-list)) - (put (quote (, name)) 'defsubst-maybe t)))))) + (put (, qname) 'defsubst-maybe t))))))) + + +;;; Conditional define (always do load-time check). + +(put 'defun-when-void 'lisp-indent-function 'defun) +(defmacro defun-when-void (name &rest everything-else) + "Define NAME as a function if NAME is not defined at the load-time. +See also the function `defun' and the macro `defun-maybe'. Note that +the macro with the same name in XEmacs will be replaced with it." + (let ((qname (` (quote (, name))))) + (` (prog1 + (, qname) + (if (not (fboundp (, qname))) + ;; Use `defalias' to update `load-history'. + (defalias (, qname) + (function (lambda (,@ everything-else))))))))) + +(put 'defmacro-when-void 'lisp-indent-function 'defun) +(defmacro defmacro-when-void (name &rest everything-else) + "Define NAME as a macro if NAME is not defined at the load-time. +See also the function `defmacro' and the macro `defmacro-maybe'." + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) + (prog1 + (defmacro (, name) (,@ everything-else)) + ;; Use `defalias' to update `load-history'. + (defalias (, qname) (symbol-function (, qname)))))))) + +(put 'defsubst-when-void 'lisp-indent-function 'defun) +(defmacro defsubst-when-void (name &rest everything-else) + "Define NAME as an inline function if NAME is not defined at the +load-time. See also the macros `defsubst' and `defsubst-maybe'." + (let ((qname (` (quote (, name))))) + (` (if (fboundp (, qname)) + (, qname) + (prog1 + (defsubst (, name) (,@ everything-else)) + ;; Use `defalias' to update `load-history'. + (defalias (, qname) (symbol-function (, qname)))))))) + +(defmacro defalias-when-void (symbol definition) + "Define SYMBOL as an alias for DEFINITION if SYMBOL is not defined at +the load-time. See also the function `defalias' and the macro +`defalias-maybe'." + (let* ((symbol (eval symbol)) + (qsymbol (` (quote (, symbol))))) + (` (if (fboundp (, qsymbol)) + (symbol-function (, qsymbol)) + ;; `defalias' updates `load-history' internally. + (defalias (, qsymbol) (, definition)))))) + +(defmacro defvar-when-void (name &rest everything-else) + "Define NAME as a variable if NAME is not defined at the load-time. +See also the function `defvar' and the macro `defvar-maybe'." + (let ((qname (` (quote (, name))))) + (` (if (boundp (, qname)) + (, qname) + ;; byte-compiler will generate code to update + ;; `load-history'. + (defvar (, name) (,@ everything-else)))))) + +(defmacro defconst-when-void (name &rest everything-else) + "Define NAME as a constant variable if NAME is not defined at the +load-time. See also the function `defconst' and the macro +`defconst-maybe'." + (let ((qname (` (quote (, name))))) + (` (if (boundp (, qname)) + (, qname) + ;; byte-compiler will generate code to update + ;; `load-history'. + (defconst (, name) (,@ everything-else)))))) ;;; Edebug spec. -- 1.7.10.4