Errors, Assertions, and Traces |
|
|
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 obj | bigloo procedure |
Returns a string which is the name of the dynamic type of obj .
|
error proc msg obj | bigloo 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 location | bigloo 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 size | bigloo procedure |
dump-trace-stack output-port size | bigloo 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 exc | bigloo procedure |
error-notify err | bigloo procedure |
warning-notify err | bigloo procedure |
Display a message describing the error or warning on the default error port.
|
current-exception-handler | SRFI-18 function |
Returns the current exception handler with is a 0-ary procedure.
|
with-exception-handler handler thunk | SRFI-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 body | bigloo 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 obj | SRFI-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)
|
try exp handler | bigloo 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
=> '()
|
|
assert (var...) s-expression | bigloo 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
-----------------------
*:=>
|
|
Bigloo provides a trace facility whose is intended for simple
debugging tasks. It is a replacement for user display s 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 . body | bigloo 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 . args | bigloo function |
This function displays all its arguments. It has to be used nested in
a with-trace form.
|
trace-bold s | bigloo function |
trace-string s | bigloo function |
These two functions are provided for convenience. They returns strings
made of their parameters.
|
trace-color color . args | bigloo 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-margin | bigloo 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-port | bigloo function |
trace-port-set! | bigloo function |
These functions return and set the output port used by traces.
|
|