use defsubst
[bpt/guile.git] / module / language / elisp / boot.el
CommitLineData
ddc9006b 1;;; Guile Emacs Lisp -*- lexical-binding: t -*-
6937c7aa
BT
2
3;;; Copyright (C) 2011 Free Software Foundation, Inc.
4
5;;; This library is free software; you can redistribute it and/or modify
6;;; it under the terms of the GNU Lesser General Public License as
7;;; published by the Free Software Foundation; either version 3 of the
8;;; License, or (at your option) any later version.
9;;;
10;;; This library is distributed in the hope that it will be useful, but
11;;; WITHOUT ANY WARRANTY; without even the implied warranty of
12;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13;;; Lesser General Public License for more details.
14;;;
15;;; You should have received a copy of the GNU Lesser General Public
16;;; License along with this library; if not, write to the Free Software
17;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18;;; 02110-1301 USA
19
20;;; Code:
9b15703d
BT
21
22(defmacro @ (module symbol)
23 `(guile-ref ,module ,symbol))
24
81fb8737
RT
25(defmacro @@ (module symbol)
26 `(guile-private-ref ,module ,symbol))
27
87f9e81a
RT
28(defmacro defun (name args &rest body)
29 `(let ((proc (function (lambda ,args ,@body))))
30 (%funcall (@ (language elisp runtime) set-symbol-function!)
31 ',name
32 proc)
33 (%funcall (@ (guile) set-procedure-property!)
34 proc 'name ',name)
35 ',name))
36
37(defun omega () (omega))
38
b652e2b9
BT
39(defmacro eval-and-compile (&rest body)
40 `(progn
41 (eval-when-compile ,@body)
42 (progn ,@body)))
43
b1e93b73
RT
44(defmacro %define-compiler-macro (name args &rest body)
45 `(eval-and-compile
46 (%funcall
47 (@ (language elisp runtime) set-symbol-plist!)
48 ',name
49 (%funcall
50 (@ (guile) cons*)
51 '%compiler-macro
52 #'(lambda ,args ,@body)
53 (%funcall (@ (language elisp runtime) symbol-plist) ',name)))
54 ',name))
55
6570cfdf
RT
56(defmacro defsubst (name args &rest body)
57 `(progn
58 (defun ,name ,args ,@body)
59 (eval-and-compile
60 (%define-compiler-macro ,name (form)
61 (%funcall (@ (guile) cons*)
62 '%funcall
63 (%funcall
64 (@ (guile) list)
65 'function
66 (%funcall (@ (guile) cons*) 'lambda ',args ',body))
67 (%funcall (@ (guile) cdr) form))))))
68
87f9e81a
RT
69(eval-and-compile
70 (defun eval (form)
71 (%funcall (@ (language elisp runtime) eval-elisp) form)))
72
b652e2b9 73(eval-and-compile
efa98de6
RT
74 (defsubst null (object)
75 (declare (lexical object))
b652e2b9 76 (if object nil t))
efa98de6
RT
77 (defsubst consp (x)
78 (declare (lexical x))
79 (%funcall (@ (guile) pair?) x))
80 (defsubst atom (x)
81 (declare (lexical x))
82 (null (consp x)))
b652e2b9 83 (defun listp (object)
efa98de6 84 (declare (lexical object))
b652e2b9 85 (if object (consp object) t))
efa98de6
RT
86 (defsubst car (list)
87 (declare (lexical list))
b05ca4ab 88 (if list (%funcall (@ (guile) car) list) nil))
efa98de6
RT
89 (defsubst cdr (list)
90 (declare (lexical list))
b05ca4ab
BT
91 (if list (%funcall (@ (guile) cdr) list) nil))
92 (defun make-symbol (name)
93 (%funcall (@ (guile) make-symbol) name))
87f9e81a
RT
94 (defun gensym ()
95 (%funcall (@ (guile) gensym)))
5950f674
BT
96 (defun signal (error-symbol data)
97 (%funcall (@ (guile) throw) 'elisp-condition error-symbol data)))
b652e2b9
BT
98
99(defmacro lambda (&rest cdr)
100 `#'(lambda ,@cdr))
101
102(defmacro prog1 (first &rest body)
87f9e81a 103 (let ((temp (gensym)))
13f022c9
BT
104 `(let ((,temp ,first))
105 (declare (lexical ,temp))
b652e2b9
BT
106 ,@body
107 ,temp)))
108
87f9e81a
RT
109(defun interactive (&optional arg)
110 nil)
111
b652e2b9
BT
112(defmacro prog2 (form1 form2 &rest body)
113 `(progn ,form1 (prog1 ,form2 ,@body)))
114
115(defmacro cond (&rest clauses)
116 (if (null clauses)
117 nil
118 (let ((first (car clauses))
119 (rest (cdr clauses)))
120 (if (listp first)
121 (let ((condition (car first))
122 (body (cdr first)))
123 (if (null body)
87f9e81a 124 (let ((temp (gensym)))
13f022c9
BT
125 `(let ((,temp ,condition))
126 (declare (lexical ,temp))
b652e2b9
BT
127 (if ,temp
128 ,temp
129 (cond ,@rest))))
130 `(if ,condition
131 (progn ,@body)
132 (cond ,@rest))))
133 (signal 'wrong-type-argument `(listp ,first))))))
134
135(defmacro and (&rest conditions)
136 (cond ((null conditions) t)
137 ((null (cdr conditions)) (car conditions))
138 (t `(if ,(car conditions)
139 (and ,@(cdr conditions))
140 nil))))
141
142(defmacro or (&rest conditions)
143 (cond ((null conditions) nil)
144 ((null (cdr conditions)) (car conditions))
87f9e81a 145 (t (let ((temp (gensym)))
13f022c9
BT
146 `(let ((,temp ,(car conditions)))
147 (declare (lexical ,temp))
b652e2b9
BT
148 (if ,temp
149 ,temp
150 (or ,@(cdr conditions))))))))
151
9083c48d
BT
152(defmacro lexical-let (bindings &rest body)
153 (labels ((loop (list vars)
154 (if (null list)
155 `(let ,bindings
156 (declare (lexical ,@vars))
157 ,@body)
158 (loop (cdr list)
159 (if (consp (car list))
160 `(,(car (car list)) ,@vars)
161 `(,(car list) ,@vars))))))
162 (loop bindings '())))
163
164(defmacro lexical-let* (bindings &rest body)
165 (labels ((loop (list vars)
166 (if (null list)
167 `(let* ,bindings
168 (declare (lexical ,@vars))
169 ,@body)
170 (loop (cdr list)
171 (if (consp (car list))
172 (cons (car (car list)) vars)
173 (cons (car list) vars))))))
174 (loop bindings '())))
175
9b90b453 176(defmacro while (test &rest body)
87f9e81a 177 (let ((loop (gensym)))
9b90b453
BT
178 `(labels ((,loop ()
179 (if ,test
180 (progn ,@body (,loop))
181 nil)))
182 (,loop))))
183
b652e2b9 184(defmacro unwind-protect (bodyform &rest unwindforms)
87f9e81a
RT
185 `(%funcall (@ (guile) dynamic-wind)
186 #'(lambda () nil)
187 #'(lambda () ,bodyform)
188 #'(lambda () ,@unwindforms)))
9b15703d 189
c0652730
BT
190(defmacro when (cond &rest body)
191 `(if ,cond
192 (progn ,@body)))
193
194(defmacro unless (cond &rest body)
195 `(when (not ,cond)
196 ,@body))
197
b05ca4ab
BT
198(defun symbolp (object)
199 (%funcall (@ (guile) symbol?) object))
200
87f9e81a 201(defun %functionp (object)
b05ca4ab
BT
202 (%funcall (@ (guile) procedure?) object))
203
204(defun symbol-function (symbol)
205 (let ((f (%funcall (@ (language elisp runtime) symbol-function)
206 symbol)))
207 (if (%funcall (@ (language elisp falias) falias?) f)
208 (%funcall (@ (language elisp falias) falias-object) f)
209 f)))
97d9da9a 210
5bcc6d9e 211(defun eval (form)
b05ca4ab
BT
212 (%funcall (@ (system base compile) compile)
213 form
214 (%funcall (@ (guile) symbol->keyword) 'from)
215 'elisp
216 (%funcall (@ (guile) symbol->keyword) 'to)
217 'value))
218
219(defun %indirect-function (object)
220 (cond
87f9e81a 221 ((%functionp object)
b05ca4ab 222 object)
87f9e81a
RT
223 ((null object)
224 (signal 'void-function nil))
b05ca4ab 225 ((symbolp object) ;++ cycle detection
87f9e81a
RT
226 (%indirect-function
227 (%funcall (@ (language elisp runtime) symbol-function) object)))
b05ca4ab
BT
228 ((listp object)
229 (eval `(function ,object)))
230 (t
231 (signal 'invalid-function `(,object)))))
232
233(defun apply (function &rest arguments)
234 (%funcall (@ (guile) apply)
235 (@ (guile) apply)
236 (%indirect-function function)
237 arguments))
238
239(defun funcall (function &rest arguments)
240 (%funcall (@ (guile) apply)
241 (%indirect-function function)
242 arguments))
243
87f9e81a
RT
244(defun autoload-do-load (fundef &optional funname macro-only)
245 (and (load (cadr fundef))
246 (%indirect-function funname)))
247
248(defun fset (symbol definition)
249 (funcall (@ (language elisp runtime) set-symbol-function!)
250 symbol
251 definition))
252
253(defun eq (obj1 obj2)
254 (if obj1
255 (%funcall (@ (guile) eq?) obj1 obj2)
256 (if obj2 nil t)))
257
258(defun nthcdr (n list)
259 (let ((i 0))
260 (while (< i n)
261 (setq list (cdr list)
262 i (+ i 1)))
263 list))
264
265(defun nth (n list)
266 (car (nthcdr n list)))
267
b05ca4ab
BT
268(defun fset (symbol definition)
269 (funcall (@ (language elisp runtime) set-symbol-function!)
270 symbol
87f9e81a
RT
271 (cond
272 ((%funcall (@ (guile) procedure?) definition)
273 definition)
274 ((and (consp definition)
275 (eq (car definition) 'macro))
276 (if (%funcall (@ (guile) procedure?) (cdr definition))
277 definition
278 (cons 'macro
279 (funcall (@ (language elisp falias) make-falias)
280 (function
281 (lambda (&rest args) (apply (cdr definition) args)))
282 (cdr definition)))))
283 ((and (consp definition)
284 (eq (car definition) 'autoload))
285 (if (or (eq (nth 4 definition) 'macro)
286 (eq (nth 4 definition) t))
287 (cons 'macro
288 (funcall
289 (@ (language elisp falias) make-falias)
290 (function (lambda (&rest args)
291 (apply (cdr (autoload-do-load definition symbol nil)) args)))
292 definition))
293 (funcall
294 (@ (language elisp falias) make-falias)
295 (function (lambda (&rest args)
296 (apply (autoload-do-load definition symbol nil) args)))
297 definition)))
298 (t
b05ca4ab 299 (funcall (@ (language elisp falias) make-falias)
87f9e81a
RT
300 (function (lambda (&rest args) (apply definition args)))
301 definition))))
b05ca4ab
BT
302 definition)
303
87f9e81a 304(defun gload (file)
5bcc6d9e
BT
305 (funcall (@ (system base compile) compile-file)
306 file
307 (funcall (@ (guile) symbol->keyword) 'from)
308 'elisp
309 (funcall (@ (guile) symbol->keyword) 'to)
310 'value)
311 t)
312
9b15703d
BT
313;;; Equality predicates
314
0ab2a63a
BT
315(defun eql (obj1 obj2)
316 (if obj1
317 (funcall (@ (guile) eqv?) obj1 obj2)
318 (null obj2)))
319
320(defun equal (obj1 obj2)
321 (if obj1
322 (funcall (@ (guile) equal?) obj1 obj2)
323 (null obj2)))
9b15703d 324
85bc6238
BT
325;;; Symbols
326
b05ca4ab
BT
327;;; `symbolp' and `symbol-function' are defined above.
328
5c65ee51 329(fset 'symbol-name (@ (guile) symbol->string))
85bc6238 330(fset 'symbol-value (@ (language elisp runtime) symbol-value))
85bc6238
BT
331(fset 'set (@ (language elisp runtime) set-symbol-value!))
332(fset 'makunbound (@ (language elisp runtime) makunbound!))
333(fset 'fmakunbound (@ (language elisp runtime) fmakunbound!))
334(fset 'boundp (@ (language elisp runtime) symbol-bound?))
335(fset 'fboundp (@ (language elisp runtime) symbol-fbound?))
5c65ee51 336(fset 'intern (@ (guile) string->symbol))
85bc6238 337
87f9e81a
RT
338;(defun defvaralias (new-alias base-variable &optional docstring)
339; (let ((fluid (funcall (@ (language elisp runtime) symbol-fluid)
340; base-variable)))
341; (funcall (@ (language elisp runtime) set-symbol-fluid!)
342; new-alias
343; fluid)
344; base-variable))
14b288ce 345
9b15703d
BT
346;;; Numerical type predicates
347
348(defun floatp (object)
349 (and (funcall (@ (guile) real?) object)
350 (or (funcall (@ (guile) inexact?) object)
351 (null (funcall (@ (guile) integer?) object)))))
352
353(defun integerp (object)
fc45b7e8
BT
354 (and (funcall (@ (guile) integer?) object)
355 (funcall (@ (guile) exact?) object)))
9b15703d
BT
356
357(defun numberp (object)
358 (funcall (@ (guile) real?) object))
359
360(defun wholenump (object)
fc45b7e8 361 (and (integerp object) (>= object 0)))
9b15703d
BT
362
363(defun zerop (object)
364 (= object 0))
365
366;;; Numerical comparisons
367
368(fset '= (@ (guile) =))
369
370(defun /= (num1 num2)
371 (null (= num1 num2)))
372
373(fset '< (@ (guile) <))
374(fset '<= (@ (guile) <=))
375(fset '> (@ (guile) >))
376(fset '>= (@ (guile) >=))
377
378(defun max (&rest numbers)
379 (apply (@ (guile) max) numbers))
380
381(defun min (&rest numbers)
382 (apply (@ (guile) min) numbers))
383
384;;; Arithmetic functions
385
386(fset '1+ (@ (guile) 1+))
387(fset '1- (@ (guile) 1-))
388(fset '+ (@ (guile) +))
389(fset '- (@ (guile) -))
390(fset '* (@ (guile) *))
391(fset '% (@ (guile) modulo))
392(fset 'abs (@ (guile) abs))
393
394;;; Floating-point rounding
395
396(fset 'ffloor (@ (guile) floor))
397(fset 'fceiling (@ (guile) ceiling))
398(fset 'ftruncate (@ (guile) truncate))
399(fset 'fround (@ (guile) round))
400
401;;; Numeric conversion
402
403(defun float (arg)
404 (if (numberp arg)
405 (funcall (@ (guile) exact->inexact) arg)
406 (signal 'wrong-type-argument `(numberp ,arg))))
407
408;;; List predicates
409
9b15703d
BT
410(fset 'not #'null)
411
412(defun atom (object)
413 (null (consp object)))
414
9b15703d
BT
415(defun nlistp (object)
416 (null (listp object)))
417
418;;; Lists
419
420(fset 'cons (@ (guile) cons))
421(fset 'list (@ (guile) list))
422(fset 'make-list (@ (guile) make-list))
423(fset 'append (@ (guile) append))
424(fset 'reverse (@ (guile) reverse))
12c00a04 425(fset 'nreverse (@ (guile) reverse!))
9b15703d 426
9b15703d
BT
427(defun car-safe (object)
428 (if (consp object)
429 (car object)
430 nil))
431
432(defun cdr-safe (object)
433 (if (consp object)
434 (cdr object)
435 nil))
436
437(defun setcar (cell newcar)
438 (if (consp cell)
439 (progn
440 (funcall (@ (guile) set-car!) cell newcar)
441 newcar)
442 (signal 'wrong-type-argument `(consp ,cell))))
443
444(defun setcdr (cell newcdr)
445 (if (consp cell)
446 (progn
447 (funcall (@ (guile) set-cdr!) cell newcdr)
448 newcdr)
449 (signal 'wrong-type-argument `(consp ,cell))))
450
df9cd3b4
BT
451(defun %member (elt list test)
452 (cond
453 ((null list) nil)
454 ((consp list)
455 (if (funcall test elt (car list))
456 list
457 (%member elt (cdr list) test)))
458 (t (signal 'wrong-type-argument `(listp ,list)))))
459
460(defun member (elt list)
461 (%member elt list #'equal))
462
463(defun memql (elt list)
464 (%member elt list #'eql))
465
466(defun memq (elt list)
467 (%member elt list #'eq))
468
12c00a04
BT
469(defun assoc (key list)
470 (funcall (@ (srfi srfi-1) assoc) key list #'equal))
471
472(defun assq (key list)
473 (funcall (@ (srfi srfi-1) assoc) key list #'eq))
474
475(defun rplaca (cell newcar)
476 (funcall (@ (guile) set-car!) cell newcar)
477 newcar)
478
479(defun rplacd (cell newcdr)
480 (funcall (@ (guile) set-cdr!) cell newcdr)
481 newcdr)
482
483(defun caar (x)
484 (car (car x)))
485
486(defun cadr (x)
487 (car (cdr x)))
488
489(defun cdar (x)
490 (cdr (car x)))
491
492(defun cddr (x)
493 (cdr (cdr x)))
494
495(defmacro dolist (spec &rest body)
496 (apply #'(lambda (var list &optional result)
87f9e81a
RT
497 (list 'progn
498 (list 'mapc
499 (cons 'lambda (cons (list var) body))
500 list)
501 result))
12c00a04
BT
502 spec))
503
8f2f6566
BT
504;;; Strings
505
506(defun string (&rest characters)
507 (funcall (@ (guile) list->string)
508 (mapcar (@ (guile) integer->char) characters)))
509
12c00a04
BT
510(defun stringp (object)
511 (funcall (@ (guile) string?) object))
512
513(defun string-equal (s1 s2)
514 (let ((s1 (if (symbolp s1) (symbol-name s1) s1))
515 (s2 (if (symbolp s2) (symbol-name s2) s2)))
516 (funcall (@ (guile) string=?) s1 s2)))
517
518(fset 'string= 'string-equal)
519
520(defun substring (string from &optional to)
521 (apply (@ (guile) substring) string from (if to (list to) nil)))
522
523(defun upcase (obj)
524 (funcall (@ (guile) string-upcase) obj))
525
526(defun downcase (obj)
527 (funcall (@ (guile) string-downcase) obj))
528
529(defun string-match (regexp string &optional start)
530 (let ((m (funcall (@ (ice-9 regex) string-match)
531 regexp
532 string
533 (or start 0))))
534 (if m
535 (funcall (@ (ice-9 regex) match:start) m 0)
536 nil)))
537
538;; Vectors
539
540(defun make-vector (length init)
541 (funcall (@ (guile) make-vector) length init))
542
9b15703d
BT
543;;; Sequences
544
ebc30e3f
BT
545(defun length (sequence)
546 (funcall (if (listp sequence)
547 (@ (guile) length)
548 (@ (guile) generalized-vector-length))
549 sequence))
8f2f6566
BT
550
551(defun mapcar (function sequence)
552 (funcall (@ (guile) map) function sequence))
12ca82ca 553
12c00a04
BT
554(defun mapc (function sequence)
555 (funcall (@ (guile) for-each) function sequence)
556 sequence)
557
558(defun aref (array idx)
559 (funcall (@ (guile) generalized-vector-ref) array idx))
560
561(defun aset (array idx newelt)
562 (funcall (@ (guile) generalized-vector-set!) array idx newelt)
563 newelt)
564
565(defun concat (&rest sequences)
566 (apply (@ (guile) string-append) sequences))
567
12ca82ca
BT
568;;; Property lists
569
570(defun %plist-member (plist property test)
76c50ec5
BT
571 (cond
572 ((null plist) nil)
573 ((consp plist)
574 (if (funcall test (car plist) property)
575 (cdr plist)
576 (%plist-member (cdr (cdr plist)) property test)))
577 (t (signal 'wrong-type-argument `(listp ,plist)))))
12ca82ca
BT
578
579(defun %plist-get (plist property test)
580 (car (%plist-member plist property test)))
581
582(defun %plist-put (plist property value test)
13f022c9 583 (let ((x (%plist-member plist property test)))
12ca82ca
BT
584 (if x
585 (progn (setcar x value) plist)
586 (cons property (cons value plist)))))
587
588(defun plist-get (plist property)
589 (%plist-get plist property #'eq))
590
591(defun plist-put (plist property value)
592 (%plist-put plist property value #'eq))
593
594(defun plist-member (plist property)
595 (%plist-member plist property #'eq))
596
597(defun lax-plist-get (plist property)
598 (%plist-get plist property #'equal))
599
600(defun lax-plist-put (plist property value)
601 (%plist-put plist property value #'equal))
602
603(defvar plist-function (funcall (@ (guile) make-object-property)))
604
605(defun symbol-plist (symbol)
606 (funcall plist-function symbol))
607
608(defun setplist (symbol plist)
609 (funcall (funcall (@ (guile) setter) plist-function) symbol plist))
610
611(defun get (symbol propname)
612 (plist-get (symbol-plist symbol) propname))
613
614(defun put (symbol propname value)
615 (setplist symbol (plist-put (symbol-plist symbol) propname value)))
5950f674
BT
616
617;;; Nonlocal exits
618
619(defmacro condition-case (var bodyform &rest handlers)
620 (let ((key (make-symbol "key"))
621 (error-symbol (make-symbol "error-symbol"))
622 (data (make-symbol "data"))
623 (conditions (make-symbol "conditions")))
624 (flet ((handler->cond-clause (handler)
625 `((or ,@(mapcar #'(lambda (c) `(memq ',c ,conditions))
626 (if (consp (car handler))
627 (car handler)
628 (list (car handler)))))
629 ,@(cdr handler))))
630 `(funcall (@ (guile) catch)
631 'elisp-condition
632 #'(lambda () ,bodyform)
633 #'(lambda (,key ,error-symbol ,data)
b07a7449 634 (declare (lexical ,key ,error-symbol ,data))
5950f674
BT
635 (let ((,conditions
636 (get ,error-symbol 'error-conditions))
637 ,@(if var
638 `((,var (cons ,error-symbol ,data)))
639 '()))
b07a7449
BT
640 (declare (lexical ,conditions
641 ,@(if var `(,var) '())))
5950f674
BT
642 (cond ,@(mapcar #'handler->cond-clause handlers)
643 (t (signal ,error-symbol ,data)))))))))
ce9b7cc2
BT
644
645(put 'error 'error-conditions '(error))
646(put 'wrong-type-argument 'error-conditions '(wrong-type-argument error))
647(put 'invalid-function 'error-conditions '(invalid-function error))
648(put 'no-catch 'error-conditions '(no-catch error))
8fb67871
BT
649(put 'throw 'error-conditions '(throw))
650
85b3dd6c
BT
651(defvar %catch nil)
652
8fb67871
BT
653(defmacro catch (tag &rest body)
654 (let ((tag-value (make-symbol "tag-value"))
655 (c (make-symbol "c"))
656 (data (make-symbol "data")))
657 `(let ((,tag-value ,tag))
b07a7449 658 (declare (lexical ,tag-value))
8fb67871 659 (condition-case ,c
85b3dd6c
BT
660 (let ((%catch t))
661 ,@body)
8fb67871
BT
662 (throw
663 (let ((,data (cdr ,c)))
b07a7449 664 (declare (lexical ,data))
8fb67871
BT
665 (if (eq (car ,data) ,tag-value)
666 (car (cdr ,data))
85b3dd6c 667 (apply #'throw ,data))))))))
ce9b7cc2 668
8fb67871 669(defun throw (tag value)
85b3dd6c 670 (signal (if %catch 'throw 'no-catch) (list tag value)))
39864d20
BT
671
672;;; I/O
673
674(defun princ (object)
675 (funcall (@ (guile) display) object))
676
677(defun print (object)
678 (funcall (@ (guile) write) object))
679
87f9e81a
RT
680(defun prin1 (object)
681 (funcall (@ (guile) write) object))
682
39864d20
BT
683(defun terpri ()
684 (funcall (@ (guile) newline)))
685
686(defun format* (stream string &rest args)
687 (apply (@ (guile) format) stream string args))
43ff6804
BT
688
689(defun send-string-to-terminal (string)
690 (princ string))
691
692(defun read-from-minibuffer (prompt &rest ignore)
693 (princ prompt)
694 (let ((value (funcall (@ (ice-9 rdelim) read-line))))
695 (if (funcall (@ (guile) eof-object?) value)
696 ""
697 value)))
698
699(defun prin1-to-string (object)
700 (format* nil "~S" object))
52d24724
BT
701
702;; Random number generation
703
704(defvar %random-state (funcall (@ (guile) copy-random-state)
705 (@ (guile) *random-state*)))
706
707(defun random (&optional limit)
87f9e81a
RT
708 (if (eq limit t)
709 (setq %random-state
710 (funcall (@ (guile) random-state-from-platform))))
711 (funcall (@ (guile) random)
712 (if (wholenump limit)
713 limit
714 (@ (guile) most-positive-fixnum))
715 %random-state))
716
717(defmacro save-excursion (&rest body)
718 `(call-with-save-excursion #'(lambda () ,@body)))
719
720(defmacro save-current-buffer (&rest body)
721 `(call-with-save-current-buffer #'(lambda () ,@body)))
722
723(defmacro save-restriction (&rest body)
724 `(call-with-save-restriction #'(lambda () ,@body)))
725
726(defmacro track-mouse (&rest body)
727 `(call-with-track-mouse #'(lambda () ,@body)))
728
729(defmacro setq-default (var value &rest args)
730 `(progn (set-default ',var ,value)
731 ,(if (null args)
732 var
733 `(setq-default ,@args))))
734
735(defmacro catch (tag &rest body)
736 `(call-with-catch ,tag #'(lambda () ,@body)))
737
738(defmacro condition-case (var bodyform &rest args)
739 (if (consp args)
740 (let* ((handler (car args))
741 (handlers (cdr args))
742 (handler-conditions (car handler))
743 (handler-body (cdr handler)))
744 `(call-with-handler ',var
745 ',handler-conditions
746 #'(lambda () ,@handler-body)
747 #'(lambda ()
748 (condition-case ,var
749 ,bodyform
750 ,@handlers))))
751 bodyform))
752
753(defun backtrace-frame (nframes)
754 (let* ((stack (funcall (@ (guile) make-stack) t))
755 (frame (stack-ref stack nframes))
756 (proc (funcall (@ (guile) frame-procedure) frame))
757 (pname (or (and (%functionp proc)
758 (funcall (@ (guile) procedure-name) proc))
759 proc))
760 (args (funcall (@ (guile) frame-arguments) frame)))
761 (cons t (cons pname args))))
762
763(defun backtrace ()
764 (interactive)
765 (let* ((stack (funcall (@ (guile) make-stack) t))
766 (frame (funcall (@ (guile) stack-ref) stack 1))
767 (space (funcall (@ (guile) integer->char) 32)))
768 (while frame
769 (princ (string 32 32))
770 (let ((proc (funcall (@ (guile) frame-procedure) frame)))
771 (prin1 (or (and (%functionp proc)
772 (funcall (@ (guile) procedure-name) proc))
773 proc)))
774 (prin1 (funcall (@ (guile) frame-arguments) frame))
775 (terpri)
776 (setq frame (funcall (@ (guile) frame-previous) frame)))
777 nil))
778
779(defun %set-eager-macroexpansion-mode (ignore)
780 nil)