Mercurial > emacs
comparison lisp/emacs-lisp/cl-macs.el @ 48550:cbc642547375
Move `predicates for analyzing Lisp
forms' block to top (before uses).
(help-fns): Don't require at top level. (Recursively.)
(cl-transform-lambda): Require help-fns.
author | Dave Love <fx@gnu.org> |
---|---|
date | Wed, 27 Nov 2002 12:23:21 +0000 |
parents | 3cb92730a3fb |
children | 9f27d033e1a7 |
comparison
equal
deleted
inserted
replaced
48549:7f8d127179e5 | 48550:cbc642547375 |
---|---|
42 ;; See cl.el for Change Log. | 42 ;; See cl.el for Change Log. |
43 | 43 |
44 | 44 |
45 ;;; Code: | 45 ;;; Code: |
46 | 46 |
47 (require 'help-fns) ;For help-add-fundoc-usage. | |
48 | |
49 (or (memq 'cl-19 features) | 47 (or (memq 'cl-19 features) |
50 (error "Tried to load `cl-macs' before `cl'!")) | 48 (error "Tried to load `cl-macs' before `cl'!")) |
51 | 49 |
52 | 50 |
53 (defmacro cl-pop2 (place) | 51 (defmacro cl-pop2 (place) |
77 (defvar cl-old-bc-file-form nil) | 75 (defvar cl-old-bc-file-form nil) |
78 | 76 |
79 (defun cl-compile-time-init () | 77 (defun cl-compile-time-init () |
80 (run-hooks 'cl-hack-bytecomp-hook)) | 78 (run-hooks 'cl-hack-bytecomp-hook)) |
81 | 79 |
80 | |
81 ;;; Some predicates for analyzing Lisp forms. These are used by various | |
82 ;;; macro expanders to optimize the results in certain common cases. | |
83 | |
84 (defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max | |
85 car-safe cdr-safe progn prog1 prog2)) | |
86 (defconst cl-safe-funcs '(* / % length memq list vector vectorp | |
87 < > <= >= = error)) | |
88 | |
89 ;;; Check if no side effects, and executes quickly. | |
90 (defun cl-simple-expr-p (x &optional size) | |
91 (or size (setq size 10)) | |
92 (if (and (consp x) (not (memq (car x) '(quote function function*)))) | |
93 (and (symbolp (car x)) | |
94 (or (memq (car x) cl-simple-funcs) | |
95 (get (car x) 'side-effect-free)) | |
96 (progn | |
97 (setq size (1- size)) | |
98 (while (and (setq x (cdr x)) | |
99 (setq size (cl-simple-expr-p (car x) size)))) | |
100 (and (null x) (>= size 0) size))) | |
101 (and (> size 0) (1- size)))) | |
102 | |
103 (defun cl-simple-exprs-p (xs) | |
104 (while (and xs (cl-simple-expr-p (car xs))) | |
105 (setq xs (cdr xs))) | |
106 (not xs)) | |
107 | |
108 ;;; Check if no side effects. | |
109 (defun cl-safe-expr-p (x) | |
110 (or (not (and (consp x) (not (memq (car x) '(quote function function*))))) | |
111 (and (symbolp (car x)) | |
112 (or (memq (car x) cl-simple-funcs) | |
113 (memq (car x) cl-safe-funcs) | |
114 (get (car x) 'side-effect-free)) | |
115 (progn | |
116 (while (and (setq x (cdr x)) (cl-safe-expr-p (car x)))) | |
117 (null x))))) | |
118 | |
119 ;;; Check if constant (i.e., no side effects or dependencies). | |
120 (defun cl-const-expr-p (x) | |
121 (cond ((consp x) | |
122 (or (eq (car x) 'quote) | |
123 (and (memq (car x) '(function function*)) | |
124 (or (symbolp (nth 1 x)) | |
125 (and (eq (car-safe (nth 1 x)) 'lambda) 'func))))) | |
126 ((symbolp x) (and (memq x '(nil t)) t)) | |
127 (t t))) | |
128 | |
129 (defun cl-const-exprs-p (xs) | |
130 (while (and xs (cl-const-expr-p (car xs))) | |
131 (setq xs (cdr xs))) | |
132 (not xs)) | |
133 | |
134 (defun cl-const-expr-val (x) | |
135 (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x))) | |
136 | |
137 (defun cl-expr-access-order (x v) | |
138 (if (cl-const-expr-p x) v | |
139 (if (consp x) | |
140 (progn | |
141 (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v))) | |
142 v) | |
143 (if (eq x (car v)) (cdr v) '(t))))) | |
144 | |
145 ;;; Count number of times X refers to Y. Return nil for 0 times. | |
146 (defun cl-expr-contains (x y) | |
147 (cond ((equal y x) 1) | |
148 ((and (consp x) (not (memq (car-safe x) '(quote function function*)))) | |
149 (let ((sum 0)) | |
150 (while x | |
151 (setq sum (+ sum (or (cl-expr-contains (pop x) y) 0)))) | |
152 (and (> sum 0) sum))) | |
153 (t nil))) | |
154 | |
155 (defun cl-expr-contains-any (x y) | |
156 (while (and y (not (cl-expr-contains x (car y)))) (pop y)) | |
157 y) | |
158 | |
159 ;;; Check whether X may depend on any of the symbols in Y. | |
160 (defun cl-expr-depends-p (x y) | |
161 (and (not (cl-const-expr-p x)) | |
162 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y)))) | |
82 | 163 |
83 ;;; Symbols. | 164 ;;; Symbols. |
84 | 165 |
85 (defvar *gensym-counter*) | 166 (defvar *gensym-counter*) |
86 (defun gensym (&optional arg) | 167 (defun gensym (&optional arg) |
181 (list* (and bind-inits (list* 'eval-when '(compile load eval) | 262 (list* (and bind-inits (list* 'eval-when '(compile load eval) |
182 (nreverse bind-inits))) | 263 (nreverse bind-inits))) |
183 (nconc (nreverse simple-args) | 264 (nconc (nreverse simple-args) |
184 (list '&rest (car (pop bind-lets)))) | 265 (list '&rest (car (pop bind-lets)))) |
185 (nconc (let ((hdr (nreverse header))) | 266 (nconc (let ((hdr (nreverse header))) |
267 (require 'help-fns) | |
186 (cons (help-add-fundoc-usage | 268 (cons (help-add-fundoc-usage |
187 (if (stringp (car hdr)) (pop hdr)) orig-args) | 269 (if (stringp (car hdr)) (pop hdr)) orig-args) |
188 hdr)) | 270 hdr)) |
189 (list (nconc (list 'let* bind-lets) | 271 (list (nconc (list 'let* bind-lets) |
190 (nreverse bind-forms) body))))))) | 272 (nreverse bind-forms) body))))))) |
2355 "Execute FORMS; if an error occurs, return nil. | 2437 "Execute FORMS; if an error occurs, return nil. |
2356 Otherwise, return result of last FORM." | 2438 Otherwise, return result of last FORM." |
2357 `(condition-case nil (progn ,@body) (error nil))) | 2439 `(condition-case nil (progn ,@body) (error nil))) |
2358 | 2440 |
2359 | 2441 |
2360 ;;; Some predicates for analyzing Lisp forms. These are used by various | |
2361 ;;; macro expanders to optimize the results in certain common cases. | |
2362 | |
2363 (defconst cl-simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max | |
2364 car-safe cdr-safe progn prog1 prog2)) | |
2365 (defconst cl-safe-funcs '(* / % length memq list vector vectorp | |
2366 < > <= >= = error)) | |
2367 | |
2368 ;;; Check if no side effects, and executes quickly. | |
2369 (defun cl-simple-expr-p (x &optional size) | |
2370 (or size (setq size 10)) | |
2371 (if (and (consp x) (not (memq (car x) '(quote function function*)))) | |
2372 (and (symbolp (car x)) | |
2373 (or (memq (car x) cl-simple-funcs) | |
2374 (get (car x) 'side-effect-free)) | |
2375 (progn | |
2376 (setq size (1- size)) | |
2377 (while (and (setq x (cdr x)) | |
2378 (setq size (cl-simple-expr-p (car x) size)))) | |
2379 (and (null x) (>= size 0) size))) | |
2380 (and (> size 0) (1- size)))) | |
2381 | |
2382 (defun cl-simple-exprs-p (xs) | |
2383 (while (and xs (cl-simple-expr-p (car xs))) | |
2384 (setq xs (cdr xs))) | |
2385 (not xs)) | |
2386 | |
2387 ;;; Check if no side effects. | |
2388 (defun cl-safe-expr-p (x) | |
2389 (or (not (and (consp x) (not (memq (car x) '(quote function function*))))) | |
2390 (and (symbolp (car x)) | |
2391 (or (memq (car x) cl-simple-funcs) | |
2392 (memq (car x) cl-safe-funcs) | |
2393 (get (car x) 'side-effect-free)) | |
2394 (progn | |
2395 (while (and (setq x (cdr x)) (cl-safe-expr-p (car x)))) | |
2396 (null x))))) | |
2397 | |
2398 ;;; Check if constant (i.e., no side effects or dependencies). | |
2399 (defun cl-const-expr-p (x) | |
2400 (cond ((consp x) | |
2401 (or (eq (car x) 'quote) | |
2402 (and (memq (car x) '(function function*)) | |
2403 (or (symbolp (nth 1 x)) | |
2404 (and (eq (car-safe (nth 1 x)) 'lambda) 'func))))) | |
2405 ((symbolp x) (and (memq x '(nil t)) t)) | |
2406 (t t))) | |
2407 | |
2408 (defun cl-const-exprs-p (xs) | |
2409 (while (and xs (cl-const-expr-p (car xs))) | |
2410 (setq xs (cdr xs))) | |
2411 (not xs)) | |
2412 | |
2413 (defun cl-const-expr-val (x) | |
2414 (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x))) | |
2415 | |
2416 (defun cl-expr-access-order (x v) | |
2417 (if (cl-const-expr-p x) v | |
2418 (if (consp x) | |
2419 (progn | |
2420 (while (setq x (cdr x)) (setq v (cl-expr-access-order (car x) v))) | |
2421 v) | |
2422 (if (eq x (car v)) (cdr v) '(t))))) | |
2423 | |
2424 ;;; Count number of times X refers to Y. Return nil for 0 times. | |
2425 (defun cl-expr-contains (x y) | |
2426 (cond ((equal y x) 1) | |
2427 ((and (consp x) (not (memq (car-safe x) '(quote function function*)))) | |
2428 (let ((sum 0)) | |
2429 (while x | |
2430 (setq sum (+ sum (or (cl-expr-contains (pop x) y) 0)))) | |
2431 (and (> sum 0) sum))) | |
2432 (t nil))) | |
2433 | |
2434 (defun cl-expr-contains-any (x y) | |
2435 (while (and y (not (cl-expr-contains x (car y)))) (pop y)) | |
2436 y) | |
2437 | |
2438 ;;; Check whether X may depend on any of the symbols in Y. | |
2439 (defun cl-expr-depends-p (x y) | |
2440 (and (not (cl-const-expr-p x)) | |
2441 (or (not (cl-safe-expr-p x)) (cl-expr-contains-any x y)))) | |
2442 | |
2443 | |
2444 ;;; Compiler macros. | 2442 ;;; Compiler macros. |
2445 | 2443 |
2446 (defmacro define-compiler-macro (func args &rest body) | 2444 (defmacro define-compiler-macro (func args &rest body) |
2447 "Define a compiler-only macro. | 2445 "Define a compiler-only macro. |
2448 This is like `defmacro', but macro expansion occurs only if the call to | 2446 This is like `defmacro', but macro expansion occurs only if the call to |