error handling documentation

cvs
Slava Pestov 2006-01-07 21:03:31 +00:00
parent cd16dd9dae
commit 4b48581234
7 changed files with 58 additions and 51 deletions

View File

@ -21,18 +21,18 @@ HELP: >continuation< "( continuation -- data call name catch )"
{ $description "Takes a continuation apart into its four constituents." } ;
HELP: ifcc "( terminator balance -- )"
{ $values { "terminator" "a quotation with stack effect " { $snippet "( continuation -- )" } { "balance" "a quotation" } }
{ $description "Reifies a continuation and passes it to " { $snippet "terminator" } ". When the continuation is restored, execution resumes; " { $snippet "terminator" } " is still on the stack and "{ $snippet "balance" } " is called." }
{ $values { "terminator" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "balance" "a quotation" } }
{ $description "Reifies a continuation from the point immediately after which the caller returns, and passes it to " { $snippet "terminator" } ". When the continuation is restored, execution resumes; " { $snippet "terminator" } " is still on the stack and "{ $snippet "balance" } " is called." }
{ $see-also callcc0 callcc1 } ;
HELP: callcc0 "( quot -- )"
{ $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } } }
{ $description "Applies the quotation to the current continuation. The " { $link continue } " word resumes the continuation." }
{ $description "Applies the quotation to the current continuation, which is reified from the point immediately after which the caller returns. The " { $link continue } " word resumes the continuation." }
{ $see-also ifcc callcc1 continue } ;
HELP: callcc1 "( quot -- obj )"
{ $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "obj" "an object provided when resuming the continuation" } }
{ $description "Applies the quotation to the current continuation. The " { $link continue-with } " word resumes the continuation, passing a value back to the original execution context." }
{ $description "Applies the quotation to the current continuation, which is reified from the point immediately after which the caller returns. The " { $link continue-with } " word resumes the continuation, passing a value back to the original execution context." }
{ $see-also ifcc callcc0 continue-with } ;
HELP: continue "( continuation -- )"

View File

@ -10,32 +10,20 @@ TUPLE: no-method object generic ;
: >c ( continuation -- ) catchstack* push ;
: c> ( -- continuation ) catchstack* pop ;
: catch ( try -- exception/f | try: -- )
#! Call the try quotation. If an exception is thrown in the
#! dynamic extent of the quotation, restore the datastack
#! and push the exception. Otherwise, the data stack is
#! not restored, and f is pushed.
: catch ( try -- error | try: -- )
[ >c call f c> drop f ] callcc1 nip ; inline
: rethrow ( error -- )
#! Use rethrow when passing an error on from a catch block.
catchstack empty?
[ die "Can't happen" throw ] [ c> continue-with ] if ;
: cleanup ( try cleanup -- | try: -- | cleanup: -- )
#! Call the try quotation. If an exception is thrown in the
#! dynamic extent of the quotation, restore the datastack
#! and run the cleanup quotation. Then throw the error to
#! the next outermost catch handler.
[ >c >r call c> drop r> call ]
[ drop (continue-with) >r nip call r> rethrow ] ifcc ; inline
[ drop (continue-with) >r nip call r> rethrow ] ifcc ;
inline
: recover ( try recovery -- | try: -- | recovery: error -- )
#! Call the try quotation. If an exception is thrown in the
#! dynamic extent of the quotation, restore the datastack,
#! push the exception on the datastack, and call the
#! recovery quotation.
[ >c drop call c> drop ]
[ drop (continue-with) rot drop swap call ] ifcc ; inline
: rethrow ( error -- )
catchstack* empty?
[ die "Can't happen" throw ] [ c> continue-with ] if ;
GENERIC: error. ( error -- )

View File

@ -1,7 +1,45 @@
USING: errors help ;
USING: errors help kernel ;
HELP: no-method "( object generic -- )"
{ $values { "object" "an object" } { "generic" "a generic word" } }
{ $description "Throws an error indicating that " { $snippet "object" } " does not respond to the " { $snippet "generic" } " word." } ;
HELP: >c "( continuation -- )"
{ $values { "continuation" "a continuation" } }
{ $description "Pushes an exception handler continuation on the catch stack. The continuation must have been reified by " { $link callcc1 } "." } ;
HELP: throw "( error -- )"
{ $values { "error" "an object" } }
{ $description "Throws an error. Execution does not continue at the point after the " { $link throw } " call. Rather, the innermost catch block is invoked, and execution continues at that point." } ;
{ $description "Saves the current continuation in the " { $link error-continuation } " global variable and throws an error. Execution does not continue at the point after the " { $link throw } " call. Rather, the innermost catch block is invoked, and execution continues at that point." }
{ $see-also rethrow } ;
HELP: catch "( try -- error/f )"
{ $values { "try" "a quotation" } { "error/f" "an object" } }
{ $description "Calls the " { $snippet "try" } " quotation. If an error is thrown in the dynamic extent of the quotation, restores the datastack and pushes the error. If the quotation returns successfully, outputs " { $link f } " without restoring the datastack." }
{ $notes "This word cannot differentiate between the case of " { $link f } " being thrown, and no error being thrown. You should never throw " { $link f } ", and you should also use other error handling combinators where possible." }
{ $see-also cleanup recover } ;
HELP: cleanup "( try cleanup -- )"
{ $values { "try" "a quotation" } { "cleanup" "a quotation" } }
{ $description "Calls the " { $snippet "try" } " quotation. If an exception is thrown in the dynamic extent of the " { $snippet "try" } " quotation, restores the datastack, calls the " { $snippet "cleanup" } " quotation, and rethrows the error. If the " { $snippet "try" } " quotation returns successfully, calls the " { $snippet "cleanup" } " quotation without restoring the datastack." }
{ $see-also catch recover } ;
HELP: recover "( try recovery -- )"
{ $values { "try" "a quotation" } { "recovery" "a quotation with stack effect " { $snippet "( error -- )" } } }
{ $description "Calls the " { $snippet "try" } " quotation. If an exception is thrown in the dynamic extent of the " { $snippet "try" } " quotation, restores the datastack and calls the " { $snippet "recovery" } " quotation to handle the error." }
{ $see-also catch cleanup } ;
HELP: rethrow "( error -- )"
{ $values { "error" "an object" } }
{ $description "Throws an error without saving the current continuation in the " { $link error-continuation } " global variable. This is done so that inspecting the error stacks sheds light on the original cause of the exception, rather than the point where it was rethrown." }
{ $examples
"This word definition attempts to convert a hexadecimal literal string to an integer, and outputs " { $link f } " if there is an error:"
{ $code
": catch-hex> ( str -- n/f )"
" [ hex> ] [ [ drop f ] when ] catch ;"
}
} ;
HELP: error. "( error -- )"
{ $values { "error" "an object" } }
{ $contract "Prints an error in human-readable form." } ;

View File

@ -108,29 +108,10 @@ M: simple-element print-element [ print-element ] each ;
: textual-list ( seq quot -- )
[ "," format* bl ] interleave ; inline
: $see-methods
"Methods defined in the generic word:" format* terpri
[ order word-sort ] keep
[ "methods" word-prop hash . ] curry
sequence-outliner ;
: $see-implementors
"Generic words defined for this class:" format* terpri
[ implementors word-sort ] keep
[ swap "methods" word-prop hash . ] curry
sequence-outliner ;
: ($see)
terpri*
code-style [ with-nesting* ] with-style
terpri* ;
: $see ( content -- )
first {
{ [ dup class? ] [ $see-implementors ] }
{ [ dup generic? ] [ $see-methods ] }
{ [ t ] [ [ see ] ($see) ] }
} cond ;
terpri*
code-style [ [ first see ] with-nesting* ] with-style
terpri* ;
: $example ( content -- )
first2 swap dup <input>

View File

@ -27,7 +27,7 @@ USING: styles ;
: code-style
H{
{ font "Monospaced" }
{ page-color { 0.9 0.9 0.9 0.5 } }
{ page-color { 0.9 0.9 1 0.5 } }
{ border-width 5 }
{ wrap-margin f }
} ;

View File

@ -7,7 +7,7 @@ words ;
: file-vocabs ( -- )
"scratchpad" set-in { "syntax" "scratchpad" } set-use ;
: with-parser ( quot -- ) [ parse-error ] recover ;
: with-parser ( quot -- ) [ <parse-error> rethrow ] recover ;
: parse-lines ( lines -- quot )
[

View File

@ -30,9 +30,9 @@ SYMBOL: column
TUPLE: parse-error file line col text ;
: parse-error ( msg -- )
C: parse-error ( error -- error )
file get line-number get column get line-text get
<parse-error> [ set-delegate ] keep throw ;
<parse-error> [ set-delegate ] keep ;
: skip ( i seq quot -- n | quot: elt -- ? )
over >r find* drop dup -1 =