summaryrefslogtreecommitdiffstatshomepage
path: root/tekuti/util.scm
diff options
context:
space:
mode:
Diffstat (limited to 'tekuti/util.scm')
-rw-r--r--tekuti/util.scm44
1 files changed, 43 insertions, 1 deletions
diff --git a/tekuti/util.scm b/tekuti/util.scm
index edd8dba..6c9231e 100644
--- a/tekuti/util.scm
+++ b/tekuti/util.scm
@@ -29,7 +29,7 @@
#:use-module (srfi srfi-1)
#:export (expanduser match-lines dbg unwind-protect dbg dsu-sort
hash-push! list-has-length? list-head-match mapn
- list-intersperse))
+ list-intersperse with-backtrace define-memoized))
(define (expanduser path)
(let ((parts (string-split path #\/)))
@@ -91,3 +91,45 @@
(let loop ((l (cdr src-l)) (dest (cons (car src-l) '())))
(if (null? l) (reverse dest)
(loop (cdr l) (cons (car l) (cons elem dest)))))))
+
+(define (handle-error key . args)
+ (let ((cep (current-error-port))
+ (highlights (if (or (eq? key 'wrong-type-arg)
+ (eq? key 'out-of-range))
+ (list-ref args 3)
+ '())))
+ (newline cep)
+ (display "Backtrace:\n")
+ (display-backtrace (fluid-ref the-last-stack) cep
+ #f #f highlights)
+ (newline cep)
+ (if (= (length args) 4)
+ (apply display-error (fluid-ref the-last-stack) cep args)
+ (format cep "~a" args))
+ (force-output cep)
+ (apply throw key args)))
+
+(define (with-backtrace proc)
+ (debug-enable 'backtrace)
+ (start-stack 'with-backtrace
+ (catch #t
+ proc
+ handle-error
+ (lambda args
+ (fluid-set! the-last-stack (make-stack #t 2 0))
+ (apply throw args)))))
+
+(define (memoize1 proc)
+ (let ((old-args #f) (cache #f) (proc proc))
+ (lambda args
+ (if (equal? args old-args)
+ cache
+ (let ((val (apply proc args)))
+ (set! old-args args)
+ (set! cache val)
+ val)))))
+
+(define-macro (define-memoized form . body)
+ `(begin
+ (define ,form ,@body)
+ (set! ,(car form) (,memoize1 ,(car form)))))