@c =================================================================== @c
@c    serrano/prgm/project/bigloo/manuals/error.texi                   @c
@c    ------------------------------------------------------------     @c
@c    Author      :  Manuel Serrano                                    @c
@c    Creation    :  Mon Jun 15 10:31:21 1998                          @c
@c    Last change :  Mon Nov 12 15:20:43 2001 (serrano)                @c
@c    ------------------------------------------------------------     @c
@c    The error handling                                               @c
@c =================================================================== @c

@c ------------------------------------------------------------------- @c
@c    Error handling ...                                               @c
@c ------------------------------------------------------------------- @c
@node Errors and Assertions, Eval, Lalr Parsing, Top
@comment  node-name,  next,  previous,  up
@chapter Errors and Assertions
@cindex error handling
@cindex assertions

Bigloo permits to signal an error via the @code{error} function. Errors
may be trapped with the @code{try} form. Assertions allow the checking
of predicates at certain points in programs.  


@deffn {bigloo procedure} error proc msg obj
This form signals an error by calling the current error handler with
@var{proc}, @var{msg} and @var{obj} as arguments.

@smalllisp
(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
@end smalllisp

Switching on the @code{-g} compilation switch enables stack dumping
when the @code{error} function is invoked. That is, when a program is
compiled with @code{-g} and when, at runtime, the shell variable
@code{BIGLOOSTACKDEPTH} is set and contains a number, an execution
stack of depth @code{BIGLOOSTACKDEPTH} is printed when an error is
raised.
@end deffn

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

@smalllisp
(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
@end smalllisp
@end deffn

@deffn {bigloo syntax} try exp handler

The argument @var{exp} is evaluated. If an error is raised, the
@var{handler} is called. The argument @var{handler} is a procedure of
four arguments. Its first argument is the continuation of @var{try}. The
other arguments are @var{proc}, @var{msg} and @var{obj}. Invoking the
first argument will resume after the error.

@smalllisp
(let ((handler (lambda (escape proc mes obj)
                  (print "***ERROR:" proc ":" mes " -- " obj)
                  (escape #f))))
   (try (car 1) handler))
   @print{} ***ERROR:CAR:not a pair -- 1
   @result{} #f
@end smalllisp

The argument @var{handler} is not evaluated in the dynamic scope of its
@code{try} form. That is:

@smalllisp
(let ((handler (lambda (escape proc mes obj)
                  (escape (car obj)))))
   (try (car 1) handler))
   @error{} *** ERROR:bigloo:CAR
            Type `PAIR' expected, `BINT' provided -- 1
@end smalllisp
@end deffn

Some library functions exist to help in writing handlers:

@deffn {bigloo procedure} notify-error proc msg obj
Display on error port @var{proc}, @var{msg} and @var{obj}.
@end deffn

@deffn {bigloo variable} *warning*
If this variable is @code{#t} warning messages are enabled.
@end deffn

@deffn {bigloo procedure} warning [arg]@dots{}
This form signals a warning. That is, is @var{arg} are displayed
on the standard error port.

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

(foo 4)
@print{} *** WARNING:bigloo:foo:
   argument not a pair -- 4
@result{} '()
@end smalllisp
@end deffn

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

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

(foo 4)
@print{} File "foo.scm", line 6, character 154:
   #       (car l)))
   #       ^
   # *** WARNING:bigloo:foo:
   argument not a pair -- 4
@result{} '()
@end smalllisp
@end deffn

@deffn {bigloo syntax} assert (var@dots{}) s-expression

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

Assertion forms are legal expressions which @emph{always} evaluate
to the @code{unspecified} object.

Here is an example of assertion usage:

@smalllisp
(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)
@end smalllisp

This module is compiled with the @code{-g} flag to enable assertions, then
the produced executable is run:

@display
$ 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
-----------------------

*:=> 
@end display
@end deffn
