16. Bigloo
A practical Scheme compiler
User manual for version 4.2a
September 2015 -- Errors, Assertions, and Traces

16.1 Errors and Warnings

Bigloo permits to signal an error via the error function. Errors are implemented by the means of exceptions (see with-exception-handler, with-handler, and raise forms). Assertions allow the checking of predicates at certain points in programs.

typeof objbigloo procedure
Returns a string which is the name of the dynamic type of obj.

error proc msg objbigloo procedure
This form signals an error by calling the current error handler with proc, msg and obj as arguments.

(define (foo l)
   (if (not (pair? l))
       (error "foo" "argument not a pair" l)
       (car l)))

(foo 4) error--> *** ERROR:bigloo:foo: argument not a pair -- 4
Switching on the -g compilation switch enables stack dumping when the error function is invoked. That is, when a program is compiled with -g and when, at runtime, the shell variable BIGLOOSTACKDEPTH is set and contains a number, an execution stack of depth BIGLOOSTACKDEPTH is printed when an error is raised.

error/location proc msg obj file locationbigloo procedure
This form signals an error by calling the current error handler with proc, msg and obj as arguments. The error is prompted in file, at character position location.

(define (foo l)
   (if (not (pair? l))
       (error/location
         "foo" "argument not a pair" l "foo.scm" 115)
       (car l)))

(foo 4) error--> File "foo.scm", line 4, character 115: # (car l))) # ^ # *** ERROR:bigloo:foo # argument not a pair -- 4 0. FOO 1. DYNAMIC-WIND 2. INTERP 3. ENGINE 4. MAIN

get-trace-stack sizebigloo procedure
dump-trace-stack output-port sizebigloo procedure
Switching on the -g compilation switch enables stack dumping Compiler Description. That is, the list of the pending calls can be dumped by the runtime-system. The function get-trace-stack builds such a trace. The list built by get-trace-stack only contains the size top most pending calls. The function dump-trace-stack displays a representation of this stack on the output-port.


warning/location file location [arg]...bigloo procedure
This form signals a warning. That is, is arg are displayed on the standard error port. The warning is prompted in file at character position location.

(define (foo l)
   (if (not (pair? l))
       (begin
          (warning/location
            "foo.scm" 154 "foo:" "argument not a pair -- " l)
          '())
       (car l)))

(foo 4) -| File "foo.scm", line 6, character 154: # (car l))) # ^ # *** WARNING:bigloo:foo: argument not a pair -- 4 => '()

exception-notify excbigloo procedure
error-notify errbigloo procedure
warning-notify errbigloo procedure
Display a message describing the error or warning on the default error port.


16.2 Exceptions

current-exception-handlerSRFI-18 function
Returns the current exception handler with is a 0-ary procedure.

with-exception-handler handler thunkSRFI-18 function
Returns the result(s) of calling thunk with no arguments. The handler, which must be a procedure, is installed as the current exception handler in the dynamic environment in effect during the call to thunk. When possible, prefer with-handler to with-exception-handler because the former provides better debugging support and because its semantics is more intuitive.

with-handler handler bodybigloo form
Returns the result(s) of evaluating body. The handler, which must be a procedure, is installed as the current exception handler in the dynamic environment in effect during the evaluation of body. Contrarily to with-exception-handler, if an exception is raised, the handler is invoked and the value of the with-handler form is the value produced by invoking the handler. The handler is executed in the continuation of the with-handler form.

JVM note: When executed within a JVM, the form with-handler also catches Java exceptions.

Important note: Since Bigloo version 3.2c, error handlers are executed after the execution stack is unwound. Hence, error handlers are executed after protected blocks. For instance in the following code:

(with-handler 
   (lambda (e) action)
   (unwind-protect
      body
      protect))
The action is executed after protect.


raise objSRFI-18 function
Calls the current exception handler with obj as the single argument. obj may be any Scheme object. Note that invoking the current handler does not escape from the current computation. It is up the to handler to perform the escape. It an error, signaled by the runtime system, if the current exception handler returns.

(define (f n)
  (if (< n 0) (raise "negative arg") (sqrt n))))

(define (g) (bind-exit (return) (with-exception-handler (lambda (exc) (return (if (string? exc) (string-append "error: " exc) "unknown error"))) (lambda () (write (f 4.)) (write (f -1.)) (write (f 9.))))))

(g) -| 2. and returns "error: negative arg"

The standard Bigloo runtime system uses the following classes for signaling errors and warnings:

  • &exception which is defined as:
    (class &exception
       (fname read-only (default #f))
       (location read-only (default #f)))
    
  • &error defined as:
    (class &error::&exception
       (proc read-only)
       (msg read-only)
       (obj read-only))
    
  • &type-error defined as:
    (class &type-error::&error
       (type read-only))
    
  • &io-error defined as:
    (class &io-error::&error)
    
  • &io-port-error defined as:
    (class &io-port-error::&io-error)
    
  • &io-read-error defined as:
    (class &io-read-error::&io-port-error)
    
  • &io-write-error defined as:
    (class &io-write-error::&io-port-error)
    
  • &io-closed-error defined as:
    (class &io-closed-error::&io-port-error)
    
  • &io-file-not-found-error defined as:
    (class &io-file-not-found-error::&io-error)
    
  • &io-parse-error defined as:
    (class &io-parse-error::&io-error)
    
  • &io-unknown-host-error defined as:
    (class &io-unknown-host-error::&io-error)
    
  • &io-malformed-url-error defined as:
    (class &io-malformed-url-error::&io-error)
    
  • &http-error defined as:
    (class &http-error::&error)
    
  • &http-redirection-error defined as:
    (class &http-redirection-error::&http-error)
    
  • &http-status-error defined as:
    (class &http-status-error::&http-error)
    
  • &http-redirection defined as:
    (class &http-redirection::&exception
      (port::input-port read-only)
      (url::bstring read-only))
    
  • &process-exception defined as:
    (class &process-exception::&error)
    
  • &warning defined as:
    (class &warning::&exception
       (args read-only))
    
  • &eval-warning defined as:
    (class &warning::&warning)
    

16.3 Deprecated try form

try exp handlerbigloo syntax
This form is deprecated. As much as possible, it should be replaced with true exceptions (i.e., with-exception-handler and raise). The argument exp is evaluated. If an error is raised, the handler is called. The argument handler is a procedure of four arguments. Its first argument is the continuation of try. The other arguments are proc, mes and obj. Invoking the first argument will resume after the error.

(let ((handler (lambda (escape proc mes obj)
                  (print "***ERROR:" proc ":" mes " -- " obj)
                  (escape #f))))
   (try (car 1) handler))
   -| ***ERROR:CAR:not a pair -- 1
   => #f
The argument handler is not evaluated in the dynamic scope of its try form. That is:

(let ((handler (lambda (escape proc mes obj)
                  (escape (car obj)))))
   (try (car 1) handler))
   error--> *** ERROR:bigloo:CAR
            Type `PAIR' expected, `BINT' provided -- 1

Some library functions exist to help in writing handlers:

warning [arg]...bigloo procedure
This form signals a warning. That is, is arg are displayed on the standard error port.

(define (foo l)
   (if (not (pair? l))
       (begin
          (warning "foo:" "argument not a pair -- " l)
          '())
       (car l)))

(foo 4) -| *** WARNING:bigloo:foo: argument not a pair -- 4 => '()


16.4 Assertions

assert (var...) s-expressionbigloo syntax
Assertions can be enabled or disabled using Bigloo's compilation flags -g flag to enable them). If the assertions are disabled they are not evaluated. If an assertion is evaluated, if the expression exp does not evaluate to #t, an error is signaled and the interpreter is launched in an environment where var... are bound to their current values.

Assertion forms are legal expressions which always evaluate to the unspecified object.

Here is an example of assertion usage:

(module foo
   (eval (export foo)))

(define (foo x y) [assert (x y) (< x y)] (labels ((gee (t) [assert (t) (>= t 0)] (let ((res (+ x t))) [assert (res t) (> res 10)] res))) (set! x (gee y)) [assert (x) (> x 10)] x))

(repl)
This module is compiled with the -g flag to enable assertions, then the produced executable is run:

$ a.out

1:=> (foo 1 2)

File "foo.scm", line 9, character 158: # [assert (res t) (> res 10)] # ^ # *** ERROR:bigloo:assert # assertion failed -- (BEGIN (> RES 10)) 0. GEE 1. FOO ----------------------- Variables' value are : RES : 3 T : 2 ----------------------- *:=> ^D File "foo.scm", line 12, character 228: # [assert (x) (> x 10)] # ^ # *** ERROR:bigloo:assert # assertion failed -- (BEGIN (> X 10)) 0. FOO ----------------------- Variables' value are : X : 3 -----------------------

*:=> 3 1:=> (foo 1 2) File "foo.scm", line 9, character 158: # [assert (res t) (> res 10)] # ^ # *** ERROR:bigloo:assert # assertion failed -- (BEGIN (> RES 10)) 0. GEE 1. FOO ----------------------- Variables' value are : RES : 3 T : 2 -----------------------

*:=>


16.5 Tracing

Bigloo provides a trace facility whose is intended for simple debugging tasks. It is a replacement for user displays that clutters the source code. Here is a typical example using it:

(define (foo x)
   (with-trace 1 'foo
      (let loop ((n x))
	 (with-trace 2 'loop
	    (trace-item "n=" n)
	    (when (> n 0)
	       (let liip ((m n))
		  (with-trace 2 'liip
		     (trace-item "m=" m))
		  (when (> m 0)
		     (liip (- m 1))))
	       (loop (- n 1)))))))

(foo 3)
which produces the following output:

+ foo
  |--+ loop
  |  |- n=3
  |  |--+ liip
  |  |  |- m=3
  |  |--+ liip
  |  |  |- m=2
  |  |--+ liip
  |  |  |- m=1
  |  |--+ liip
  |  |  |- m=0
  |  |--+ loop
  |  |  |- n=2
  |  |  |--+ liip
  |  |  |  |- m=2
  |  |  |--+ liip
  |  |  |  |- m=1
  |  |  |--+ liip
  |  |  |  |- m=0
  |  |  |--+ loop
  |  |  |  |- n=1
  |  |  |  |--+ liip
  |  |  |  |  |- m=1
  |  |  |  |--+ liip
  |  |  |  |  |- m=0
  |  |  |  |--+ loop
  |  |  |  |  |- n=0
Traces generation is controlled by a set of functions and parameters (see Parameters). The functions are described in this chapter.

with-trace level label . bodybigloo syntax
The variable level is the level of a trace. It is a positive integer. It enables simple filtering for traces. A trace is displayed if and only if the debugging level used to compile or to execute the program is greater than the trace level. The variable label is a label, .e.i., an identifier denoting the trace. This identifier will be displayed in debug mode. The variable body is the body of the form, that is, the expression to be evaluated.

Unless a trace is activated (with-trace lv la body) (when its level lv is greater than the current debug level) is equivalent to (begin body). When traces are activated, before executing body.

The debugging level is controlled by two parameters: bigloo-debug and bigloo-compiler-debug (see Parameters).


trace-item . argsbigloo function
This function displays all its arguments. It has to be used nested in a with-trace form.

trace-bold sbigloo function
trace-string sbigloo function
These two functions are provided for convenience. They returns strings made of their parameters.

trace-color color . argsbigloo function
The color argument is a positive integer. This function returns a string which is the representation of args and that appears on the terminal in color color.

Colors can be enable or disabled using the bigloo-trace-color parameter (see Parameters).

trace-marginbigloo function
trace-margin-set!bigloo function
The trace-margin parameter is used to control the characters that are displayed in the margin of a trace. Usual applications should not use this. However, it may be convenient to set the margin by hands in some context. For instance, it can be used to distinguished threads in a multi-threaded application such as:

(make-thread (lambda () 
                (trace-margin-set! (trace-color 1 "="))
                ...))
(make-thread (lambda () 
                (trace-margin-set! (trace-color 2 "="))
                ...))

trace-portbigloo function
trace-port-set!bigloo function
These functions return and set the output port used by traces.





This Html page has been produced by Skribe.
Last update Thu Sep 3 08:07:38 2015.