Hi all!
Is there a way to debug a macro expansion? More precisely, I'd like to be able to have access to the full debugger when my macro expansion fails such that I could trace what's wrong of the code producing the expansion...
At the moment I get something like:
(pp (lambda () (define-class tata (toto) (slot: a))))
*** ERROR -- Unbound table key (table-ref '#<table #2> 'tata)
with no possibility to debug and see whats wrong. I guess that the environment is available at the expansion time so I don't see why I couldn't debug it like normal gambit code.
Many thanks in advance ^_^Y
David
Afficher les réponses par date
Introduces a parameter object in |current-clean-exception-handling|, which is set to #f by default.
With clean exception handling switched off, exceptions happening during macro expansion trap into the repl at the point of the error.
Signed-off-by: Christian Jaeger christian@pflanze.mine.nu --- Example: $ cat t.scm (define-macro (hello . body) (let ((v (error "an error"))) `(display (list "Hm: " ',v ',body))))
(hello "hua")
(include "t.scm")
*** ERROR IN #<procedure #2>, "t.scm"@2.12 -- an error 1>
;; restore the old behaviour:
(current-clean-exception-handling #t) (include "t.scm")
*** ERROR -- an error
lib/_repl.scm | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/lib/_repl.scm b/lib/_repl.scm index 3dc0aac..fe41fb6 100644 --- a/lib/_repl.scm +++ b/lib/_repl.scm @@ -2275,17 +2275,24 @@
(##exit))
+ +(define current-clean-exception-handling (make-parameter #f)) + + (define-prim (##repl-within cont write-reason)
(define (with-clean-exception-handling repl-context thunk) - (##with-exception-catcher - (lambda (exc) - (##continuation-graft ;; get rid of any useless continuation frames - (macro-repl-context-cont repl-context) - (lambda () - (release-ownership!) - (macro-raise exc)))) - thunk)) + (let ((old-handler (current-exception-handler))) + (with-exception-handler + (lambda (exc) + (if (current-clean-exception-handling) + (##continuation-graft ;; get rid of any useless continuation frames + (macro-repl-context-cont repl-context) + (lambda () + (release-ownership!) + (macro-raise exc))) + (old-handler exc))) + thunk)))
(define (acquire-ownership!) (##repl-channel-acquire-ownership!))
After breakfast I realize that the "cleanness" the routine is referring to was probably not the stripping of continuation frames from the sight of the user, but the calling of (release-ownership!).
Now how to fix this? The approach in this patch is to run (release-ownership!) in the repl-context as did the old code, but then run the original handler in the context of the error; well this means that we will be in a repl while ownership has been released, dunno if that's a good thing.
Possibly an alternative might be using |dynamic-wind| instead? I don't know what the onwership exactly implies.
Signed-off-by: Christian Jaeger christian@pflanze.mine.nu --- Apply on top of the previous patch. As usual with "git am -3 emailfile"
lib/_repl.scm | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/lib/_repl.scm b/lib/_repl.scm index fe41fb6..9765661 100644 --- a/lib/_repl.scm +++ b/lib/_repl.scm @@ -2291,7 +2291,16 @@ (lambda () (release-ownership!) (macro-raise exc))) - (old-handler exc))) + (continuation-capture + (lambda (cont) + (##continuation-graft + (macro-repl-context-cont repl-context) + (lambda () + (release-ownership!) + (##continuation-graft + cont + (lambda () + (old-handler exc))))))))) thunk)))
(define (acquire-ownership!)