Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conklin E.K.Forth programmer's handbook.2000.pdf
Скачиваний:
321
Добавлен:
23.08.2013
Размер:
2.04 Mб
Скачать

Forth Programmer’s Handbook

2.6 EXCEPTION HANDLING

Forth provides several methods for error handling. ABORT and ABORT" may be used to detect errors. However, they are relatively inflexible, in that they unconditionally terminate program execution and return to the idle state.

The words CATCH and THROW, discussed in this section, provide a method for propagating error handling to any desired level in an application program. THROW may be thought of as a multi-level EXIT from a definition, with CATCH marking the location to which the THROW returns.

Suppose that, at some point, word A calls word B, whose execution may cause an error to occur. Instead of just executing word B’s name, word A calls word B using the word CATCH. Someplace in word B’s definition (or in words that B’s definition may call) there is at least one instance of the word THROW, which is executed if an error occurs, leaving a numerical throw code identifier on the stack. After word B has executed and program execution returns to word A just beyond the CATCH, the throw code is available on the stack to assist word A in resolving the error. If the THROW was not executed, the top stack item after the CATCH is zero.

When CATCH executes, it requires the execution token of the lower-level routine it is to call to be on top of the stack:

… ['] <routine name> CATCH …

is the typical syntax. At the time CATCH executes, there may be other items on the data stack.

After the lower-level routine has executed and control has returned to the CATCHing routine, the data stack will have one of two behaviors. If the lowerlevel routine (and any words it called) did not cause a THROW to execute, the top stack item after the CATCH will be zero and the remainder of the data stack may be different than it was before, changed by the behavior of the lower-level routine. If a THROW did occur, the top stack item after the CATCH will contain the throw code, and the remainder of the data stack will be restored to the same depth (although not necessarily to the same data) it had just before the CATCH. The return stack will also be restored to the depth it had before the CATCH.

When THROW executes, it requires a throw code on top of the stack. If this code

74 Forth Fundamentals

Forth Programmer’s Handbook

is zero, THROW does nothing except to remove the zero from the stack; the remainder of the stack is unchanged. If the throw code is non-zero, THROW returns the code on top of the stack, restores the data stack depth (but not necessarily the data) to its value when CATCH was executed, restores the return stack depth, and passes control to the CATCHing routine. If a non-zero THROW occurs without a corresponding application program CATCH to return to, it is treated as an ABORT.

The set of information (e.g., stack depths) that may be needed for restoration is called an exception frame. Exception frames are placed on an exception stack in order to allow nesting of CATCHes and THROWs. Each use of CATCH pushes an exception frame onto the exception stack. If execution proceeds normally, CATCH pops the frame; if an error occurs, THROW pops the frame and uses its information for restoration.

An example of CATCH and THROW taken from Standard Forth is:

: COULD-FAIL ( --

c)

KEY DUP [CHAR] Q = IF

1 THROW

THEN ;

 

 

 

: DO-IT ( n

n -- c)

2DROP COULD-FAIL

;

: TRY-IT (

-- )

1 2

['] DO-IT CATCH

IF

2DROP ."

There

was an exception" CR

 

ELSE ."

The character was " EMIT CR

THEN ;

The upper-level word TRY-IT calls the high-risk operation DO-IT (which in turn calls COULD-FAIL) using CATCH. Following the CATCH, the data stack contains either the character returned by KEY and a zero on top, or two other- wise-undefined items (to restore it to the depth before the CATCH) and a one on top. Since any non-zero value is interpreted as true, the returned throw code is suitable for direct input to the IF clause in TRY-IT.

Standard Forth reserves negative throw codes for system implementors, and positive throw codes for applications. Throw codes -1 through -255 are reserved for assignment by the Standard itself, and are used to specify common types of errors (such as divide by zero, invalid address, stack underflow/overflow, etc.) in order that different Forth implementations will have compatible behaviors in these common cases.

Forth Fundamentals 75

Core, Exception Ext

Forth Programmer’s Handbook

Frequently, when a terminal task aborts, it is desirable to display a message, clear stacks, and re-enter a default state awaiting user commands. This is the primary use of ABORT".

Glossary

ABORT ( i*x — ); ( R: j*x — ) Core, Exception Ext

Unconditionally terminate execution, empty both stacks, and return to the task’s idle behavior (usually QUIT—see Section 4.1.2). No message is issued. May be executed by any task in a multitasked implementation.

ABORT" <text>" ( i*x flag — ); ( R: j*x — )

If flag is true (non-zero), type the specified text at the user’s terminal, clear both stacks, and return to the task’s idle behavior. Must be used inside a definition.

“abort-quote”

The definition of ABORT" concludes with the word ABORT (or otherwise includes its functionality).

CATCH

( i*x xt — j*x 0 | i*x n )

Exception

 

Save information about the depth of the data and return stacks in an exception

 

frame and push the frame on the exception stack. Execute the execution token

 

xt (as with EXECUTE). If the execution of xt completes normally (i.e., a non-

 

zero THROW is not executed), pop the exception frame and return zero on top of

 

the data stack, above whatever stack items were returned by xt EXECUTE, and

 

delete the stack-depth information. Otherwise, see the definition of THROW for

 

completion of the exception-processing behavior.

 

THROW

( k*x n — k*x | i*x n )

Exception

If n is zero, simply remove n from the data stack. If n is non-zero, pop the topmost frame from the exception stack, restore the input source specification that was in use before the corresponding CATCH, and adjust the depths of all stacks so they are the same as the depths saved in the exception frame (the value of i in THROW’s stack comments is the same as the value of i in CATCH’s comments). Place n on top of the data stack and transfer control to a point just beyond the corresponding CATCH that pushed the exception frame.

References EXECUTE, Section 2.5.6

76 Forth Fundamentals

Соседние файлы в предмете Электротехника