comparison lisp/emacs-lisp/cl-macs.el @ 15030:257fd294d7cb

(defstruct): Treat multi-nested :include properly. (flet): Warn when flet rebinds a macro name. (labels): Rewrite to be fully CL-compliant.
author Richard M. Stallman <rms@gnu.org>
date Tue, 16 Apr 1996 04:36:21 +0000
parents 83f275dcd93a
children a74507d555ba
comparison
equal deleted inserted replaced
15029:ba44a899c055 15030:257fd294d7cb
1220 go back to their previous definitions, or lack thereof)." 1220 go back to their previous definitions, or lack thereof)."
1221 (list* 'letf* 1221 (list* 'letf*
1222 (mapcar 1222 (mapcar
1223 (function 1223 (function
1224 (lambda (x) 1224 (lambda (x)
1225 (if (or (and (fboundp (car x))
1226 (eq (car-safe (symbol-function (car x))) 'macro))
1227 (cdr (assq (car x) cl-macro-environment)))
1228 (error "Use `labels', not `flet', to rebind macro names"))
1225 (let ((func (list 'function* 1229 (let ((func (list 'function*
1226 (list 'lambda (cadr x) 1230 (list 'lambda (cadr x)
1227 (list* 'block (car x) (cddr x)))))) 1231 (list* 'block (car x) (cddr x))))))
1228 (if (and (cl-compiling-file) 1232 (if (and (cl-compiling-file)
1229 (boundp 'byte-compile-function-environment)) 1233 (boundp 'byte-compile-function-environment))
1231 byte-compile-function-environment)) 1235 byte-compile-function-environment))
1232 (list (list 'symbol-function (list 'quote (car x))) func)))) 1236 (list (list 'symbol-function (list 'quote (car x))) func))))
1233 bindings) 1237 bindings)
1234 body)) 1238 body))
1235 1239
1236 (defmacro labels (&rest args) (cons 'flet args)) 1240 (defmacro labels (bindings &rest body)
1241 "(labels ((FUNC ARGLIST BODY...) ...) FORM...): make temporary func bindings.
1242 This is like `flet', except the bindings are lexical instead of dynamic.
1243 Unlike `flet', this macro is fully complaint with the Common Lisp standard."
1244 (let ((vars nil) (sets nil) (cl-macro-environment cl-macro-environment))
1245 (while bindings
1246 (let ((var (gensym)))
1247 (cl-push var vars)
1248 (cl-push (list 'function* (cons 'lambda (cdar bindings))) sets)
1249 (cl-push var sets)
1250 (cl-push (list (car (cl-pop bindings)) 'lambda '(&rest cl-labels-args)
1251 (list 'list* '(quote funcall) (list 'quote var)
1252 'cl-labels-args))
1253 cl-macro-environment)))
1254 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body))
1255 cl-macro-environment)))
1237 1256
1238 ;; The following ought to have a better definition for use with newer 1257 ;; The following ought to have a better definition for use with newer
1239 ;; byte compilers. 1258 ;; byte compilers.
1240 (defmacro macrolet (bindings &rest body) 1259 (defmacro macrolet (bindings &rest body)
1241 "(macrolet ((NAME ARGLIST BODY...) ...) FORM...): make temporary macro defns. 1260 "(macrolet ((NAME ARGLIST BODY...) ...) FORM...): make temporary macro defns.
2015 (safety (if (cl-compiling-file) cl-optimize-safety 3)) 2034 (safety (if (cl-compiling-file) cl-optimize-safety 3))
2016 (include nil) 2035 (include nil)
2017 (tag (intern (format "cl-struct-%s" name))) 2036 (tag (intern (format "cl-struct-%s" name)))
2018 (tag-symbol (intern (format "cl-struct-%s-tags" name))) 2037 (tag-symbol (intern (format "cl-struct-%s-tags" name)))
2019 (include-descs nil) 2038 (include-descs nil)
2020 (include-tag-symbol nil)
2021 (side-eff nil) 2039 (side-eff nil)
2022 (type nil) 2040 (type nil)
2023 (named nil) 2041 (named nil)
2024 (forms nil) 2042 (forms nil)
2025 pred-form pred-check) 2043 pred-form pred-check)
2047 ((eq opt ':include) 2065 ((eq opt ':include)
2048 (setq include (car args) 2066 (setq include (car args)
2049 include-descs (mapcar (function 2067 include-descs (mapcar (function
2050 (lambda (x) 2068 (lambda (x)
2051 (if (consp x) x (list x)))) 2069 (if (consp x) x (list x))))
2052 (cdr args)) 2070 (cdr args))))
2053 include-tag-symbol (intern (format "cl-struct-%s-tags"
2054 include))))
2055 ((eq opt ':print-function) 2071 ((eq opt ':print-function)
2056 (setq print-func (car args))) 2072 (setq print-func (car args)))
2057 ((eq opt ':type) 2073 ((eq opt ':type)
2058 (setq type (car args))) 2074 (setq type (car args)))
2059 ((eq opt ':named) 2075 ((eq opt ':named)
2087 (cl-pop include-descs))) 2103 (cl-pop include-descs)))
2088 (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs)) 2104 (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs))
2089 type (car inc-type) 2105 type (car inc-type)
2090 named (assq 'cl-tag-slot descs)) 2106 named (assq 'cl-tag-slot descs))
2091 (if (cadr inc-type) (setq tag name named t)) 2107 (if (cadr inc-type) (setq tag name named t))
2092 (cl-push (list 'pushnew (list 'quote tag) include-tag-symbol) 2108 (let ((incl include))
2093 forms)) 2109 (while incl
2110 (cl-push (list 'pushnew (list 'quote tag)
2111 (intern (format "cl-struct-%s-tags" incl)))
2112 forms)
2113 (setq incl (get incl 'cl-struct-include)))))
2094 (if type 2114 (if type
2095 (progn 2115 (progn
2096 (or (memq type '(vector list)) 2116 (or (memq type '(vector list))
2097 (error "Illegal :type specifier: %s" type)) 2117 (error "Illegal :type specifier: %s" type))
2098 (if named (setq tag name))) 2118 (if named (setq tag name)))
2195 (cl-push (list* 'eval-when '(compile load eval) 2215 (cl-push (list* 'eval-when '(compile load eval)
2196 (list 'put (list 'quote name) '(quote cl-struct-slots) 2216 (list 'put (list 'quote name) '(quote cl-struct-slots)
2197 (list 'quote descs)) 2217 (list 'quote descs))
2198 (list 'put (list 'quote name) '(quote cl-struct-type) 2218 (list 'put (list 'quote name) '(quote cl-struct-type)
2199 (list 'quote (list type (eq named t)))) 2219 (list 'quote (list type (eq named t))))
2220 (list 'put (list 'quote name) '(quote cl-struct-include)
2221 (list 'quote include))
2200 (list 'put (list 'quote name) '(quote cl-struct-print) 2222 (list 'put (list 'quote name) '(quote cl-struct-print)
2201 print-auto) 2223 print-auto)
2202 (mapcar (function (lambda (x) 2224 (mapcar (function (lambda (x)
2203 (list 'put (list 'quote (car x)) 2225 (list 'put (list 'quote (car x))
2204 '(quote side-effect-free) 2226 '(quote side-effect-free)