DrScheme version with source location tracking Andre van Tonder (08 Sep 2005 01:24 UTC)
Re: DrScheme version with source location tracking Per Bothner (08 Sep 2005 01:36 UTC)
Re: DrScheme version with source location tracking Andre van Tonder (08 Sep 2005 14:01 UTC)

DrScheme version with source location tracking Andre van Tonder 08 Sep 2005 01:23 UTC

As proof of concept, I have integrated the macro system
of this SRFI with the MzScheme source location tracking mechanism.

Examples can now be run in DrScheme 299.100 and both runtime and syntax
errors will be correctly highlighted.  The implementation is at:

   http://www.het.brown.edu/people/andre/macros/implementation/

The integration works by replacing current-eval and the native expansion
mechanism with that of the current SRFI, which harvests the native source
locations from the input and keeps track of these in a weak hashtable.
This is done for compound syntax objects only.  Errors in atoms are referred to
the nearest enclosing expression.  In most examples, errors are pinpointed with
great accuracy.  The implementation of the source tracking mechanism was really
simple.

A couple of examples from the file simple-location-tests.scm
at the above link:

In the following, the subexpression (2 3) will be highlighted:

(cons 1 (
          2
             3))

In the following, a runtime error will cause (set ,y t) to be
highlighted:

(let-syntax ((main (lambda (form)

                      (define (make-swap x y)
                        (quasisyntax
                         (let ((t ,x))
                           (set! ,x ,y)
                           (set ,y t))))

                      (quasisyntax
                       (let ((s 1)
                             (t 2))
                         ,(make-swap (syntax s) (syntax t))
                         (list s t))))))
   (main))

In the following, a syntax error will highlight the inner let-expression:

(let ((a 1))
   (let ((b 3))
     (define a 1)
     (let ((temp 1)
           (temp 2))
       temp)))

Finally, given the following definition for case:

(define-syntax case
   (lambda (x)
     (syntax-case x ()
       ((_ e c1 c2 ...)
        (quasisyntax
         (let ((t e))
           ,(let f ((c1 (syntax c1)) (cmore (syntax (c2 ...))))
              (if (null? cmore)
                  (syntax-case c1 (else)
                    ((else e1 e2 ...)    (syntax (beginn e1 e2 ...)))
                    (((k ...) e1 e2 ...) (syntax (if (memv t '(k ...))
                                                     (begin e1 e2 ...)))))
                  (syntax-case c1 ()
                    (((k ...) e1 e2 ...)
                     (quasisyntax
                      (if (memv t '(k ...))
                          (begin e1 e2 ...)
                          ,(f (car cmore) (cdr cmore))))))))))))))

the syntax error in the following will highlight the case expression:

(let ((x 1))
   (let ((y 2))
     (case 'a
       ((x y) 'no)
       (z u 'yes))))

While a runtime error in the following will highlight the error
(beginn e1 e2 ...) in the macro above:

(case 'a
   ((b c) 'd)
   (else e))

Regards
Andre