Diff for /gforth/doc/gforth.ds between versions 1.171 and 1.172

version 1.171, 2007/02/08 14:07:33 version 1.172, 2007/02/19 00:08:20
Line 2847  like this: Line 2847  like this:
    ( ... n ) throw ;     ( ... n ) throw ;
 @end example  @end example
   
 Gforth provides an alternative syntax in addition to @code{catch}:  However, this is still not safe against, e.g., the user pressing
 @code{try ... recover ... endtry}.  If the code between @code{try} and  @kbd{Ctrl-C} when execution is between the @code{catch} and
 @code{recover} has an exception, the stack depths are restored, the  @code{restore-x}.
 exception number is pushed on the stack, and the code between  
 @code{recover} and @code{endtry} is performed.  E.g., the definition for  Gforth provides an alternative exception handling syntax that is safe
 @code{catch} is  against such cases: @code{try ... restore ... endtry}.  If the code
   between @code{try} and @code{endtry} has an exception, the stack
   depths are restored, the exception number is pushed on the stack, and
   the execution continues right after @code{restore}.
   
 @example  The safer equivalent to the restoration code above is
 : catch ( x1 .. xn xt -- y1 .. ym 0 / z1 .. zn error ) \ exception  
   try  
     execute 0  
   recover  
     nip  
   endtry ;  
 @end example  
   
 The equivalent to the restoration code above is  
   
 @example  @example
 : ...  : ...
   save-x    save-x
   try    try
     word-changing-x 0      word-changing-x 0
   recover endtry    restore
   restore-x      restore-x
     endtry
   throw ;    throw ;
 @end example  @end example
   
 This works if @code{word-changing-x} does not change the stack depth,  
 otherwise you should add some code between @code{recover} and  
 @code{endtry} to balance the stack.  
   
 Reference: @ref{Exception Handling}.  Reference: @ref{Exception Handling}.
   
   
Line 5709  therefore Gforth provides an alternative Line 5700  therefore Gforth provides an alternative
 @example  @example
 TRY  TRY
   @i{code1}    @i{code1}
 RECOVER    IFERROR
   @i{code2} \ optional      @i{code2}
     THEN
     @i{code3}
 ENDTRY  ENDTRY
 @end example  @end example
   
 This performs @i{Code1}.  If @i{code1} completes normally, execution  This performs @i{code1}.  If @i{code1} completes normally, execution
 continues after the @code{endtry}.  If @i{Code1} throws, the stacks are  continues with @i{code3}.  If @i{code1} or there is an exception
 reset to the state during @code{try}, the throw value is pushed on the  before @code{endtry}, the stacks are reset to the state during
 data stack, and execution constinues at @i{code2}, and finally falls  @code{try}, the throw value is pushed on the data stack, and execution
 through the @code{endtry} into the following code.  constinues at @i{code2}, and finally falls through the @i{code3}.
   
 doc-try  doc-try
 doc-recover  
 doc-endtry  doc-endtry
   doc-iferror
   
   If you don't need @i{code2}, you can write @code{restore} instead of
   @code{iferror then}:
   
   @example
   TRY
     @i{code1}
   RESTORE
     @i{code3}
   ENDTRY
   @end example
   
   @cindex unwind-protect
 The cleanup example from above in this syntax:  The cleanup example from above in this syntax:
   
 @example  @example
 base @ >r TRY  base @ @{ oldbase @}
   TRY
   hex foo \ now the hex is placed correctly    hex foo \ now the hex is placed correctly
   0       \ value for throw    0       \ value for throw
 RECOVER ENDTRY  RESTORE
 r> base ! throw    oldbase base !
   ENDTRY
   throw
 @end example  @end example
   
 And here's the error handling example:  An additional advantage of this variant is that an exception between
   @code{restore} and @code{endtry} (e.g., from the user pressing
   @kbd{Ctrl-C}) restarts the execution of the code after @code{restore},
   so the base will be restored under all circumstances.
   
   However, you have to ensure that this code does not cause an exception
   itself, otherwise the @code{iferror}/@code{restore} code will loop.
   Moreover, you should also make sure that the stack contents needed by
   the @code{iferror}/@code{restore} code exist everywhere between
   @code{try} and @code{endtry}; in our example this is achived by
   putting the data in a local before the @code{try} (you cannot use the
   return stack because the exception frame (@i{sys1}) is in the way
   there).
   
   This kind of usage corresponds to Lisp's @code{unwind-protect}.
   
   @cindex @code{recover} (old Gforth versions)
   If you do not want this exception-restarting behaviour, you achieve
   this as follows:
   
 @example  @example
 TRY  TRY
   foo    @i{code1}
   ENDTRY-IFERROR
     @i{code2}
   THEN
   @end example
   
   If there is an exception in @i{code1}, then @i{code2} is executed,
   otherwise execution continues behind the @code{then} (or in a possible
   @code{else} branch).  This corresponds to the construct
   
   @example
   TRY
     @i{code1}
 RECOVER  RECOVER
     @i{code2}
   ENDTRY
   @end example
   
   in Gforth before version 0.7.  So you can directly replace
   @code{recover}-using code; however, we recommend that you check if it
   would not be better to use one of the other @code{try} variants while
   you are at it.
   
   doc-restore
   doc-endtry-iferror
   
   Here's the error handling example:
   
   @example
   TRY
     foo
   ENDTRY-IFERROR
   CASE    CASE
     myerror OF ... ( do something about it ) nothrow ENDOF      myerror OF ... ( do something about it ) nothrow ENDOF
     throw \ pass other errors on      throw \ pass other errors on
   ENDCASE    ENDCASE
 ENDTRY  THEN
 @end example  @end example
   
 @progstyle  @progstyle

Removed from v.1.171  
changed lines
  Added in v.1.172


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>