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


Reply via email to