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