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

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

\ 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
10
\ as published by the Free Software Foundation, either version 3
11 12 13 14 15 16 17 18
\ 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
19
\ along with this program. If not, see http://www.gnu.org/licenses/.
20

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

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

28 29
\ !! explain handler on-stack structure

Anton Ertl's avatar
Anton Ertl committed
30 31 32
[undefined] first-throw [if]
    User first-throw  \ contains true if the next throw is the first throw
[then]
33 34 35 36
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
37
: nothrow ( -- ) \ gforth
Anton Ertl's avatar
Anton Ertl committed
38
    \G Use this (or the standard sequence @code{['] false catch 2drop})
anton's avatar
anton committed
39 40 41
    \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.
42
    first-throw on ;
43

44 45
' nothrow is .status

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

: iferror ( compilation  orig1 -- orig2 ; run-time  -- ) \ gforth
52 53 54
    \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}.
55
    \ !! check using a special tag
56
    POSTPONE else
57 58 59
; immediate compile-only

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

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

70 71 72 73 74 75
: 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}).
76
    POSTPONE uncatch POSTPONE iferror POSTPONE uncatch
77 78
; immediate compile-only

79 80
0 Value catch-frame

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

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

\ lines to show before and after locate
Anton Ertl's avatar
Anton Ertl committed
98 99 100 101
3 value before-locate ( -- u ) \ gforth
\G number of lines shown before current location (default 3).
12 value after-locate ( -- u ) \ gforth
\G number of lines shown after current location (default 12).
102

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

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

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

117 118
: set-current-view ( -- )
    current-sourceview input-lexeme @ set-located-view ;
119

120 121 122
[IFDEF] ?set-current-view
    :noname error-stack $@len 0= IF  set-current-view  THEN ;
    is ?set-current-view
123 124
[THEN]

125 126
\ : set-current-view ( -- )
\    input-lexeme @ located-len ! current-sourceview located-view ! ;
127

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

142
[defined] pushwrap [if]
Anton Ertl's avatar
Anton Ertl committed
143 144 145 146 147 148 149 150 151 152 153 154
\ 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
155 156
[then]