Liste des Groupes | Revenir à cl forth |
On 2025-05-17 17:28, dxf wrote:On 17/05/2025 9:30 pm, Ruvim wrote:On 2025-05-17 06:56, dxf wrote:>On 16/05/2025 9:12 pm, Ruvim wrote:>>>...>
What solution do you mean?
Default behaviour of QUIT is Core QUIT. THROW handles -56 by jumping to
Core QUIT.
If you make `throw` do this regardless of whether a user's exception frame exists in the exception stack, you make the `-56` error code uncatchable. So, the following test case will fail:
>
t{ [: -56 throw ;] catch -> -56 }t
>
And what is the benefit?
Why should it fail?
You wrote: "THROW handles -56 by jumping to Core QUIT". Then the test should fail. But as you now show, you only meant the case where there is no user exception frame in the exception stack.
>
>>>
[: -56 throw ;] catch ok -56 <
>
[: -1 throw ;] catch ok -1 <
Okay, these cases are compliant.
>
>>>
1 2 3 -56 throw
ok 1 2 3 <
>
1 2 3 -1 throw
ok
This special handling of `-56` is inconsistent, not justified by practice, and complicates implementations.
Well, at least you don't object to the arguments about inconsistency and impracticality.
Neither special nor complicated:
>
-1 of s0 @ sp! fs0 @ fsp ! (core-quit) then
>
-56 of (core-quit) then
Why do you empty stacks especially for `-1`? Don't you do the same for `-2`, `-3`, `-4`, etc?
In many systems, the actions specified for `throw` when there is no user exception frame are implemented in `quit`:
: translate-input ( any -- any )
begin refill while interpret ?ok repeat
;
: quit ( i*x -- never ) \ point (1)
rdepth rndrop \ empty the return stack and exception stack
0 set-source-id
begin
0 state ! \ enter interpretation state
['] translate-input catch dup
while ( i*x n\0 ) \ point (2)
['] print-error catch if 6 bye-status then
depth ndrop \ empty the data stack (and control-flow stack)
fdepth fndrop \ empty the floating-point stack
repeat bye \ end of stdin
;
(this is allowed as the programs are not affected)
And the system enters `quit` right after startup. So `throw` does not call `(core-quit)`, but non-locally *returns* to `(core-quit)` according to the system's exception frame.
This approach avoids the need to determine in `throw` whether a user exception frame exists, and allows to use `catch` in the words like `evaluate` and `included` to restore the input source. See an example implementation for `throw` in E.9.6.1.2275
<https://forth-standard.org/standard/implement#imp:exception:THROW>
The caveat/nuance is that the special handling of `-56` as in your example is not compatible with this approach at all.
>
This handling cannot be implemented in `throw`, since some exception frame always exists when `throw` is executed. And this handling cannot be implemented in `quit` because in the point (2) the data stack depth is already restored and is the same as in the point (1) plus one.
That's why I said this special handling of `-56` complicates implementations.
Les messages affichés proviennent d'usenet.