2

I have a couple of files written in Chez Scheme, each about a thousand lines. When I try to load a file into the REPL:

> (load "filexxx.scm")
...
Exception: variable A is not bound
Type (debug) to enter the debugger.

How can I figure out which line from which file triggered this exception?

I mainly use Racket, where DrRacket would have pointed me to the line causing the exception. Is there a similar way to find where the undefined variable A is being used in Chez?

brj
  • 375
  • 2
  • 11

1 Answers1

1

Obtaining source location for exceptions can be frustrating in Chez Scheme. In this particular case, it may work to define identifier syntax for A that reports the location.

filexxx.scm

(define a 1)
(define b (+ A 1))
(define c 3)
(define-syntax A
  (make-variable-transformer
   (lambda (x)
     (errorf #f "variable ~a is not bound at ~s"
       (syntax->datum x) (annotation-source (syntax->annotation x))))))

(load "filexxx.scm")
Exception: variable A is not bound at #<source filexxx.scm[26:27]>
Type (debug) to enter the debugger.

This indicates A is referenced at 0-based character offset 26 in filexxx.scm.


Alternatively, you can use the debugger to gain context, though maybe not a line or character number.

If A occurs in a variable definition ...

filexxx.scm

(define my-var (+ A x))

... you'll likely find yourself in the compiler, as seen below. (Enter i to inspect the continuation, then sf to list frames.)

> (load "filexxx.scm")

Exception: variable A is not bound
Type (debug) to enter the debugger.
> (debug)
debug> i
#<system continuation in map>                                     : sf
  0: #<system continuation in map>
  1: #<system continuation in compile>
  2: #<system continuation in map>
  3: #<system continuation in compile>
  4: #<system continuation in compile>
  5: #<system continuation in ksrc>
  6: #<system continuation>
  7: #<system continuation in dynamic-wind>
  8: #<system continuation in dynamic-wind>
  9: #<system continuation in $reset-protect>
  10: #<system continuation in new-cafe>
#<system continuation in map>                                     : 

Use d and s to walk and inspect the stack frames until you see something familiar.

#<system continuation in map>                                     : s
  continuation:          #<system continuation in compile>
  frame and free variables:
  0: #<procedure compile>
  1: (#[#{Lsrc:Expr:call czsa1fcfzdeh493n-3-44} 44 #[...] #[...] (...)])
  2: ()
#<system continuation in map>                                     : d
#<system continuation in compile>                                 : s
  continuation:          #<system continuation in map>
  frame and free variables:
  0: #[#{primref a0xltlrcpeygsahopkplcn-2} + 19834 (-1)]
#<system continuation in compile>                                 : d
#<system continuation in map>                                     : s
  continuation:          #<system continuation in compile>
  frame and free variables:
  0: #{my-var *top*:my-var}
  1: ()

Here, we see my-var, which provides a clue.

On the other hand, if A occurs somewhere other than a variable definition ...

filexxx.scm

(define (my-procedure x)
  (+ A x))

(my-procedure 1)

... you'll likely find yourself at the site of the reference.

> (load "filexxx.scm")

Exception: variable A is not bound
Type (debug) to enter the debugger.
> (debug)
debug> i
#<continuation in my-procedure>                                   : sf
  0: #<continuation in my-procedure>
  1: #<system continuation in ksrc>
  2: #<system continuation>
  3: #<system continuation in dynamic-wind>
  4: #<system continuation in dynamic-wind>
  5: #<system continuation in $reset-protect>
  6: #<system continuation in new-cafe>

Here, we see my-procedure, another clue. And showing the frame with s reveals the expression within which A occurs.

#<continuation in my-procedure>                                   : s
  continuation:          #<system continuation in ksrc>
  procedure code:        (lambda (x) (+ A x))
  call code:             A
  frame and free variables:
  0. x:                  1
Peter Winton
  • 574
  • 3
  • 8