| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
(require 'cl) |
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
(defun coerce (x type) |
|---|
| 47 |
"Coerce OBJECT to type TYPE. |
|---|
| 48 |
TYPE is a Common Lisp type specifier. |
|---|
| 49 |
\n(fn OBJECT TYPE)" |
|---|
| 50 |
(cond ((eq type 'list) (if (listp x) x (append x nil))) |
|---|
| 51 |
((eq type 'vector) (if (vectorp x) x (vconcat x))) |
|---|
| 52 |
((eq type 'string) (if (stringp x) x (concat x))) |
|---|
| 53 |
((eq type 'array) (if (arrayp x) x (vconcat x))) |
|---|
| 54 |
((and (eq type 'character) (stringp x) (= (length x) 1)) (aref x 0)) |
|---|
| 55 |
((and (eq type 'character) (symbolp x)) (coerce (symbol-name x) type)) |
|---|
| 56 |
((eq type 'float) (float x)) |
|---|
| 57 |
((typep x type) x) |
|---|
| 58 |
(t (error "Can't coerce %s to type %s" x type)))) |
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
(defun equalp (x y) |
|---|
| 64 |
"Return t if two Lisp objects have similar structures and contents. |
|---|
| 65 |
This is like `equal', except that it accepts numerically equal |
|---|
| 66 |
numbers of different types (float vs. integer), and also compares |
|---|
| 67 |
strings case-insensitively." |
|---|
| 68 |
(cond ((eq x y) t) |
|---|
| 69 |
((stringp x) |
|---|
| 70 |
(and (stringp y) (= (length x) (length y)) |
|---|
| 71 |
(or (string-equal x y) |
|---|
| 72 |
(string-equal (downcase x) (downcase y))))) |
|---|
| 73 |
((numberp x) |
|---|
| 74 |
(and (numberp y) (= x y))) |
|---|
| 75 |
((consp x) |
|---|
| 76 |
(while (and (consp x) (consp y) (equalp (car x) (car y))) |
|---|
| 77 |
(setq x (cdr x) y (cdr y))) |
|---|
| 78 |
(and (not (consp x)) (equalp x y))) |
|---|
| 79 |
((vectorp x) |
|---|
| 80 |
(and (vectorp y) (= (length x) (length y)) |
|---|
| 81 |
(let ((i (length x))) |
|---|
| 82 |
(while (and (>= (setq i (1- i)) 0) |
|---|
| 83 |
(equalp (aref x i) (aref y i)))) |
|---|
| 84 |
(< i 0)))) |
|---|
| 85 |
(t (equal x y)))) |
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
(defun cl-mapcar-many (cl-func cl-seqs) |
|---|
| 91 |
(if (cdr (cdr cl-seqs)) |
|---|
| 92 |
(let* ((cl-res nil) |
|---|
| 93 |
(cl-n (apply 'min (mapcar 'length cl-seqs))) |
|---|
| 94 |
(cl-i 0) |
|---|
| 95 |
(cl-args (copy-sequence cl-seqs)) |
|---|
| 96 |
cl-p1 cl-p2) |
|---|
| 97 |
(setq cl-seqs (copy-sequence cl-seqs)) |
|---|
| 98 |
(while (< cl-i cl-n) |
|---|
| 99 |
(setq cl-p1 cl-seqs cl-p2 cl-args) |
|---|
| 100 |
(while cl-p1 |
|---|
| 101 |
(setcar cl-p2 |
|---|
| 102 |
(if (consp (car cl-p1)) |
|---|
| 103 |
(prog1 (car (car cl-p1)) |
|---|
| 104 |
(setcar cl-p1 (cdr (car cl-p1)))) |
|---|
| 105 |
(aref (car cl-p1) cl-i))) |
|---|
| 106 |
(setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2))) |
|---|
| 107 |
(push (apply cl-func cl-args) cl-res) |
|---|
| 108 |
(setq cl-i (1+ cl-i))) |
|---|
| 109 |
(nreverse cl-res)) |
|---|
| 110 |
(let ((cl-res nil) |
|---|
| 111 |
(cl-x (car cl-seqs)) |
|---|
| 112 |
(cl-y (nth 1 cl-seqs))) |
|---|
| 113 |
(let ((cl-n (min (length cl-x) (length cl-y))) |
|---|
| 114 |
(cl-i -1)) |
|---|
| 115 |
(while (< (setq cl-i (1+ cl-i)) cl-n) |
|---|
| 116 |
(push (funcall cl-func |
|---|
| 117 |
(if (consp cl-x) (pop cl-x) (aref cl-x cl-i)) |
|---|
| 118 |
(if (consp cl-y) (pop cl-y) (aref cl-y cl-i))) |
|---|
| 119 |
cl-res))) |
|---|
| 120 |
(nreverse cl-res)))) |
|---|
| 121 |
|
|---|
| 122 |
(defun map (cl-type cl-func cl-seq &rest cl-rest) |
|---|
| 123 |
"Map a FUNCTION across one or more SEQUENCEs, returning a sequence. |
|---|
| 124 |
TYPE is the sequence type to return. |
|---|
| 125 |
\n(fn TYPE FUNCTION SEQUENCE...)" |
|---|
| 126 |
(let ((cl-res (apply 'mapcar* cl-func cl-seq cl-rest))) |
|---|
| 127 |
(and cl-type (coerce cl-res cl-type)))) |
|---|
| 128 |
|
|---|
| 129 |
(defun maplist (cl-func cl-list &rest cl-rest) |
|---|
| 130 |
"Map FUNCTION to each sublist of LIST or LISTs. |
|---|
| 131 |
Like `mapcar', except applies to lists and their cdr's rather than to |
|---|
| 132 |
the elements themselves. |
|---|
| 133 |
\n(fn FUNCTION LIST...)" |
|---|
| 134 |
(if cl-rest |
|---|
| 135 |
(let ((cl-res nil) |
|---|
| 136 |
(cl-args (cons cl-list (copy-sequence cl-rest))) |
|---|
| 137 |
cl-p) |
|---|
| 138 |
(while (not (memq nil cl-args)) |
|---|
| 139 |
(push (apply cl-func cl-args) cl-res) |
|---|
| 140 |
(setq cl-p cl-args) |
|---|
| 141 |
(while cl-p (setcar cl-p (cdr (pop cl-p)) ))) |
|---|
| 142 |
(nreverse cl-res)) |
|---|
| 143 |
(let ((cl-res nil)) |
|---|
| 144 |
(while cl-list |
|---|
| 145 |
(push (funcall cl-func cl-list) cl-res) |
|---|
| 146 |
(setq cl-list (cdr cl-list))) |
|---|
| 147 |
(nreverse cl-res)))) |
|---|
| 148 |
|
|---|
| 149 |
(defun cl-mapc (cl-func cl-seq &rest cl-rest) |
|---|
| 150 |
"Like `mapcar', but does not accumulate values returned by the function. |
|---|
| 151 |
\n(fn FUNCTION SEQUENCE...)" |
|---|
| 152 |
(if cl-rest |
|---|
| 153 |
(progn (apply 'map nil cl-func cl-seq cl-rest) |
|---|
| 154 |
cl-seq) |
|---|
| 155 |
(mapc cl-func cl-seq))) |
|---|
| 156 |
|
|---|
| 157 |
(defun mapl (cl-func cl-list &rest cl-rest) |
|---|
| 158 |
"Like `maplist', but does not accumulate values returned by the function. |
|---|
| 159 |
\n(fn FUNCTION LIST...)" |
|---|
| 160 |
(if cl-rest |
|---|
| 161 |
(apply 'maplist cl-func cl-list cl-rest) |
|---|
| 162 |
(let ((cl-p cl-list)) |
|---|
| 163 |
(while cl-p (funcall cl-func cl-p) (setq cl-p (cdr cl-p))))) |
|---|
| 164 |
cl-list) |
|---|
| 165 |
|
|---|
| 166 |
(defun mapcan (cl-func cl-seq &rest cl-rest) |
|---|
| 167 |
"Like `mapcar', but nconc's together the values returned by the function. |
|---|
| 168 |
\n(fn FUNCTION SEQUENCE...)" |
|---|
| 169 |
(apply 'nconc (apply 'mapcar* cl-func cl-seq cl-rest))) |
|---|
| 170 |
|
|---|
| 171 |
(defun mapcon (cl-func cl-list &rest cl-rest) |
|---|
| 172 |
"Like `maplist', but nconc's together the values returned by the function. |
|---|
| 173 |
\n(fn FUNCTION LIST...)" |
|---|
| 174 |
(apply 'nconc (apply 'maplist cl-func cl-list cl-rest))) |
|---|
| 175 |
|
|---|
| 176 |
(defun some (cl-pred cl-seq &rest cl-rest) |
|---|
| 177 |
"Return true if PREDICATE is true of any element of SEQ or SEQs. |
|---|
| 178 |
If so, return the true (non-nil) value returned by PREDICATE. |
|---|
| 179 |
\n(fn PREDICATE SEQ...)" |
|---|
| 180 |
(if (or cl-rest (nlistp cl-seq)) |
|---|
| 181 |
(catch 'cl-some |
|---|
| 182 |
(apply 'map nil |
|---|
| 183 |
(function (lambda (&rest cl-x) |
|---|
| 184 |
(let ((cl-res (apply cl-pred cl-x))) |
|---|
| 185 |
(if cl-res (throw 'cl-some cl-res))))) |
|---|
| 186 |
cl-seq cl-rest) nil) |
|---|
| 187 |
(let ((cl-x nil)) |
|---|
| 188 |
(while (and cl-seq (not (setq cl-x (funcall cl-pred (pop cl-seq)))))) |
|---|
| 189 |
cl-x))) |
|---|
| 190 |
|
|---|
| 191 |
(defun every (cl-pred cl-seq &rest cl-rest) |
|---|
| 192 |
"Return true if PREDICATE is true of every element of SEQ or SEQs. |
|---|
| 193 |
\n(fn PREDICATE SEQ...)" |
|---|
| 194 |
(if (or cl-rest (nlistp cl-seq)) |
|---|
| 195 |
(catch 'cl-every |
|---|
| 196 |
(apply 'map nil |
|---|
| 197 |
(function (lambda (&rest cl-x) |
|---|
| 198 |
(or (apply cl-pred cl-x) (throw 'cl-every nil)))) |
|---|
| 199 |
cl-seq cl-rest) t) |
|---|
| 200 |
(while (and cl-seq (funcall cl-pred (car cl-seq))) |
|---|
| 201 |
(setq cl-seq (cdr cl-seq))) |
|---|
| 202 |
(null cl-seq))) |
|---|
| 203 |
|
|---|
| 204 |
(defun notany (cl-pred cl-seq &rest cl-rest) |
|---|
| 205 |
"Return true if PREDICATE is false of every element of SEQ or SEQs. |
|---|
| 206 |
\n(fn PREDICATE SEQ...)" |
|---|
| 207 |
(not (apply 'some cl-pred cl-seq cl-rest))) |
|---|
| 208 |
|
|---|
| 209 |
(defun notevery (cl-pred cl-seq &rest cl-rest) |
|---|
| 210 |
"Return true if PREDICATE is false of some element of SEQ or SEQs. |
|---|
| 211 |
\n(fn PREDICATE SEQ...)" |
|---|
| 212 |
(not (apply 'every cl-pred cl-seq cl-rest))) |
|---|
| 213 |
|
|---|
| 214 |
|
|---|
| 215 |
(defalias 'cl-map-keymap 'map-keymap) |
|---|
| 216 |
|
|---|
| 217 |
(defun cl-map-keymap-recursively (cl-func-rec cl-map &optional cl-base) |
|---|
| 218 |
(or cl-base |
|---|
| 219 |
(setq cl-base (copy-sequence [0]))) |
|---|
| 220 |
(map-keymap |
|---|
| 221 |
(function |
|---|
| 222 |
(lambda (cl-key cl-bind) |
|---|
| 223 |
(aset cl-base (1- (length cl-base)) cl-key) |
|---|
| 224 |
(if (keymapp cl-bind) |
|---|
| 225 |
(cl-map-keymap-recursively |
|---|
| 226 |
cl-func-rec cl-bind |
|---|
| 227 |
(vconcat cl-base (list 0))) |
|---|
| 228 |
(funcall cl-func-rec cl-base cl-bind)))) |
|---|
| 229 |
cl-map)) |
|---|
| 230 |
|
|---|
| 231 |
(defun cl-map-intervals (cl-func &optional cl-what cl-prop cl-start cl-end) |
|---|
| 232 |
(or cl-what (setq cl-what (current-buffer))) |
|---|
| 233 |
(if (bufferp cl-what) |
|---|
| 234 |
(let (cl-mark cl-mark2 (cl-next t) cl-next2) |
|---|
| 235 |
(with-current-buffer cl-what |
|---|
| 236 |
(setq cl-mark (copy-marker (or cl-start (point-min)))) |
|---|
| 237 |
(setq cl-mark2 (and cl-end (copy-marker cl-end)))) |
|---|
| 238 |
(while (and cl-next (or (not cl-mark2) (< cl-mark cl-mark2))) |
|---|
| 239 |
(setq cl-next (if cl-prop (next-single-property-change |
|---|
| 240 |
cl-mark cl-prop cl-what) |
|---|
| 241 |
(next-property-change cl-mark cl-what)) |
|---|
| 242 |
cl-next2 (or cl-next (with-current-buffer cl-what |
|---|
| 243 |
(point-max)))) |
|---|
| 244 |
(funcall cl-func (prog1 (marker-position cl-mark) |
|---|
| 245 |
(set-marker cl-mark cl-next2)) |
|---|
| 246 |
(if cl-mark2 (min cl-next2 cl-mark2) cl-next2))) |
|---|
| 247 |
(set-marker cl-mark nil) (if cl-mark2 (set-marker cl-mark2 nil))) |
|---|
| 248 |
(or cl-start (setq cl-start 0)) |
|---|
| 249 |
(or cl-end (setq cl-end (length cl-what))) |
|---|
| 250 |
(while (< cl-start cl-end) |
|---|
| 251 |
(let ((cl-next (or (if cl-prop (next-single-property-change |
|---|
| 252 |
cl-start cl-prop cl-what) |
|---|
| 253 |
(next-property-change cl-start cl-what)) |
|---|
| 254 |
cl-end))) |
|---|
| 255 |
(funcall cl-func cl-start (min cl-next cl-end)) |
|---|
| 256 |
(setq cl-start cl-next))))) |
|---|
| 257 |
|
|---|
| 258 |
(defun cl-map-overlays (cl-func &optional cl-buffer cl-start cl-end cl-arg) |
|---|
| 259 |
(or cl-buffer (setq cl-buffer (current-buffer))) |
|---|
| 260 |
(if (fboundp 'overlay-lists) |
|---|
| 261 |
|
|---|
| 262 |
|
|---|
| 263 |
(let (cl-ovl) |
|---|
| 264 |
(with-current-buffer cl-buffer |
|---|
| 265 |
(setq cl-ovl (overlay-lists)) |
|---|
| 266 |
(if cl-start (setq cl-start (copy-marker cl-start))) |
|---|
| 267 |
(if cl-end (setq cl-end (copy-marker cl-end)))) |
|---|
| 268 |
(setq cl-ovl (nconc (car cl-ovl) (cdr cl-ovl))) |
|---|
| 269 |
(while (and cl-ovl |
|---|
| 270 |
(or (not (overlay-start (car cl-ovl))) |
|---|
| 271 |
(and cl-end (>= (overlay-start (car cl-ovl)) cl-end)) |
|---|
| 272 |
(and cl-start (<= (overlay-end (car cl-ovl)) cl-start)) |
|---|
| 273 |
(not (funcall cl-func (car cl-ovl) cl-arg)))) |
|---|
| 274 |
(setq cl-ovl (cdr cl-ovl))) |
|---|
| 275 |
(if cl-start (set-marker cl-start nil)) |
|---|
| 276 |
(if cl-end (set-marker cl-end nil))) |
|---|
| 277 |
|
|---|
| 278 |
|
|---|
| 279 |
(let ((cl-mark (with-current-buffer cl-buffer |
|---|
| 280 |
(copy-marker (or cl-start (point-min))))) |
|---|
| 281 |
(cl-mark2 (and cl-end (with-current-buffer cl-buffer |
|---|
| 282 |
(copy-marker cl-end)))) |
|---|
| 283 |
cl-pos cl-ovl) |
|---|
| 284 |
(while (save-excursion |
|---|
| 285 |
(and (setq cl-pos (marker-position cl-mark)) |
|---|
| 286 |
(< cl-pos (or cl-mark2 (point-max))) |
|---|
| 287 |
(progn |
|---|
| 288 |
(set-buffer cl-buffer) |
|---|
| 289 |
(setq cl-ovl (overlays-at cl-pos)) |
|---|
| 290 |
(set-marker cl-mark (next-overlay-change cl-pos))))) |
|---|
| 291 |
(while (and cl-ovl |
|---|
| 292 |
(or (/= (overlay-start (car cl-ovl)) cl-pos) |
|---|
| 293 |
(not (and (funcall cl-func (car cl-ovl) cl-arg) |
|---|
| 294 |
(set-marker cl-mark nil))))) |
|---|
| 295 |
(setq cl-ovl (cdr cl-ovl)))) |
|---|
| 296 |
(set-marker cl-mark nil) (if cl-mark2 (set-marker cl-mark2 nil))))) |
|---|
| 297 |
|
|---|
| 298 |
|
|---|
| 299 |
(defun cl-set-frame-visible-p (frame val) |
|---|
| 300 |
(cond ((null val) (make-frame-invisible frame)) |
|---|
| 301 |
((eq val 'icon) (iconify-frame frame)) |
|---|
| 302 |
(t (make-frame-visible frame))) |
|---|
| 303 |
val) |
|---|
| 304 |
|
|---|
| 305 |
|
|---|
| 306 |
(defvar cl-progv-save) |
|---|
| 307 |
(defun cl-progv-before (syms values) |
|---|
| 308 |
(while syms |
|---|
| 309 |
(push (if (boundp (car syms)) |
|---|
| 310 |
(cons (car syms) (symbol-value (car syms))) |
|---|
| 311 |
(car syms)) cl-progv-save) |
|---|
| 312 |
(if values |
|---|
| 313 |
(set (pop syms) (pop values)) |
|---|
| 314 |
(makunbound (pop syms))))) |
|---|
| 315 |
|
|---|
| 316 |
(defun cl-progv-after () |
|---|
| 317 |
(while cl-progv-save |
|---|
| 318 |
(if (consp (car cl-progv-save)) |
|---|
| 319 |
(set (car (car cl-progv-save)) (cdr (car cl-progv-save))) |
|---|
| 320 |
(makunbound (car cl-progv-save))) |
|---|
| 321 |
(pop cl-progv-save))) |
|---|
| 322 |
|
|---|
| 323 |
|
|---|
| 324 |
|
|---|
| 325 |
|
|---|
| 326 |
(defun gcd (&rest args) |
|---|
| 327 |
"Return the greatest common divisor of the arguments." |
|---|
| 328 |
(let ((a (abs (or (pop args) 0)))) |
|---|
| 329 |
(while args |
|---|
| 330 |
(let ((b (abs (pop args)))) |
|---|
| 331 |
(while (> b 0) (setq b (% a (setq a b)))))) |
|---|
| 332 |
a)) |
|---|
| 333 |
|
|---|
| 334 |
(defun lcm (&rest args) |
|---|
| 335 |
"Return the least common multiple of the arguments." |
|---|
| 336 |
(if (memq 0 args) |
|---|
| 337 |
0 |
|---|
| 338 |
(let ((a (abs (or (pop args) 1)))) |
|---|
| 339 |
(while args |
|---|
| 340 |
(let ((b (abs (pop args)))) |
|---|
| 341 |
(setq a (* (/ a (gcd a b)) b)))) |
|---|
| 342 |
a))) |
|---|
| 343 |
|
|---|
| 344 |
(defun isqrt (x) |
|---|
| 345 |
"Return the integer square root of the argument." |
|---|
| 346 |
(if (and (integerp x) (> x 0)) |
|---|
| 347 |
(let ((g (cond ((<= x 100) 10) ((<= x 10000) 100) |
|---|
| 348 |
((<= x 1000000) 1000) (t x))) |
|---|
| 349 |
g2) |
|---|
| 350 |
(while (< (setq g2 (/ (+ g (/ x g)) 2)) g) |
|---|
| 351 |
(setq g g2)) |
|---|
| 352 |
g) |
|---|
| 353 |
(if (eq x 0) 0 (signal 'arith-error nil)))) |
|---|
| 354 |
|
|---|
| 355 |
(defun floor* (x &optional y) |
|---|
| 356 |
"Return a list of the floor of X and the fractional part of X. |
|---|
| 357 |
With two arguments, return floor and remainder of their quotient." |
|---|
| 358 |
(let ((q (floor x y))) |
|---|
| 359 |
(list q (- x (if y (* y q) q))))) |
|---|
| 360 |
|
|---|
| 361 |
(defun ceiling* (x &optional y) |
|---|
| 362 |
"Return a list of the ceiling of X and the fractional part of X. |
|---|
| 363 |
With two arguments, return ceiling and remainder of their quotient." |
|---|
| 364 |
(let ((res (floor* x y))) |
|---|
| 365 |
(if (= (car (cdr res)) 0) res |
|---|
| 366 |
(list (1+ (car res)) (- (car (cdr res)) (or y 1)))))) |
|---|
| 367 |
|
|---|
| 368 |
(defun truncate* (x &optional y) |
|---|
| 369 |
"Return a list of the integer part of X and the fractional part of X. |
|---|
| 370 |
With two arguments, return truncation and remainder of their quotient." |
|---|
| 371 |
(if (eq (>= x 0) (or (null y) (>= y 0))) |
|---|
| 372 |
(floor* x y) (ceiling* x y))) |
|---|
| 373 |
|
|---|
| 374 |
(defun round* (x &optional y) |
|---|
| 375 |
"Return a list of X rounded to the nearest integer and the remainder. |
|---|
| 376 |
With two arguments, return rounding and remainder of their quotient." |
|---|
| 377 |
(if y |
|---|
| 378 |
(if (and (integerp x) (integerp y)) |
|---|
| 379 |
(let* ((hy (/ y 2)) |
|---|
| 380 |
(res (floor* (+ x hy) y))) |
|---|
| 381 |
(if (and (= (car (cdr res)) 0) |
|---|
| 382 |
(= (+ hy hy) y) |
|---|
| 383 |
(/= (% (car res) 2) 0)) |
|---|
| 384 |
(list (1- (car res)) hy) |
|---|
| 385 |
(list (car res) (- (car (cdr res)) hy)))) |
|---|
| 386 |
(let ((q (round (/ x y)))) |
|---|
| 387 |
(list q (- x (* q y))))) |
|---|
| 388 |
(if (integerp x) (list x 0) |
|---|
| 389 |
(let ((q (round x))) |
|---|
| 390 |
(list q (- x q)))))) |
|---|
| 391 |
|
|---|
| 392 |
(defun mod* (x y) |
|---|
| 393 |
"The remainder of X divided by Y, with the same sign as Y." |
|---|
| 394 |
(nth 1 (floor* x y))) |
|---|
| 395 |
|
|---|
| 396 |
(defun rem* (x y) |
|---|
| 397 |
"The remainder of X divided by Y, with the same sign as X." |
|---|
| 398 |
(nth 1 (truncate* x y))) |
|---|
| 399 |
|
|---|
| 400 |
(defun signum (x) |
|---|
| 401 |
"Return 1 if X is positive, -1 if negative, 0 if zero." |
|---|
| 402 |
(cond ((> x 0) 1) ((< x 0) -1) (t 0))) |
|---|
| 403 |
|
|---|
| 404 |
|
|---|
| 405 |
|
|---|
| 406 |
|
|---|
| 407 |
(defvar *random-state*) |
|---|
| 408 |
(defun random* (lim &optional state) |
|---|
| 409 |
"Return a random nonnegative number less than LIM, an integer or float. |
|---|
| 410 |
Optional second arg STATE is a random-state object." |
|---|
| 411 |
(or state (setq state *random-state*)) |
|---|
| 412 |
|
|---|
| 413 |
(let ((vec (aref state 3))) |
|---|
| 414 |
(if (integerp vec) |
|---|
| 415 |
(let ((i 0) (j (- 1357335 (% (abs vec) 1357333))) (k 1) ii) |
|---|
| 416 |
(aset state 3 (setq vec (make-vector 55 nil))) |
|---|
| 417 |
(aset vec 0 j) |
|---|
| 418 |
(while (> (setq i (% (+ i 21) 55)) 0) |
|---|
| 419 |
(aset vec i (setq j (prog1 k (setq k (- j k)))))) |
|---|
| 420 |
(while (< (setq i (1+ i)) 200) (random* 2 state)))) |
|---|
| 421 |
(let* ((i (aset state 1 (% (1+ (aref state 1)) 55))) |
|---|
| 422 |
(j (aset state 2 (% (1+ (aref state 2)) 55))) |
|---|
| 423 |
(n (logand 8388607 (aset vec i (- (aref vec i) (aref vec j)))))) |
|---|
| 424 |
(if (integerp lim) |
|---|
| 425 |
(if (<= lim 512) (% n lim) |
|---|
| 426 |
(if (> lim 8388607) (setq n (+ (lsh n 9) (random* 512 state)))) |
|---|
| 427 |
(let ((mask 1023)) |
|---|
| 428 |
(while (< mask (1- lim)) (setq mask (1+ (+ mask mask)))) |
|---|
| 429 |
(if (< (setq n (logand n mask)) lim) n (random* lim state)))) |
|---|
| 430 |
(* (/ n '8388608e0) lim))))) |
|---|
| 431 |
|
|---|
| 432 |
(defun make-random-state (&optional state) |
|---|
| 433 |
"Return a copy of random-state STATE, or of `*random-state*' if omitted. |
|---|
| 434 |
If STATE is t, return a new state object seeded from the time of day." |
|---|
| 435 |
(cond ((null state) (make-random-state *random-state*)) |
|---|
| 436 |
((vectorp state) (cl-copy-tree state t)) |
|---|
| 437 |
((integerp state) (vector 'cl-random-state-tag -1 30 state)) |
|---|
| 438 |
(t (make-random-state (cl-random-time))))) |
|---|
| 439 |
|
|---|
| 440 |
(defun random-state-p (object) |
|---|
| 441 |
"Return t if OBJECT is a random-state object." |
|---|
| 442 |
(and (vectorp object) (= (length object) 4) |
|---|
| 443 |
(eq (aref object 0) 'cl-random-state-tag))) |
|---|
| 444 |
|
|---|
| 445 |
|
|---|
| 446 |
|
|---|
| 447 |
|
|---|
| 448 |
(defun cl-finite-do (func a b) |
|---|
| 449 |
(condition-case err |
|---|
| 450 |
(let ((res (funcall func a b))) |
|---|
| 451 |
(and (numberp res) (/= res (/ res 2)) res)) |
|---|
| 452 |
(arith-error nil))) |
|---|
| 453 |
|
|---|
| 454 |
(defvar most-positive-float) |
|---|
| 455 |
(defvar most-negative-float) |
|---|
| 456 |
(defvar least-positive-float) |
|---|
| 457 |
(defvar least-negative-float) |
|---|
| 458 |
(defvar least-positive-normalized-float) |
|---|
| 459 |
(defvar least-negative-normalized-float) |
|---|
| 460 |
(defvar float-epsilon) |
|---|
| 461 |
(defvar float-negative-epsilon) |
|---|
| 462 |
|
|---|
| 463 |
(defun cl-float-limits () |
|---|
| 464 |
(or most-positive-float (not (numberp '2e1)) |
|---|
| 465 |
(let ((x '2e0) y z) |
|---|
| 466 |
|
|---|
| 467 |
(while (cl-finite-do '* x x) (setq x (* x x))) |
|---|
| 468 |
(while (cl-finite-do '* x (/ x 2)) (setq x (* x (/ x 2)))) |
|---|
| 469 |
(while (cl-finite-do '+ x x) (setq x (+ x x))) |
|---|
| 470 |
(setq z x y (/ x 2)) |
|---|
| 471 |
|
|---|
| 472 |
(while (and (cl-finite-do '+ x y) (/= (+ x y) x)) |
|---|
| 473 |
(setq x (+ x y) y (/ y 2))) |
|---|
| 474 |
(setq most-positive-float x |
|---|
| 475 |
most-negative-float (- x)) |
|---|
| 476 |
|
|---|
| 477 |
(setq x (/ x z) y (/ 16 z) x (* x y)) |
|---|
| 478 |
(while (condition-case err (and (= x (* (/ x 2) 2)) (> (/ y 2) 0)) |
|---|
| 479 |
(arith-error nil)) |
|---|
| 480 |
(setq x (/ x 2) y (/ y 2))) |
|---|
| 481 |
(setq least-positive-normalized-float y |
|---|
| 482 |
least-negative-normalized-float (- y)) |
|---|
| 483 |
|
|---|
| 484 |
(setq x (/ 1 z) y x) |
|---|
| 485 |
(while (condition-case err (> (/ x 2) 0) (arith-error nil)) |
|---|
| 486 |
(setq x (/ x 2))) |
|---|
| 487 |
(setq least-positive-float x |
|---|
| 488 |
least-negative-float (- x)) |
|---|
| 489 |
(setq x '1e0) |
|---|
| 490 |
(while (/= (+ '1e0 x) '1e0) (setq x (/ x 2))) |
|---|
| 491 |
(setq float-epsilon (* x 2)) |
|---|
| 492 |
(setq x '1e0) |
|---|
| 493 |
(while (/= (- '1e0 x) '1e0) (setq x (/ x 2))) |
|---|
| 494 |
(setq float-negative-epsilon (* x 2)))) |
|---|
| 495 |
nil) |
|---|
| 496 |
|
|---|
| 497 |
|
|---|
| 498 |
|
|---|
| 499 |
|
|---|
| 500 |
(defun subseq (seq start &optional end) |
|---|
| 501 |
"Return the subsequence of SEQ from START to END. |
|---|
| 502 |
If END is omitted, it defaults to the length of the sequence. |
|---|
| 503 |
If START or END is negative, it counts from the end." |
|---|
| 504 |
(if (stringp seq) (substring seq start end) |
|---|
| 505 |
(let (len) |
|---|
| 506 |
(and end (< end 0) (setq end (+ end (setq len (length seq))))) |
|---|
| 507 |
(if (< start 0) (setq start (+ start (or len (setq len (length seq)))))) |
|---|
| 508 |
(cond ((listp seq) |
|---|
| 509 |
(if (> start 0) (setq seq (nthcdr start seq))) |
|---|
| 510 |
(if end |
|---|
| 511 |
(let ((res nil)) |
|---|
| 512 |
(while (>= (setq end (1- end)) start) |
|---|
| 513 |
(push (pop seq) res)) |
|---|
| 514 |
(nreverse res)) |
|---|
| 515 |
(copy-sequence seq))) |
|---|
| 516 |
(t |
|---|
| 517 |
(or end (setq end (or len (length seq)))) |
|---|
| 518 |
(let ((res (make-vector (max (- end start) 0) nil)) |
|---|
| 519 |
(i 0)) |
|---|
| 520 |
(while (< start end) |
|---|
| 521 |
(aset res i (aref seq start)) |
|---|
| 522 |
(setq i (1+ i) start (1+ start))) |
|---|
| 523 |
res)))))) |
|---|
| 524 |
|
|---|
| 525 |
(defun concatenate (type &rest seqs) |
|---|
| 526 |
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs. |
|---|
| 527 |
\n(fn TYPE SEQUENCE...)" |
|---|
| 528 |
(cond ((eq type 'vector) (apply 'vconcat seqs)) |
|---|
| 529 |
((eq type 'string) (apply 'concat seqs)) |
|---|
| 530 |
((eq type 'list) (apply 'append (append seqs '(nil)))) |
|---|
| 531 |
(t (error "Not a sequence type name: %s" type)))) |
|---|
| 532 |
|
|---|
| 533 |
|
|---|
| 534 |
|
|---|
| 535 |
|
|---|
| 536 |
(defun revappend (x y) |
|---|
| 537 |
"Equivalent to (append (reverse X) Y)." |
|---|
| 538 |
(nconc (reverse x) y)) |
|---|
| 539 |
|
|---|
| 540 |
(defun nreconc (x y) |
|---|
| 541 |
"Equivalent to (nconc (nreverse X) Y)." |
|---|
| 542 |
(nconc (nreverse x) y)) |
|---|
| 543 |
|
|---|
| 544 |
(defun list-length (x) |
|---|
| 545 |
"Return the length of list X. Return nil if list is circular." |
|---|
| 546 |
(let ((n 0) (fast x) (slow x)) |
|---|
| 547 |
(while (and (cdr fast) (not (and (eq fast slow) (> n 0)))) |
|---|
| 548 |
(setq n (+ n 2) fast (cdr (cdr fast)) slow (cdr slow))) |
|---|
| 549 |
(if fast (if (cdr fast) nil (1+ n)) n))) |
|---|
| 550 |
|
|---|
| 551 |
(defun tailp (sublist list) |
|---|
| 552 |
"Return true if SUBLIST is a tail of LIST." |
|---|
| 553 |
(while (and (consp list) (not (eq sublist list))) |
|---|
| 554 |
(setq list (cdr list))) |
|---|
| 555 |
(if (numberp sublist) (equal sublist list) (eq sublist list))) |
|---|
| 556 |
|
|---|
| 557 |
(defalias 'cl-copy-tree 'copy-tree) |
|---|
| 558 |
|
|---|
| 559 |
|
|---|
| 560 |
|
|---|
| 561 |
|
|---|
| 562 |
(defun get* (sym tag &optional def) |
|---|
| 563 |
"Return the value of SYMBOL's PROPNAME property, or DEFAULT if none. |
|---|
| 564 |
\n(fn SYMBOL PROPNAME &optional DEFAULT)" |
|---|
| 565 |
(or (get sym tag) |
|---|
| 566 |
(and def |
|---|
| 567 |
(let ((plist (symbol-plist sym))) |
|---|
| 568 |
(while (and plist (not (eq (car plist) tag))) |
|---|
| 569 |
(setq plist (cdr (cdr plist)))) |
|---|
| 570 |
(if plist (car (cdr plist)) def))))) |
|---|
| 571 |
|
|---|
| 572 |
(defun getf (plist tag &optional def) |
|---|
| 573 |
"Search PROPLIST for property PROPNAME; return its value or DEFAULT. |
|---|
| 574 |
PROPLIST is a list of the sort returned by `symbol-plist'. |
|---|
| 575 |
\n(fn PROPLIST PROPNAME &optional DEFAULT)" |
|---|
| 576 |
(setplist '--cl-getf-symbol-- plist) |
|---|
| 577 |
(or (get '--cl-getf-symbol-- tag) |
|---|
| 578 |
|
|---|
| 579 |
|
|---|
| 580 |
|
|---|
| 581 |
(when def |
|---|
| 582 |
(while (and plist (not (eq (car plist) tag))) |
|---|
| 583 |
(setq plist (cdr (cdr plist)))) |
|---|
| 584 |
(if plist (car (cdr plist)) def)))) |
|---|
| 585 |
|
|---|
| 586 |
(defun cl-set-getf (plist tag val) |
|---|
| 587 |
(let ((p plist)) |
|---|
| 588 |
(while (and p (not (eq (car p) tag))) (setq p (cdr (cdr p)))) |
|---|
| 589 |
(if p (progn (setcar (cdr p) val) plist) (list* tag val plist)))) |
|---|
| 590 |
|
|---|
| 591 |
(defun cl-do-remf (plist tag) |
|---|
| 592 |
(let ((p (cdr plist))) |
|---|
| 593 |
(while (and (cdr p) (not (eq (car (cdr p)) tag))) (setq p (cdr (cdr p)))) |
|---|
| 594 |
(and (cdr p) (progn (setcdr p (cdr (cdr (cdr p)))) t)))) |
|---|
| 595 |
|
|---|
| 596 |
(defun cl-remprop (sym tag) |
|---|
| 597 |
"Remove from SYMBOL's plist the property PROPNAME and its value. |
|---|
| 598 |
\n(fn SYMBOL PROPNAME)" |
|---|
| 599 |
(let ((plist (symbol-plist sym))) |
|---|
| 600 |
(if (and plist (eq tag (car plist))) |
|---|
| 601 |
(progn (setplist sym (cdr (cdr plist))) t) |
|---|
| 602 |
(cl-do-remf plist tag)))) |
|---|
| 603 |
(defalias 'remprop 'cl-remprop) |
|---|
| 604 |
|
|---|
| 605 |
|
|---|
| 606 |
|
|---|
| 607 |
|
|---|
| 608 |
|
|---|
| 609 |
|
|---|
| 610 |
|
|---|
| 611 |
(defun cl-not-hash-table (x &optional y &rest z) |
|---|
| 612 |
(signal 'wrong-type-argument (list 'cl-hash-table-p (or y x)))) |
|---|
| 613 |
|
|---|
| 614 |
(defvar cl-builtin-gethash (symbol-function 'gethash)) |
|---|
| 615 |
(defvar cl-builtin-remhash (symbol-function 'remhash)) |
|---|
| 616 |
(defvar cl-builtin-clrhash (symbol-function 'clrhash)) |
|---|
| 617 |
(defvar cl-builtin-maphash (symbol-function 'maphash)) |
|---|
| 618 |
|
|---|
| 619 |
(defalias 'cl-gethash 'gethash) |
|---|
| 620 |
(defalias 'cl-puthash 'puthash) |
|---|
| 621 |
(defalias 'cl-remhash 'remhash) |
|---|
| 622 |
(defalias 'cl-clrhash 'clrhash) |
|---|
| 623 |
(defalias 'cl-maphash 'maphash) |
|---|
| 624 |
|
|---|
| 625 |
(defalias 'cl-make-hash-table 'make-hash-table) |
|---|
| 626 |
(defalias 'cl-hash-table-p 'hash-table-p) |
|---|
| 627 |
(defalias 'cl-hash-table-count 'hash-table-count) |
|---|
| 628 |
|
|---|
| 629 |
|
|---|
| 630 |
|
|---|
| 631 |
(defun cl-prettyprint (form) |
|---|
| 632 |
"Insert a pretty-printed rendition of a Lisp FORM in current buffer." |
|---|
| 633 |
(let ((pt (point)) last) |
|---|
| 634 |
(insert "\n" (prin1-to-string form) "\n") |
|---|
| 635 |
(setq last (point)) |
|---|
| 636 |
(goto-char (1+ pt)) |
|---|
| 637 |
(while (search-forward "(quote " last t) |
|---|
| 638 |
(delete-backward-char 7) |
|---|
| 639 |
(insert "'") |
|---|
| 640 |
(forward-sexp) |
|---|
| 641 |
(delete-char 1)) |
|---|
| 642 |
(goto-char (1+ pt)) |
|---|
| 643 |
(cl-do-prettyprint))) |
|---|
| 644 |
|
|---|
| 645 |
(defun cl-do-prettyprint () |
|---|
| 646 |
(skip-chars-forward " ") |
|---|
| 647 |
(if (looking-at "(") |
|---|
| 648 |
(let ((skip (or (looking-at "((") (looking-at "(prog") |
|---|
| 649 |
(looking-at "(unwind-protect ") |
|---|
| 650 |
(looking-at "(function (") |
|---|
| 651 |
(looking-at "(cl-block-wrapper "))) |
|---|
| 652 |
(two (or (looking-at "(defun ") (looking-at "(defmacro "))) |
|---|
| 653 |
(let (or (looking-at "(let\\*? ") (looking-at "(while "))) |
|---|
| 654 |
(set (looking-at "(p?set[qf] "))) |
|---|
| 655 |
(if (or skip let |
|---|
| 656 |
(progn |
|---|
| 657 |
(forward-sexp) |
|---|
| 658 |
(and (>= (current-column) 78) (progn (backward-sexp) t)))) |
|---|
| 659 |
(let ((nl t)) |
|---|
| 660 |
(forward-char 1) |
|---|
| 661 |
(cl-do-prettyprint) |
|---|
| 662 |
(or skip (looking-at ")") (cl-do-prettyprint)) |
|---|
| 663 |
(or (not two) (looking-at ")") (cl-do-prettyprint)) |
|---|
| 664 |
(while (not (looking-at ")")) |
|---|
| 665 |
(if set (setq nl (not nl))) |
|---|
| 666 |
(if nl (insert "\n")) |
|---|
| 667 |
(lisp-indent-line) |
|---|
| 668 |
(cl-do-prettyprint)) |
|---|
| 669 |
(forward-char 1)))) |
|---|
| 670 |
(forward-sexp))) |
|---|
| 671 |
|
|---|
| 672 |
(defvar cl-macroexpand-cmacs nil) |
|---|
| 673 |
(defvar cl-closure-vars nil) |
|---|
| 674 |
|
|---|
| 675 |
(defun cl-macroexpand-all (form &optional env) |
|---|
| 676 |
"Expand all macro calls through a Lisp FORM. |
|---|
| 677 |
This also does some trivial optimizations to make the form prettier." |
|---|
| 678 |
(while (or (not (eq form (setq form (macroexpand form env)))) |
|---|
| 679 |
(and cl-macroexpand-cmacs |
|---|
| 680 |
(not (eq form (setq form (compiler-macroexpand form))))))) |
|---|
| 681 |
(cond ((not (consp form)) form) |
|---|
| 682 |
((memq (car form) '(let let*)) |
|---|
| 683 |
(if (null (nth 1 form)) |
|---|
| 684 |
(cl-macroexpand-all (cons 'progn (cddr form)) env) |
|---|
| 685 |
(let ((letf nil) (res nil) (lets (cadr form))) |
|---|
| 686 |
(while lets |
|---|
| 687 |
(push (if (consp (car lets)) |
|---|
| 688 |
(let ((exp (cl-macroexpand-all (caar lets) env))) |
|---|
| 689 |
(or (symbolp exp) (setq letf t)) |
|---|
| 690 |
(cons exp (cl-macroexpand-body (cdar lets) env))) |
|---|
| 691 |
(let ((exp (cl-macroexpand-all (car lets) env))) |
|---|
| 692 |
(if (symbolp exp) exp |
|---|
| 693 |
(setq letf t) (list exp nil)))) res) |
|---|
| 694 |
(setq lets (cdr lets))) |
|---|
| 695 |
(list* (if letf (if (eq (car form) 'let) 'letf 'letf*) (car form)) |
|---|
| 696 |
(nreverse res) (cl-macroexpand-body (cddr form) env))))) |
|---|
| 697 |
((eq (car form) 'cond) |
|---|
| 698 |
(cons (car form) |
|---|
| 699 |
(mapcar (function (lambda (x) (cl-macroexpand-body x env))) |
|---|
| 700 |
(cdr form)))) |
|---|
| 701 |
((eq (car form) 'condition-case) |
|---|
| 702 |
(list* (car form) (nth 1 form) (cl-macroexpand-all (nth 2 form) env) |
|---|
| 703 |
(mapcar (function |
|---|
| 704 |
(lambda (x) |
|---|
| 705 |
(cons (car x) (cl-macroexpand-body (cdr x) env)))) |
|---|
| 706 |
(cdddr form)))) |
|---|
| 707 |
((memq (car form) '(quote function)) |
|---|
| 708 |
(if (eq (car-safe (nth 1 form)) 'lambda) |
|---|
| 709 |
(let ((body (cl-macroexpand-body (cddadr form) env))) |
|---|
| 710 |
(if (and cl-closure-vars (eq (car form) 'function) |
|---|
| 711 |
(cl-expr-contains-any body cl-closure-vars)) |
|---|
| 712 |
(let* ((new (mapcar 'gensym cl-closure-vars)) |
|---|
| 713 |
(sub (pairlis cl-closure-vars new)) (decls nil)) |
|---|
| 714 |
(while (or (stringp (car body)) |
|---|
| 715 |
(eq (car-safe (car body)) 'interactive)) |
|---|
| 716 |
(push (list 'quote (pop body)) decls)) |
|---|
| 717 |
(put (car (last cl-closure-vars)) 'used t) |
|---|
| 718 |
(append |
|---|
| 719 |
(list 'list '(quote lambda) '(quote (&rest --cl-rest--))) |
|---|
| 720 |
(sublis sub (nreverse decls)) |
|---|
| 721 |
(list |
|---|
| 722 |
(list* 'list '(quote apply) |
|---|
| 723 |
(list 'function |
|---|
| 724 |
(list* 'lambda |
|---|
| 725 |
(append new (cadadr form)) |
|---|
| 726 |
(sublis sub body))) |
|---|
| 727 |
(nconc (mapcar (function |
|---|
| 728 |
(lambda (x) |
|---|
| 729 |
(list 'list '(quote quote) x))) |
|---|
| 730 |
cl-closure-vars) |
|---|
| 731 |
'((quote --cl-rest--))))))) |
|---|
| 732 |
(list (car form) (list* 'lambda (cadadr form) body)))) |
|---|
| 733 |
(let ((found (assq (cadr form) env))) |
|---|
| 734 |
(if (and found (ignore-errors |
|---|
| 735 |
(eq (cadr (caddr found)) 'cl-labels-args))) |
|---|
| 736 |
(cl-macroexpand-all (cadr (caddr (cadddr found))) env) |
|---|
| 737 |
form)))) |
|---|
| 738 |
((memq (car form) '(defun defmacro)) |
|---|
| 739 |
(list* (car form) (nth 1 form) (cl-macroexpand-body (cddr form) env))) |
|---|
| 740 |
((and (eq (car form) 'progn) (not (cddr form))) |
|---|
| 741 |
(cl-macroexpand-all (nth 1 form) env)) |
|---|
| 742 |
((eq (car form) 'setq) |
|---|
| 743 |
(let* ((args (cl-macroexpand-body (cdr form) env)) (p args)) |
|---|
| 744 |
(while (and p (symbolp (car p))) (setq p (cddr p))) |
|---|
| 745 |
(if p (cl-macroexpand-all (cons 'setf args)) (cons 'setq args)))) |
|---|
| 746 |
((consp (car form)) |
|---|
| 747 |
(cl-macroexpand-all (list* 'funcall |
|---|
| 748 |
(list 'function (car form)) |
|---|
| 749 |
(cdr form)) |
|---|
| 750 |
env)) |
|---|
| 751 |
(t (cons (car form) (cl-macroexpand-body (cdr form) env))))) |
|---|
| 752 |
|
|---|
| 753 |
(defun cl-macroexpand-body (body &optional env) |
|---|
| 754 |
(mapcar (function (lambda (x) (cl-macroexpand-all x env))) body)) |
|---|
| 755 |
|
|---|
| 756 |
(defun cl-prettyexpand (form &optional full) |
|---|
| 757 |
(message "Expanding...") |
|---|
| 758 |
(let ((cl-macroexpand-cmacs full) (cl-compiling-file full) |
|---|
| 759 |
(byte-compile-macro-environment nil)) |
|---|
| 760 |
(setq form (cl-macroexpand-all form |
|---|
| 761 |
(and (not full) '((block) (eval-when))))) |
|---|
| 762 |
(message "Formatting...") |
|---|
| 763 |
(prog1 (cl-prettyprint form) |
|---|
| 764 |
(message "")))) |
|---|
| 765 |
|
|---|
| 766 |
|
|---|
| 767 |
|
|---|
| 768 |
(run-hooks 'cl-extra-load-hook) |
|---|
| 769 |
|
|---|
| 770 |
|
|---|
| 771 |
|
|---|
| 772 |
|
|---|