REF EXCEPTION                                       John Gibson Apr 1996

        COPYRIGHT University of Sussex 1996. All Rights Reserved.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<                             >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<          EXCEPTION          >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<          PROCEDURES         >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<                             >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

This file documents the Poplog exception handling facilities.

         CONTENTS - (Use <ENTER> g to access required sections)

  1   Overview

  2   Raising an Exception

  3   Handling Exceptions

  4   Printing Exceptions

  5   Exception ID Strings
      5.1   Standard Exception Classes
            ... arith
            ... control
            ... exsys
            ... mem
            ... name
            ... syntax
            ... type

  6   Exceptions Raised



-----------
1  Overview
-----------

An exception condition arises when a  program detects that an error  (or
possible error, etc) has  occurred during its  execution. A program  can
signal   an   exception   by   calling   sys_raise_exception,   allowing
user-definable handler procedures (or standard system handlers) to  deal
with the problem.

The arguments to sys_raise_exception comprise

  # a severity code;
  # an (optional) ID string that identifies the particular exception;
  # a message string together with any associated data items.

The severity code recognises four levels of severity, namely

  # Information
  # Warning
  # Recoverable error
  # Error

The variable procedure pop_exception_handler represents the first  stage
of exception handling, and may be redefined, either locally or globally.
sys_raise_exception calls all current (dynamically local) definitions of
this procedure, until one  returns true to say  that it has handled  the
exception  (or  performs   an  abnormal  exit).   A  true  return   from
pop_exception_handler indicates that  sys_raise_exception should  return
to its caller,  and normal program  execution should continue  (however,
this is  only  permissible  for  Information,  Warning  and  Recoverable
error).

If all current definitions  of pop_exception_handler return false  (i.e.
do not  wish to  handle the  exception), then  sys_exception_handler  is
called as  a backstop.  This provides  a second-stage  variable  handler
pop_exception_final,  which  is   called  in   the  same   way  as   for
pop_exception_handler.

However,  at  the  sys_exception_handler  stage,  it  is  assumed   that
continuing with normal  program execution  after an error  is no  longer
possible, and that  'handling' an  error will consist  (for example)  of
printing  an  appropriate  message.  Thus  while  a  true  return   from
pop_exception_final prevents  any further  handlers from  being  called,
sys_exception_handler always finishes  by either (a)  returning true  to
sys_raise_exception for Information or Warning, or (b) calling interrupt
for errors. (But, as with pop_exception_handler, pop_exception_final has
the option of performing an abnormal exit.)

The  backstop  for  pop_exception_final  is  sys_exception_final,  which
merely calls pop_pr_exception and returns true.

The normal sequence of events  in processing an exception is  summarised
by  the  following  diagram  (where   ...  means  calling  all   current
definitions until one returns true):


  sys_raise_exception --
                       |
pop_exception_handler ... sys_exception_handler --
                       |                         |
                       |    pop_exception_final ... sys_exception_final
                       |                         |          |
                       |                         |   pop_pr_exception
                       |                         |          |
                       |---------<--------(I,W)--+----<------
                       |                         |
                       |                       (R,E)
                       |                         |
                     return                  interrupt
                  (I,W,R only)


Note that pop_exception_handler is  intended to be  used to handle  (and
recover from) specific  exceptions only. All  'bulk' handling of  errors
should be done with pop_exception_final.

For  this  reason,  no  part  of  the  system  ever  locally   redefines
pop_exception_handler, which  is therefore  completely free  for use  by
user programs. (The system does locally redefine pop_exception_final  in
some contexts.)




-----------------------
2  Raising an Exception
-----------------------

sys_raise_exception(item1, ..., itemN, N,                    [procedure]
                                mess, idstring, severity)
sys_raise_exception(item1, ..., itemN, N, mess, severity)
sys_raise_exception(mess, itemlist, severity)
        Raises an exception condition, and calls user-defined  exception
        handlers in pop_exception_handler to deal with it.

        The arguments are as follows:

            item1, ..., itemN, N
                Zero or more data items  involved in the exception,  and
                the number  N  of  them:  these  are  dependent  on  the
                particular exception.

                (For backward compatibility, the  last form of the  call
                allows item1 ... itemN to  be passed in a list  itemlist
                following the  mess  argument.  This  call  form  cannot
                supply an idstring argument, and is now deprecated.)

            mess
                A message string describing  the exception (or a  vector
                whose  first  element  is   the  message  string).   See
                * sys_pr_message  for   a  full   description  of   this
                argument.

            idstring
                A  string  whose  characters  identify  the   particular
                exception  (defaults  to  nullstring  if  omitted).  See
                Exception ID Strings below.

            severity
                An integer ASCII character code specifying the  severity
                of the exception: `I` = Information, `W` = Warning,  `R`
                = Recoverable error, `E` = Error.

        sys_raise_exception searches up the call stack for dynamic local
        definitions of  the  variable  procedure  pop_exception_handler,
        starting with its current value. Each handler procedure P  found
        is called with all the given arguments, i.e.

            P(item1, ..., itemN, N, mess, idstring, severity)

        A handler may do one of three things:

        (1) Return false to  say that  it does  not want  to handle  the
            condition. sys_raise_exception will then continue by calling
            the next handler.  In addition  to false,  the handler  must
            also leave  item1  ...  itemN  on the  stack  for  the  next
            handler, i.e.

                P(...) -> (item1, ..., itemN, false)

            (Note that, if required, the code

                repeat N times subscr_stack(N) endrepeat;

            can be  used to  duplicate item1  ... itemN  on top  of  the
            stack.)

        (2) Return true to  say it  has handled the  condition. In  this
            case,  sys_raise_exception  will  return  normally  to   its
            caller.

            This is not permissible for severity = `E` (and results in a
            recursive error  with idstring  'exception-illret:control').
            For a recoverable error  `R`, the handler must  additionally
            leave on the  stack any results  expected by the  particular
            error.

        (3) Perform an abnormal exit  out of sys_raise_exception,  using
            exitfrom, chainfrom, setpop etc.

        If all  locally-defined  handlers return  false,  the  top-level
        value of  pop_exception_handler  is  run;  by  default  this  is
        * sys_exception_handler, but  if  this is  also  redefined,  and
        returns false, sys_exception_handler is run anyway.

        (N.B. If another  exception is raised  while calling a  handler,
        the recursive call of  sys_raise_exception will call only  those
        handlers that have not  yet been tried  by outer invocations  of
        sys_raise_exception.)


mishap(item1, ..., itemN, N, mess, idstring)                  [procedure]
mishap(item1, ..., itemN, N, mess)
mishap(mess, itemlist)
        This procedure is  sys_raise_exception(% `E` %),  i.e. raise  an
        error.




----------------------
3  Handling Exceptions
----------------------

pop_exception_handler(item1, ..., itemN, N,         [procedure variable]
                mess, idstring, severity) -> bool
        A user-definable first-stage handler for exceptions. All current
        definitions    of     this    procedure     are    called     by
        * sys_raise_exception (described  above). Its  default value  is
        sys_exception_handler.


sys_exception_handler(item1, ..., itemN, N,                  [procedure]
                            mess, idstring, severity)
        This procedure is  the default  value of  pop_exception_handler,
        called by  sys_raise_exception.  See  * sys_raise_exception  for
        details of the arguments.

        sys_exception_handler searches  up the  call stack  for  dynamic
        local definitions of the variable procedure pop_exception_final,
        starting with its current value. Each handler procedure P  found
        is called with all the given arguments, i.e.

            P(item1, ..., itemN, N, mess, idstring, severity)

        A handler may do one of three things:

        (1) Return false to say that  the next handler should be  tried.
            In addition to false, the handler must also leave item1  ...
            itemN on the stack for the next handler, i.e.

                P(...) -> (item1, ..., itemN, false)

        (2) Return true to say no further handlers should be called.

        (3) Perform an abnormal exit  using exitfrom, chainfrom,  setpop
            etc.

        If all  locally-defined  handlers return  false,  the  top-level
        value  of  pop_exception_final  is  run;  by  default  this   is
        * sys_exception_final,  but  if  this  is  also  redefined,  and
        returns false,  sys_exception_final  is run  anyway  (this  will
        always return true).

        (N.B. If another exception is raised while calling a  handler, a
        recursive call  of sys_exception_handler  will call  only  those
        handlers that have not  yet been tried  by outer invocations  of
        sys_exception_handler.)

        After calling the  handlers, sys_exception_handler just  returns
        if   severity   =   `I`   or   `W`   (i.e.   returns   true   to
        sys_raise_exception).

        Otherwise, for errors,  the procedure in  * interrupt is  called
        (and if that  returns, * setpop). Before  calling interrupt  (in
        fact,  before   calling   the   pop_exception_final   handlers),
        * pop_exit_ok is set  to false  if the standard  input is  not a
        terminal. (Since  the default  value  of interrupt  under  these
        circumstances is  sysexit, this  guarantees that  an error  will
        result in an error status being returned to the operating system
        -- see REF * SYSTEM.)


pop_exception_final(item1, ..., itemN, N,           [procedure variable]
                mess, idstring, severity) -> bool
        A user-definable  final  handler  for  exceptions.  All  current
        definitions    of     this    procedure     are    called     by
        * sys_exception_handler (described above). Its default value  is
        sys_exception_final.


sys_exception_final(item1, ..., itemN, N,                    [procedure]
                            mess, idstring, severity)
        This procedure  is  the default  value  of  pop_exception_final,
        called by * sys_exception_handler.

        It simply calls * pop_pr_exception with the given arguments, and
        then returns true to sys_exception_handler.




----------------------
4  Printing Exceptions
----------------------

All the default Poplog routines for printing mishap and warning messages
use the procedure sys_pr_message  to print the message,  as well as  the
current file, line number and other useful information.


pop_pr_exception(item1, ..., itemN, N,              [procedure variable]
                        mess, idstring, severity)
        A variable procedure called by * sys_exception_final to print an
        error or warning message for an exception. Its default value  is
        sys_pr_exception. (However,  the procedure  sys_pr_exception  is
        only required  for  backward compatibility  reasons;  otherwise,
        pop_pr_exception would default to sys_pr_message.)


pop_default_pr_exception(item1, ..., itemN, N,      [procedure variable]
                        mess, idstring, severity)
        If this variable  has a non-undef  value (i.e. not(isundef))  it
        will be assigned to pop_pr_exception in contexts where otherwise
        a system procedure would be locally assigned.

        In  particular  inside  Ved,  pop_pr_exception  has  the   value
        ved_pr_exception. However, in  immediate mode,  sys_pr_exception
        is assigned to it instead,  and inside ved_lmr is is  assigned a
        special procedure which displays  certain mishaps on the  status
        line, etc. In both these contexts pop_default_pr_exception  will
        be used instead, if defined by the user (e.g. in your init.p  or
        vedinit.p file).


sys_pr_exception(item1, ..., itemN, N,                       [procedure]
                        mess, idstring, severity)
        This procedure  is  necessary only  for  backward  compatibility
        reasons, namely  to call  the obsolete  procedures prmishap  and
        prwarning (i.e. when the exception  relates to one of them,  and
        that one  is set  to something  other than  its default  value).
        Otherwise, sys_pr_exception just calls sys_pr_message.


sys_pr_message(item1, ..., itemN, N,                          [procedure]
                        mess, idstring, severity)
        Prints a  message (usually  for  an exception),  outputting  the
        characters through * cucharerr.

        The arguments are as follows:

            item1, ..., itemN, N
                Zero or more 'culprit' data  items, and the number N  of
                them:   these   are   dependent   on   the    particular
                message/exception.

            mess
                A message string to be printed. Alternatively, it may be
                a 2- or  3-element vector  whose  first element  is  the
                message string, and whose second or third element(s) are
                a header_string and an integer detail_level, i.e.

                    { message_string header_string detail_level }

                If not supplied, header_string defaults to 'NOTE -'  for
                severity = `I`, to 'WARNING -'  for severity = `W`,  and
                to 'MISHAP -' otherwise.

                If not supplied, detail_level defaults to 4 for severity
                = `I` or `W`, and to  5 otherwise. Note that the  actual
                detail level must be 0-5, and only the bottom 4 bits  of
                detail_level are used for  this; the remaining bits  can
                specify a number  of newlines  to be  output before  the
                message (e.g. 16:14 means 1 newline, detail level 4).

                In all cases,  the actual  detail level used  is got  by
                maximising the  argument  (or default)  value  with  the
                value of the variable pop_message_min_detail.

                The actual message string used is got by processing  the
                given  string  (together  with  the  idstring  argument)
                through the  variable procedure  pop_message_trans.  (By
                default, this just returns the same string.)

            idstring
                A  string   whose  characters   identify  a   particular
                message/exception (see Exception ID Strings below).

            severity
                An integer ASCII character code specifying the  severity
                of  the  message/exception:  `I`  =  Information,  `W` =
                Warning, `R`  = Recoverable  error, `E`  = Error.  (This
                procedure does not distinguish between `R` and `E`.)

        The full format of the message printed by sys_pr_message is

            ;;; header_string message_string
            ;;; INVOLVING:  item1 item2 ... itemN
            ;;; FILE     :  popfilename  LINE NUMBER poplinenum
            ;;; COMPILING:  names of procedures being compiled
            ;;; DOING    :  pdprops of procedures currently executing

        (popfilename and  poplinenum  are associated  with  the  current
        input list proglist -- see REF * PROGLIST.)

        The detail level controls how many  of the 5 lines are  printed:
        if 0, only the header string is  printed; if 5, all 5 lines  are
        printed. Note that the INVOLVING  line is present only if  there
        are 1  or more  culprits, the  FILE line  is present  only  when
        popfilename is true, and the COMPILING line is present only when
        the Poplog VM is not at execute level.

        message_string is  printed using  * sys_message_printf, with  an
        argument  list  containing  item1   ...  itemN.  (That  is,   if
        message_string starts with a % character, the string without the
        initial %  is  printed using  printf,  otherwise the  string  is
        printed  literally.)  Only  the  remaining  items  returned   by
        sys_message_printf (i.e those  not picked up  by printf %  field
        specifiers) will be used as culprits for the INVOLVING line.

        See also  * popsyscall,  * pop_mishap_doing_lim,  * popmessages,
        * popmishaps, * popwarnings.


pop_message_trans(message_string, idstring)         [procedure variable]
                                  -> message_string
        Called by sys_pr_message (with its idstring argument) to perform
        any required translation  of a  message_string before  printing.
        The   default   value   is   erase   (i.e.   return   the   same
        message_string).


pop_message_min_detail -> int                                 [variable]
int -> pop_message_min_detail
        The  given  (or  default)  detail  level  in  sys_pr_message  is
        maximised with the value in this variable. Its default value  is
        0; setting it  to 4 (for  example) will cause  warnings such  as
        DECLARING VARIABLE to print everything but the DOING line.


popsyscall -> bool                                            [variable]
bool -> popsyscall
        Controls which procedures  currently executing  are included  in
        the DOING list for messages produced by sys_pr_message.

        If false (the  default), only procedures  whose pdprops are  not
        false and which  are not "uninteresting"  are printed (where  an
        "uninteresting" procedure is one whose pdprops are not "setpop",
        or a word being with  'sys', 'ved', 'wved', 'xved', 'subsys'  or
        'pop11_'.

        For a true value, all procedures are printed. If the true  value
        is additionally an integer, then system procedures whose pdprops
        are false are printed as their hexadecimal addresses.

        (In addition, a true value  causes sys_pr_message to print  each
        invocation of  * sys_raise_exception  starting on  a  new  line,
        followed  by  the  idstring  argument  of  that  invocation   in
        parentheses.)


pop_mishap_doing_lim -> false_or_int                          [variable]
false_or_int -> pop_mishap_doing_lim
        Controls the number of procedures  printed in the DOING list  of
        messages produced by sys_pr_message.

        If false (the default),  all currently executing procedures  are
        included;  otherwise  it  should   be  a  positive  integer   N,
        specifying that only the most recent N callers are to be shown.

        If set to 0, the DOING list is not printed at all.


popmessages -> list_or_false                                  [variable]
list_or_false -> popmessages
        Each time sys_pr_message is called to print a message it  puts a
        summary of the message  (as a list of  items) it this  variable.
        This can be disabled by assigning false to popmessages. (Default
        value []).


popmishaps -> list_or_false                                   [variable]
list_or_false -> popmishaps
        Each time sys_pr_message  is called  to print  an error  message
        (i.e. severity `R` or `E`) it puts in this variable a summary of
        the message printed (as list  of items); this is overwrites  any
        previous mishap  message.  You  can prevent  the  message  being
        stored by assigning false to popmishaps. (Default value []).


popwarnings -> list_or_false                                  [variable]
list_or_false -> popwarnings
        When sys_pr_message  is called  to  print a  DECLARING  VARIABLE
        warning message by * sysdeclare (that is, a warning message with
        idstring 'vm-ident:name-ref-none'),  the  name  of  the  culprit
        identifier is added to this list.

        The initial value of  popwarnings is [].  If popwarnings is  set
        false, no list is created.




-----------------------
5  Exception ID Strings
-----------------------

The idstring  argument to  sys_raise_exception and  other procedures  in
this file is a string  whose characters identify a particular  exception
condition.

The general format of an idstring is a context part separated by a colon
from a class part, i.e.

        context:class

The context  part  specifies  the  context  or  facility  in  which  the
exception  occurred,   while  the   class   part  provides   a   generic
classification of the type of error, etc.

Each part may be further subdivided by hyphens into as many  hierachical
components as required, i.e.

        context-subcontext-subsubcontext:class-subclass-subsubclass

For example, the sysdeclare warning idstring

        vm-ident:name-ref-none

specifies that the problem is in a Poplog VM procedure, and concerns  an
identifier name; the class of the exception is name, subclass ref (using
the referent of a name), sub-subclass none (referent does not exist).

Note that the colon in an idstring is considered part of the class, i.e.
must always be present if class  is non-empty. (An idstring of the  form
:class indicates a 'generic' error.)



5.1  Standard Exception Classes
-------------------------------
The  system  currently  defines  the  following  standard  classes   for
exceptions (more will be added in future versions).


...  arith
----------
Arithmetic errors.

arith-fltovf                                           [exception class]
        An arithmetic operation resulted in floating-point overflow.


arith-div0                                             [exception class]
        Attempt to divide a rational  number by integer zero (note  that
        dividing floating-point by zero produces arith-fltovf).


...  control
------------

control                                                [exception class]
        Some kind of error in the flow of control.


...  exsys
----------
This class is intended for exceptions relating to external systems,  and
is further subclassed  by (at least)  the name of  a particular  system.
(For example,  LIB * ODBC  uses  :exsys-odbc-sqlstate,  where  different
sqlstate values represent  standard error classes  as defined by  X/Open
and SQL Access Group.)


...  mem
--------
These are errors concerning the allocation of memory in some area of the
system (e.g. heap,  userstack, callstack, etc).  They divide into  limit
errors (advisory limit reached) and nomore (no more memory available).

mem-limit                                              [exception class]
        While trying  to allocate  more space  in a  particular area  of
        memory, the advisory limit on the area's size was reached.


mem-nomore                                             [exception class]
        While trying  to allocate  more space  in a  particular area  of
        memory, the absolute  (e.g. operating system  imposed) limit  on
        the area's size was reached.


mem-fixedsize                                          [exception class]
        A fixed size memory area was exhausted.


...  name
---------
name errors concern the  association between a name  and an object  (its
referent). The name class subdivides into decl (declaring the name, i.e.
establishing a referent for it) and ref (using the referent).

name-decl-prot                                         [exception class]
        A  name  being  declared  already   has  a  referent,  and   the
        association is protected (i.e. cannot be overridden).


name-decl-ambig                                        [exception class]
        A name  being declared  already  has a  referent, which  can  be
        overridden, but only if the new referent is sufficently  similar
        to the  old in  some respect  (which it  is not,  hence the  new
        declaration is ambiguous).


name-ref-inval                                         [exception class]
        A name was supplied to an operation which uses its referent, but
        the referent is invalid for the particular operation.


name-ref-none                                          [exception class]
        A name was supplied to an operation which uses its referent, but
        the name has no referent.


...  syntax
-----------

syntax                                                 [exception class]
        Any kind of syntactic error in a language.


...  type
---------
These concern  supplying  the wrong  type  of  data as  argument  to  an
operation. They are subclassed by  the dataword (or pseudo-dataword)  of
the type needed.

type-integer                                           [exception class]
        An argument was not an integer.


type-intrange                                          [exception class]
        An argument was an integer, but out-of-range.


type-real                                              [exception class]
        An argument was not a real number.


type-number                                            [exception class]
        An argument was not a number.




--------------------
6  Exceptions Raised
--------------------

This section describes exceptions generated by procedures in this file.


exception-illret:control                                  [exception ID]
        (Error)  A  pop_exception_handler  procedure  returned  true  to
        sys_raise_exception for severity `E` (which is only allowed  for
        `I`, `W` and `R`).




--- C.all/ref/exception
--- Copyright University of Sussex 1996. All rights reserved.
