1;;; cl-specs.el --- Edebug specs for cl.el -*- no-byte-compile: t -*- 2 3;; Copyright (C) 1993, 2001, 2002, 2003, 2004, 2005, 4;; 2006, 2007 Free Software Foundation, Inc. 5;; Author: Daniel LaLiberte <liberte@holonexus.org> 6;; Keywords: lisp, tools, maint 7 8;; LCD Archive Entry: 9;; cl-specs.el|Daniel LaLiberte|liberte@holonexus.org 10;; |Edebug specs for cl.el 11 12;; This file is part of GNU Emacs. 13 14;; GNU Emacs is free software; you can redistribute it and/or modify 15;; it under the terms of the GNU General Public License as published by 16;; the Free Software Foundation; either version 2, or (at your option) 17;; any later version. 18 19;; GNU Emacs is distributed in the hope that it will be useful, 20;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22;; GNU General Public License for more details. 23 24;; You should have received a copy of the GNU General Public License 25;; along with GNU Emacs; see the file COPYING. If not, write to the 26;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 27;; Boston, MA 02110-1301, USA. 28 29;;; Commentary: 30 31;; These specs are to be used with edebug.el version 3.3 or later and 32;; cl.el version 2.03 or later, by Dave Gillespie <daveg@synaptics.com>. 33 34;; This file need not be byte-compiled, but it shouldn't hurt. 35 36;;; Code: 37 38(provide 'cl-specs) 39;; Do the above provide before the following require. 40;; Otherwise if you load this before edebug if cl is already loaded 41;; an infinite loading loop would occur. 42(require 'edebug) 43 44;; Blocks 45 46(def-edebug-spec block (symbolp body)) 47(def-edebug-spec return (&optional form)) 48(def-edebug-spec return-from (symbolp &optional form)) 49 50;; Loops 51 52(def-edebug-spec case (form &rest (sexp body))) 53(def-edebug-spec ecase case) 54(def-edebug-spec do 55 ((&rest &or symbolp (symbolp &optional form form)) 56 (form body) 57 cl-declarations body)) 58(def-edebug-spec do* do) 59(def-edebug-spec dolist 60 ((symbolp form &optional form) cl-declarations body)) 61(def-edebug-spec dotimes dolist) 62(def-edebug-spec do-symbols 63 ((symbolp &optional form form) cl-declarations body)) 64(def-edebug-spec do-all-symbols 65 ((symbolp &optional form) cl-declarations body)) 66 67;; Multiple values 68 69(def-edebug-spec multiple-value-list (form)) 70(def-edebug-spec multiple-value-call (function-form body)) 71(def-edebug-spec multiple-value-bind 72 ((&rest symbolp) form cl-declarations body)) 73(def-edebug-spec multiple-value-setq ((&rest symbolp) form)) 74(def-edebug-spec multiple-value-prog1 (form body)) 75 76;; Bindings 77 78(def-edebug-spec lexical-let let) 79(def-edebug-spec lexical-let* let) 80 81(def-edebug-spec psetq setq) 82(def-edebug-spec progv (form form body)) 83 84(def-edebug-spec flet ((&rest (defun*)) cl-declarations body)) 85(def-edebug-spec labels flet) 86 87(def-edebug-spec macrolet 88 ((&rest (&define name (&rest arg) cl-declarations-or-string def-body)) 89 cl-declarations body)) 90 91(def-edebug-spec symbol-macrolet 92 ((&rest (symbol sexp)) cl-declarations body)) 93 94(def-edebug-spec destructuring-bind 95 (&define cl-macro-list form cl-declarations def-body)) 96 97;; Setf 98 99(def-edebug-spec setf (&rest [place form])) ;; sexp is not specific enough 100(def-edebug-spec psetf setf) 101 102(def-edebug-spec letf ;; *not* available in Common Lisp 103 ((&rest (gate place &optional form)) 104 body)) 105(def-edebug-spec letf* letf) 106 107 108(def-edebug-spec defsetf 109 (&define name 110 [&or [symbolp &optional stringp] 111 [cl-lambda-list (symbolp)]] 112 cl-declarations-or-string def-body)) 113 114(def-edebug-spec define-setf-method 115 (&define name cl-lambda-list cl-declarations-or-string def-body)) 116 117(def-edebug-spec define-modify-macro 118 (&define name cl-lambda-list ;; should exclude &key 119 symbolp &optional stringp)) 120 121(def-edebug-spec callf (function* place &rest form)) 122(def-edebug-spec callf2 (function* form place &rest form)) 123 124;; Other operations on places 125 126(def-edebug-spec remf (place form)) 127 128(def-edebug-spec incf (place &optional form)) 129(def-edebug-spec decf incf) 130(def-edebug-spec push (form place)) ; different for CL 131(def-edebug-spec pushnew 132 (form place &rest 133 &or [[&or ":test" ":test-not" ":key"] function-form] 134 [keywordp form])) 135(def-edebug-spec pop (place)) ; different for CL 136 137(def-edebug-spec shiftf (&rest place)) ;; really [&rest place] form 138(def-edebug-spec rotatef (&rest place)) 139 140 141;; Functions with function args. These are only useful if the 142;; function arg is quoted with ' instead of function. 143 144(def-edebug-spec some (function-form form &rest form)) 145(def-edebug-spec every some) 146(def-edebug-spec notany some) 147(def-edebug-spec notevery some) 148 149;; Mapping 150 151(def-edebug-spec map (form function-form form &rest form)) 152(def-edebug-spec maplist (function-form form &rest form)) 153(def-edebug-spec mapc maplist) 154(def-edebug-spec mapl maplist) 155(def-edebug-spec mapcan maplist) 156(def-edebug-spec mapcon maplist) 157 158;; Sequences 159 160(def-edebug-spec reduce (function-form form &rest form)) 161 162;; Types and assertions 163 164(def-edebug-spec cl-type-spec (sexp)) ;; not worth the trouble to specify, yet. 165 166(def-edebug-spec deftype defmacro*) 167(def-edebug-spec check-type (place cl-type-spec &optional stringp)) 168;; (def-edebug-spec assert (form &optional form stringp &rest form)) 169(def-edebug-spec assert (form &rest form)) 170(def-edebug-spec typecase (form &rest ([&or cl-type-spec "otherwise"] body))) 171(def-edebug-spec etypecase typecase) 172 173(def-edebug-spec ignore-errors t) 174 175;; Time of Evaluation 176 177(def-edebug-spec eval-when 178 ((&rest &or "compile" "load" "eval") body)) 179(def-edebug-spec load-time-value (form &optional &or "t" "nil")) 180 181;; Declarations 182 183(def-edebug-spec cl-decl-spec 184 ((symbolp &rest sexp))) 185 186(def-edebug-spec cl-declarations 187 (&rest ("declare" &rest cl-decl-spec))) 188 189(def-edebug-spec cl-declarations-or-string 190 (&or stringp cl-declarations)) 191 192(def-edebug-spec declaim (&rest cl-decl-spec)) 193(def-edebug-spec declare (&rest cl-decl-spec)) ;; probably not needed. 194(def-edebug-spec locally (cl-declarations &rest form)) 195(def-edebug-spec the (cl-type-spec form)) 196 197;;====================================================== 198;; Lambda things 199 200(def-edebug-spec cl-lambda-list 201 (([&rest arg] 202 [&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]] 203 [&optional ["&rest" arg]] 204 [&optional ["&key" [cl-&key-arg &rest cl-&key-arg] 205 &optional "&allow-other-keys"]] 206 [&optional ["&aux" &rest 207 &or (symbolp &optional def-form) symbolp]] 208 ))) 209 210(def-edebug-spec cl-&optional-arg 211 (&or (arg &optional def-form arg) arg)) 212 213(def-edebug-spec cl-&key-arg 214 (&or ([&or (symbolp arg) arg] &optional def-form arg) arg)) 215 216;; The lambda list for macros is different from that of normal lambdas. 217;; Note that &environment is only allowed as first or last items in the 218;; top level list. 219 220(def-edebug-spec cl-macro-list 221 (([&optional "&environment" arg] 222 [&rest cl-macro-arg] 223 [&optional ["&optional" &rest 224 &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] 225 [&optional [[&or "&rest" "&body"] cl-macro-arg]] 226 [&optional ["&key" [&rest 227 [&or ([&or (symbolp cl-macro-arg) arg] 228 &optional def-form cl-macro-arg) 229 arg]] 230 &optional "&allow-other-keys"]] 231 [&optional ["&aux" &rest 232 &or (symbolp &optional def-form) symbolp]] 233 [&optional "&environment" arg] 234 ))) 235 236(def-edebug-spec cl-macro-arg 237 (&or arg cl-macro-list1)) 238 239(def-edebug-spec cl-macro-list1 240 (([&optional "&whole" arg] ;; only allowed at lower levels 241 [&rest cl-macro-arg] 242 [&optional ["&optional" &rest 243 &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] 244 [&optional [[&or "&rest" "&body"] cl-macro-arg]] 245 [&optional ["&key" [&rest 246 [&or ([&or (symbolp cl-macro-arg) arg] 247 &optional def-form cl-macro-arg) 248 arg]] 249 &optional "&allow-other-keys"]] 250 [&optional ["&aux" &rest 251 &or (symbolp &optional def-form) symbolp]] 252 . [&or arg nil]))) 253 254 255(def-edebug-spec defun* 256 ;; Same as defun but use cl-lambda-list. 257 (&define [&or name 258 ("setf" :name setf name)] 259 cl-lambda-list 260 cl-declarations-or-string 261 [&optional ("interactive" interactive)] 262 def-body)) 263(def-edebug-spec defsubst* defun*) 264 265(def-edebug-spec defmacro* 266 (&define name cl-macro-list cl-declarations-or-string def-body)) 267(def-edebug-spec define-compiler-macro defmacro*) 268 269 270(def-edebug-spec function* 271 (&or symbolp cl-lambda-expr)) 272 273(def-edebug-spec cl-lambda-expr 274 (&define ("lambda" cl-lambda-list 275 ;;cl-declarations-or-string 276 ;;[&optional ("interactive" interactive)] 277 def-body))) 278 279;; Redefine function-form to also match function* 280(def-edebug-spec function-form 281 ;; form at the end could also handle "function", 282 ;; but recognize it specially to avoid wrapping function forms. 283 (&or ([&or "quote" "function"] &or symbolp lambda-expr) 284 ("function*" function*) 285 form)) 286 287;;====================================================== 288;; Structures 289;; (def-edebug-spec defstruct (&rest sexp)) would be sufficient, but... 290 291;; defstruct may contain forms that are evaluated when a structure is created. 292(def-edebug-spec defstruct 293 (&define ; makes top-level form not be wrapped 294 [&or symbolp 295 (gate 296 symbolp &rest 297 (&or [":conc-name" &or stringp "nil"] 298 [":constructor" symbolp &optional cl-lambda-list] 299 [":copier" symbolp] 300 [":predicate" symbolp] 301 [":include" symbolp &rest sexp];; not finished 302 ;; The following are not supported. 303 ;; [":print-function" ...] 304 ;; [":type" ...] 305 ;; [":initial-offset" ...] 306 ))] 307 [&optional stringp] 308 ;; All the above is for the following def-form. 309 &rest &or symbolp (symbolp def-form &optional ":read-only" sexp))) 310 311;;====================================================== 312;; Loop 313 314;; The loop macro is very complex, and a full spec is found below. 315;; The following spec only minimally specifies that 316;; parenthesized forms are executable, but single variables used as 317;; expressions will be missed. You may want to use this if the full 318;; spec causes problems for you. 319 320(def-edebug-spec loop 321 (&rest &or symbolp form)) 322 323;; Below is a complete spec for loop, in several parts that correspond 324;; to the syntax given in CLtL2. The specs do more than specify where 325;; the forms are; it also specifies, as much as Edebug allows, all the 326;; syntactically legal loop clauses. The disadvantage of this 327;; completeness is rigidity, but the "for ... being" clause allows 328;; arbitrary extensions of the form: [symbolp &rest &or symbolp form]. 329 330(def-edebug-spec loop 331 ([&optional ["named" symbolp]] 332 [&rest 333 &or 334 ["repeat" form] 335 loop-for-as 336 loop-with 337 loop-initial-final] 338 [&rest loop-clause] 339 )) 340 341(def-edebug-spec loop-with 342 ("with" loop-var 343 loop-type-spec 344 [&optional ["=" form]] 345 &rest ["and" loop-var 346 loop-type-spec 347 [&optional ["=" form]]])) 348 349(def-edebug-spec loop-for-as 350 ([&or "for" "as"] loop-for-as-subclause 351 &rest ["and" loop-for-as-subclause])) 352 353(def-edebug-spec loop-for-as-subclause 354 (loop-var 355 loop-type-spec 356 &or 357 [[&or "in" "on" "in-ref" "across-ref"] 358 form &optional ["by" function-form]] 359 360 ["=" form &optional ["then" form]] 361 ["across" form] 362 ["being" 363 [&or "the" "each"] 364 &or 365 [[&or "element" "elements"] 366 [&or "of" "in" "of-ref"] form 367 &optional "using" ["index" symbolp]];; is this right? 368 [[&or "hash-key" "hash-keys" 369 "hash-value" "hash-values"] 370 [&or "of" "in"] 371 hash-table-p &optional ["using" ([&or "hash-value" "hash-values" 372 "hash-key" "hash-keys"] sexp)]] 373 374 [[&or "symbol" "present-symbol" "external-symbol" 375 "symbols" "present-symbols" "external-symbols"] 376 [&or "in" "of"] package-p] 377 378 ;; Extensions for Emacs Lisp, including Lucid Emacs. 379 [[&or "frame" "frames" 380 "screen" "screens" 381 "buffer" "buffers"]] 382 383 [[&or "window" "windows"] 384 [&or "of" "in"] form] 385 386 [[&or "overlay" "overlays" 387 "extent" "extents"] 388 [&or "of" "in"] form 389 &optional [[&or "from" "to"] form]] 390 391 [[&or "interval" "intervals"] 392 [&or "in" "of"] form 393 &optional [[&or "from" "to"] form] 394 ["property" form]] 395 396 [[&or "key-code" "key-codes" 397 "key-seq" "key-seqs" 398 "key-binding" "key-bindings"] 399 [&or "in" "of"] form 400 &optional ["using" ([&or "key-code" "key-codes" 401 "key-seq" "key-seqs" 402 "key-binding" "key-bindings"] 403 sexp)]] 404 ;; For arbitrary extensions, recognize anything else. 405 [symbolp &rest &or symbolp form] 406 ] 407 408 ;; arithmetic - must be last since all parts are optional. 409 [[&optional [[&or "from" "downfrom" "upfrom"] form]] 410 [&optional [[&or "to" "downto" "upto" "below" "above"] form]] 411 [&optional ["by" form]] 412 ])) 413 414(def-edebug-spec loop-initial-final 415 (&or ["initially" 416 ;; [&optional &or "do" "doing"] ;; CLtL2 doesn't allow this. 417 &rest loop-non-atomic-expr] 418 ["finally" &or 419 [[&optional &or "do" "doing"] &rest loop-non-atomic-expr] 420 ["return" form]])) 421 422(def-edebug-spec loop-and-clause 423 (loop-clause &rest ["and" loop-clause])) 424 425(def-edebug-spec loop-clause 426 (&or 427 [[&or "while" "until" "always" "never" "thereis"] form] 428 429 [[&or "collect" "collecting" 430 "append" "appending" 431 "nconc" "nconcing" 432 "concat" "vconcat"] form 433 [&optional ["into" loop-var]]] 434 435 [[&or "count" "counting" 436 "sum" "summing" 437 "maximize" "maximizing" 438 "minimize" "minimizing"] form 439 [&optional ["into" loop-var]] 440 loop-type-spec] 441 442 [[&or "if" "when" "unless"] 443 form loop-and-clause 444 [&optional ["else" loop-and-clause]] 445 [&optional "end"]] 446 447 [[&or "do" "doing"] &rest loop-non-atomic-expr] 448 449 ["return" form] 450 loop-initial-final 451 )) 452 453(def-edebug-spec loop-non-atomic-expr 454 ([¬ atom] form)) 455 456(def-edebug-spec loop-var 457 ;; The symbolp must be last alternative to recognize e.g. (a b . c) 458 ;; loop-var => 459 ;; (loop-var . [&or nil loop-var]) 460 ;; (symbolp . [&or nil loop-var]) 461 ;; (symbolp . loop-var) 462 ;; (symbolp . (symbolp . [&or nil loop-var])) 463 ;; (symbolp . (symbolp . loop-var)) 464 ;; (symbolp . (symbolp . symbolp)) == (symbolp symbolp . symbolp) 465 (&or (loop-var . [&or nil loop-var]) [gate symbolp])) 466 467(def-edebug-spec loop-type-spec 468 (&optional ["of-type" loop-d-type-spec])) 469 470(def-edebug-spec loop-d-type-spec 471 (&or (loop-d-type-spec . [&or nil loop-d-type-spec]) cl-type-spec)) 472 473;;; arch-tag: b29aa3c2-cf67-4af8-9ee1-318fea61b478 474;;; cl-specs.el ends here 475