Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 28 |
Nodes: | 6 (0 / 6) |
Uptime: | 43:08:55 |
Calls: | 422 |
Calls today: | 1 |
Files: | 1,024 |
Messages: | 90,180 |
Checking the doc it says:
9.3.5 Possible actions on an ambiguous condition
A system choosing to execute THROW when detecting one of the ambiguous
conditions listed in table 9.3.6 shall use the throw code listed there.
So while CATCH and THROW are compulsory (EXCEPTION wordset), there is no >requirement to implement any of the codes listed in the table. Only if
the EXCEPTION EXT wordset is implemented must the codes for ABORT and
ABORT" be used. Thus a system may implement the following if it wishes:
: QUIT -56 THROW ;
On 4/05/2025 2:02 am, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:
Checking the doc it says:
9.3.5 Possible actions on an ambiguous condition
A system choosing to execute THROW when detecting one of the ambiguous
conditions listed in table 9.3.6 shall use the throw code listed there.
Calling ABORT or QUIT is not an ambiguous condition, so that section
plays no role there.
Yet ABORT ABORT" and QUIT are present in the table and assigned codes.
It is clear to me all three are candidates for CATCHing and that this
was the intent.
This is confirmed by the EXCEPTION EXT wordset in which
ABORT and ABORT" are required to be CATCHable irrespective of their
category.
: QUIT -56 THROW ;
That would not be a standard system, because in a standard system QUIT
must do what 6.1.2050 QUIT says, and "-56 THROW" is not a correct
implementation of that.
No for the fact QUIT is CATCHable by virtue of its inclusion in the table
of codes in Section 9.
If OTOH you believe the inclusion of ABORT ABORT"
and QUIT was made in error then you have the option of testing that by
making a proposal to have them removed.
1 .( a ) cr -56 throw .( b )^
dxf <dxforth@gmail.com> writes:[..]
On 4/05/2025 2:02 am, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:
In iForth 5.1-mini QUIT preserves the stack while an uncaught -56
THROW resets it to empty (as it should); the uncaught -56 THROW does
not produce a message. For the cases with CATCH, the FOO variant does
not put the -56 on the stack and does not text-interpret the 5
afterwards, but it does preserve the 2 that was pushed earlier.
Strange. The BAR variant behaves as expected. If I try
2 : foo 3 1 throw ; ' foo catch 5
..s
iForth 5.1-mini behaves as follows:
FORTH> 2 : foo 3 1 throw ; ' foo catch 5 ok
[3]FORTH> .s
Data: 2 1 5 ---
System: ---
Float: --- ok
This is expected, so it seems to do something special for -56 THROW.
On 6/05/2025 3:29 am, Ruvim wrote:
On 2025-05-05 08:11, dxf wrote:
: bar 4 quit ; ' bar catch 6
  stack is: -56 6
This violates `quit` 6.1.2050, because:
 - `quit` is not allowed to remove anything from the data stack (in this case, remove 4 from the stack);
 - `quit` is not allowed to place anything on the data stack (in this case, place `-56`);
 - `quit` is not allowed to interpret the remaining part of the input buffer (in this case, interpret "6" and place 6 on the stack).
A caught ABORT does the same:
SwiftForth i386-Win32 3.11.9-RC1 01-Sep-2022
: bar 4 abort ; ' bar catch 6 .s
-1 6 <-Top ok
Yes, -1 and -2 are special cases in 9.6.1.2275 (when there is no user >exception frame). But for those cases it *only* specifies what message
shall be displayed, and *nothing more*.
Backtrace:abort<<<
Except THROW special-cased codes -1 and -2 effectively reserving their behaviour.
One can speculate why ANS didn't do so for -56 but to my mind QUIT when implemented
should function as expected i.e. -56 THROW uncaught should perform QUIT.
On Sun, 4 May 2025 13:33:31 +0000, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:[..]
On 4/05/2025 2:02 am, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:
In iForth 5.1-mini QUIT preserves the stack while an uncaught -56
THROW resets it to empty (as it should); the uncaught -56 THROW does
not produce a message. For the cases with CATCH, the FOO variant does
not put the -56 on the stack and does not text-interpret the 5
afterwards, but it does preserve the 2 that was pushed earlier.
Strange. The BAR variant behaves as expected. If I try
2 : foo 3 1 throw ; ' foo catch 5
..s
iForth 5.1-mini behaves as follows:
FORTH> 2 : foo 3 1 throw ; ' foo catch 5 ok
[3]FORTH> .s
Data: 2 1 5 ---
System: ---
Float: --- ok
This is expected, so it seems to do something special for -56 THROW.
Searching for: -56 THROW
D:\dfwforth\examples\misc\risky-program.frt(3): \ A heated debate is
possible over the exact action -56 THROW should have. Should it QUIT ? >D:\dfwforth\examples\misc\risky-program.frt(57): 2: 1999 12 [ -56 throw
-56 THROW executed
Found 3 occurrence(s) in 1 file(s), 39514 ms
There must have been a convincing reason.
-marcel
On 2025-05-06 14:12, dxf wrote:
Irrespective of the merits such a change to the spec for THROW would
be not be practical given most systems appear to use ANS' QUIT-based
exception handler. But for new implementers or the curious here is
how I organised mine and which is readily changeable.
\ return to OS with exit code
: RETURN ( code -- ) ... ;
\ perform ANS QUIT
: (quit) ( -- ) r0 @ rp! reset normal /interpret
begin cr (refill) drop interpret state? 0= if (vstat)
@execute then again ;
\ exit to OS or back to forth
: ?return ( code -- ) turnkey? if return then drop (quit) ;
Returning to OS can be useful not only for a turnkey program, but also
for batch mode, in which the Forth system must return to the OS on any >uncaught error.
A possible use-case in Linux shell:
./generate-forth-program params | forth --batch-mode
since you probably prefer not to interpret the following lines if there
an error occurs when defining a word in some line.
\ clear data stacks
: (abort) ( i*x -- ) s0 @ sp! fs0 @ fsp ! 1 ?return ;
\ part of THROW
: error ( n -- )
-1 of (abort) then
-2 of boot cell+ @ 0= if .error then
space errmsg 2@ type (abort) then
." THROW #" @base decimal swap . !base (abort) ;
: QUIT ( -- ) 0 ?return ; \ QUIT not trapped
\ QUIT is not trapped in DX-Forth but may be made so by
\ adding -56 of 1 ?return then to 'error' and defining
\ : QUIT -56 throw ;
I use `quit` only for testing and debugging. And I expect to get into
the Forth text interpreter (Forth shell) exactly in the current program
state (as far as possible).
If `quit` simply calls `-56 throw`, the program state will probably
change (due to actions after `catch` in the program, including restoring
the data stack depth in `throw`) when you get into the Forth shell.
Also, there is a chance that you will not get into the Forth shell at
all if the program does not re-throw the error in some places.
So I would not recommend the suggested deviation in the `quit` behavior
even for new implementers, since this brakes the well-known expectation
from `quit`. A better way is to introduce another word with desired
behavior deviation.
: ?ABORT ( flag c-addr u -- )
rot if errmsg 2! -2 throw then 2drop ;
: (abort") ( flag -- ) r> count 2dup + >r ?abort ;
: ABORT" state @ if postpone (abort") ," end
postpone s" ?abort ; immediate
: ABORT -1 throw ;
--
Ruvim
On 9/05/2025 4:20 pm, Ruvim wrote:
On 2025-05-09 04:54, dxf wrote:into the Forth text interpreter (Forth shell) exactly in the current
On 8/05/2025 10:50 pm, Ruvim wrote:
On 2025-05-08 06:52, dxf wrote:
On 8/05/2025 3:52 am, Ruvim wrote:
...
I use `quit` only for testing and debugging. And I expect to get
program state (as far as possible).
probably change (due to actions after `catch` in the program, including >restoring the data stack depth in `throw`) when you get into the Forth
If `quit` simply calls `-56 throw`, the program state will
shell. Also, there is a chance that you will not get into the Forth
shell at all if the program does not re-throw the error in some places.
behavior even for new implementers, since this brakes the well-known >expectation from `quit`. A better way is to introduce another word with >desired behavior deviation.
So I would not recommend the suggested deviation in the `quit`
ANS never gave a rationale for ABORT ABORT" QUIT - only
options that we're now exploring.
For the reasons you've stated I'm reluctant to define:
: QUIT -56 THROW ;
But are there reasons an application might were THROW able
to handle it?
I don't see such a reason. The application can simply do
`abort` or `-56 throw` (and no special cases are needed).
Yes but those would be workarounds. It's making the argument
QUIT can't or shouldn't be caught whereas I'm talking about
entitlement.
`BYE` and `EXIT` cannot be caught too.
QUIT is in the table; those are not. Besides BYE is an optional tool
and I've no idea what use is a catchable EXIT .
`QUIT` can be considered by the Forth program as a kind of `BYE` that >immediately returns control to the Forth shell (when `BYE` returnscontrol to the host OS).
must be provided if EXCEPTION is provided — yes, I agree.
Speaking of entitlement, ANS made EXCEPTION EXT a one-way street.
There's no rolling back from the changes.
If you mean that EXCEPTION EXT is not actually optional in itself, but
Not what I said but if you're going to enforce a catchable ABORT and
ABORT" then why omit QUIT - and if you do - why is it in table?
We can keep going round in circles but ISTM what's needed is a rationale. >Because I'm not seeing one in ANS. Folks have implemented what it said
but can't explain it. Hence the Bible allusion.
ANS made provision for a catchable QUIT.