except.fs 4.89 KB
Newer Older
1 2
\ catch, throw, etc.

Anton Ertl's avatar
Anton Ertl committed
3
\ Copyright (C) 1999,2000,2003,2006,2007,2010,2013,2014,2015,2016,2017 Free Software Foundation, Inc.
4 5 6 7 8

\ This file is part of Gforth.

\ Gforth is free software; you can redistribute it and/or
\ modify it under the terms of the GNU General Public License
9
\ as published by the Free Software Foundation, either version 3
10 11 12 13 14 15 16 17
\ of the License, or (at your option) any later version.

\ This program is distributed in the hope that it will be useful,
\ but WITHOUT ANY WARRANTY; without even the implied warranty of
\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
\ GNU General Public License for more details.

\ You should have received a copy of the GNU General Public License
18
\ along with this program. If not, see http://www.gnu.org/licenses/.
19

20 21
\ !! use a separate exception stack?           anton

22 23 24 25 26
\ has? backtrace [IF]
Defer store-backtrace
' noop IS store-backtrace
\ [THEN]

27 28
\ !! explain handler on-stack structure

Anton Ertl's avatar
Anton Ertl committed
29 30 31
[undefined] first-throw [if]
    User first-throw  \ contains true if the next throw is the first throw
[then]
32 33 34 35
User stored-backtrace ( addr -- )
\ contains the address of a cell-counted string that contains a copy
\ of the return stack at the throw

anton's avatar
anton committed
36
: nothrow ( -- ) \ gforth
Anton Ertl's avatar
Anton Ertl committed
37
    \G Use this (or the standard sequence @code{['] false catch 2drop})
anton's avatar
anton committed
38 39 40
    \G after a @code{catch} or @code{endtry} that does not rethrow;
    \G this ensures that the next @code{throw} will record a
    \G backtrace.
41
    first-throw on ;
42

43 44
' nothrow is .status

Anton Ertl's avatar
Anton Ertl committed
45 46
: try ( compilation  -- orig ; run-time  -- R:sys1 ) \ gforth
    \G Start an exception-catching region.
Anton Ertl's avatar
Anton Ertl committed
47
    POSTPONE (try) >mark
Anton Ertl's avatar
Anton Ertl committed
48
; immediate compile-only
49 50

: iferror ( compilation  orig1 -- orig2 ; run-time  -- ) \ gforth
51 52 53
    \G Starts the exception handling code (executed if there is an
    \G exception between @code{try} and @code{endtry}).  This part has
    \G to be finished with @code{then}.
54
    \ !! check using a special tag
55
    POSTPONE else
56 57 58
; immediate compile-only

: restore ( compilation  orig1 -- ; run-time  -- ) \ gforth
59 60
    \G Starts restoring code, that is executed if there is an
    \G exception, and if there is no exception.
61
    POSTPONE iferror POSTPONE then
62
; immediate compile-only
63

64 65
: endtry ( compilation  -- ; run-time  R:sys1 -- ) \ gforth
    \G End an exception-catching region.
66
    POSTPONE uncatch
67
; immediate compile-only
68

69 70 71 72 73 74
: endtry-iferror ( compilation  orig1 -- orig2 ; run-time  R:sys1 -- ) \ gforth
    \G End an exception-catching region while starting
    \G exception-handling code outside that region (executed if there
    \G is an exception between @code{try} and @code{endtry-iferror}).
    \G This part has to be finished with @code{then} (or
    \G @code{else}...@code{then}).
75
    POSTPONE uncatch POSTPONE iferror POSTPONE uncatch
76 77
; immediate compile-only

78 79
0 Value catch-frame

80 81
:noname ( x1 .. xn xt -- y1 .. ym 0 / z1 .. zn error ) \ exception
    try
Anton Ertl's avatar
Anton Ertl committed
82
	execute [ here to catch-frame ] 0 uncatch exit
83 84 85
    iferror
	nip
    then endtry ;
86 87
is catch

88
Defer kill-task ' noop IS kill-task
89
Variable located-view
90
Variable located-len
91
variable bn-view      \ first contains located-view, but is updated by B and N
92 93
variable located-top  \ first line to display with l
variable located-bottom \ last line to display with l
94
2variable located-slurped \ the contents of the file in located-view, or 0 0
95 96 97 98 99

\ lines to show before and after locate
3 value before-locate
12 value after-locate

100 101
: view>filename# ( view -- u )
    \G filename-number of view (obtained by @code{name>view}) see @code{filename#>str}
102 103
    23 rshift ;

104 105
: view>line ( view -- u )
    \G line number in file of view (obtained by @code{name>view})
106 107
    8 rshift $7fff and ;

108 109 110
: set-located-view ( view len -- )
    located-len ! dup located-view ! dup bn-view !
    view>line
111 112
    dup before-locate - 0 max located-top !
    after-locate + located-bottom ! ;
113

114 115
: set-current-view ( -- )
    current-sourceview input-lexeme @ set-located-view ;
116

117 118 119
[IFDEF] ?set-current-view
    :noname error-stack $@len 0= IF  set-current-view  THEN ;
    is ?set-current-view
120 121
[THEN]

122 123
\ : set-current-view ( -- )
\    input-lexeme @ located-len ! current-sourceview located-view ! ;
124

125
:noname ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error ) \ exception
Anton Ertl's avatar
Anton Ertl committed
126
    ?DUP-IF
127 128
	[ here forthstart 9 cells + !
	  here throw-entry ! ]
129 130
	first-throw @ IF
	    store-backtrace
131
	THEN
Anton Ertl's avatar
Anton Ertl committed
132 133 134 135
	handler @ IF
	    fast-throw THEN
	>stderr cr ." uncaught exception: " .error cr
	kill-task  2 (bye)
136 137
    THEN ;
is throw
138

139
[defined] pushwrap [if]
Anton Ertl's avatar
Anton Ertl committed
140 141 142 143 144 145 146 147 148 149 150 151
\ usage: wrap ... end-wrap
\ or:    wrap ... wrap-onexit ... then
\ in combination with: exit-wrap

: wrap ( compilation: -- orig; run-time: -- r:sys ) \ gforth-experimental
    POSTPONE pushwrap >mark ; immediate compile-only

: end-wrap ( compilation: orig --; run-time: r:sys -- ) \ gforth-experimental
    POSTPONE dropwrap POSTPONE then ; immediate compile-only

: wrap-onexit ( compilation: orig --; run-time: r:sys -- ) \ gforth-experimental
    POSTPONE dropwrap POSTPONE else ; immediate compile-only
152 153
[then]