(define-library (debug trace)
(export trace-define trace-lambda trace-let trace)
(import (scheme base) (scheme write))
(begin
(define global-indent " ")
(define-syntax trace-define
(syntax-rules ()
((_ (name args ...) body ...)
(define (name args ...)
(let ((indent global-indent))
(display indent)
(display "(")
(display (quote name))
(begin (display " ") (display args))
...
(display ")")
(newline)
(set! global-indent (string-append indent ": "))
(let ((return body ...))
(set! global-indent indent)
(unless (equal? indent " ")
(display indent)
(display return)
(newline))
return))))))
(define-syntax trace-lambda
(syntax-rules ()
((_ name (args ...) body ...)
(lambda (args ...)
(trace-define (name args ...) body ...)
(name args ...)))))
(define-syntax trace-let
(syntax-rules ()
((_ name ((keys values) ...) body ...)
((lambda () ; why doesn't ‘begin’ work?
(trace-define (name keys ...) body ...)
(name values ...))))))
(define-syntax trace
(syntax-rules ()
((_ exp)
(let ((result exp))
(display global-indent)
(display result)
(newline)
result))))))