Hi Guiler!
TL;DR: See the code at the end. You can put in your .guile to fix some
syntax-violation source-location reporting when compiling.
I've recently worked on something that might be good for all.
Basically, I am sure all of us have already encountered this kind of
error when compiling a module:
foo.scm:
+-
1|
2|
3|
4| (let () lambda)
+-
Compiling /home/old/foo.scm ...
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Syntax error:
unknown location: lambda: bad lambda in form lambda
Not very great right? "unknown location" is not very helpful.
Furthermore, the syntax-violation is indeed the "lamda", but it happened
inside the "let" form, not in the lambda form itself. Well, with the
proposed fix I have, this is what you will get instead:
Compiling /home/old/foo.scm ...
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Syntax error:
/home/old/foo.scm:4:3: let: bad lambda in subform lambda of (let () lambda)
Neat eh?
So the idea is to re-define some of the core syntax-transformers from
psyntax.
Indeed, for some reasons, not all of the transformers in psyntax have
proper source wrapping of forms on syntax-violation.
I am not sure of the consequences here but I don't think there's much to
it since the wrappers are forwarding the expander states to their
original implementations anyway. Basically, it's just catching
syntax-violation exceptions and raising new exceptions with proper
source annotations. Hopefully I got this correctly.
In the end, just put this in your .guile:
--8<---------------cut here---------------start------------->8---
(eval-when (eval)
(let-syntax ((redefine-syntax-transformer
(syntax-rules ()
((_ id who)
(let* ((guile-module the-root-module)
(original-transformer (macro-binding (module-ref
guile-module (quote id)))))
(module-define!
guile-module
(quote id)
(make-syntax-transformer
(quote id)
'core
(lambda (e r w s mod)
(with-exception-handler
(lambda (exn)
((@ (ice-9 exceptions) raise-exception)
(cond
(((@ (ice-9 exceptions) syntax-error?) exn)
(let* ((args (exception-args exn)))
(if (syntax-violation 'who
(cadr args)
(datum->syntax #f e
#:source s)
(cadddr args))
exn))))))
(lambda ()
(original-transformer e r w s mod))
#:unwind? #f)))))))))
(redefine-syntax-transformer lambda lambda)
(redefine-syntax-transformer lambda* lambda)
(redefine-syntax-transformer let let)
(redefine-syntax-transformer letrec letrec)
(redefine-syntax-transformer letrec* letrec*)
(redefine-syntax-transformer case-lambda case-lambda)
(redefine-syntax-transformer case-lambda* case-lambda)))
--8<---------------cut here---------------end--------------->8---
Regards,
Olivier
--
Olivier Dion
oldiob.ca