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