f



Is this workable? .warning .error

OK, so the setting is boostrapping a system that will eventually be
able to read from a configuration file or engage in a dialog to
determine what Forth implementation (or model) it is loading under,
and will know where to go to get implementation-specific code to
implement the user's preferences.

That will include whether or not error trapping works by ``ABORT'',
``THROW'', or some other mechanism ... and, indeed, if more than one
are available, which one the user wants to use.

However, there is a buffer overflow possibility at a low level early
on, long before that is in place. So, how to get the primitive error
handling in place that can be used in both simple and complex systems.

The current approach is the following, and the question is whether
this is workable or whether there is a hidden pitfall that I don't
see.

I am using CORE EXT words if the situation arises, and I'll sort out
which are going to be dependencies and which will have optional back-
up definitions later.

[DEFINED] and [UNDEFINED] are defined ... well, very first thing if
they are not available from the outset. That's a bootstrap I worked
out a long while back.

\ .warning prints a cautionary warning ... you will want to use
something
\ more elaborate than TYPE for full screen applications
[UNDEFINED] .warning [IF]
    ' TYPE VALUE {.warning}
    : .warning ( ca u -- ) {.warning} EXECUTE
[THEN]

\ .error prints a cautionary warning, then returns as an exception
\ If you use CATCH/THROW, you will wish to use THROW for {error}
[UNDEFINED] .error [IF]
    ' ABORT VALUE {error}
    : .error ( throw# ca u -- ) {.warning} EXECUTE {error} EXECUTE
[THEN]

For a long while, I was hung up on the fact that THROW required the
throw code and ABORT did not, until it occurred to me that ... yeah,
obviously, but then I never said programming was my field ... what
harm is an extra parameter on the stack if you are calling ABORT?

"At worst" ABORT will be throwing away the throw code, and at best the
stack state will be displayed or available on ABORT, so that the throw
code gives useful information in any event.
0
agila61 (3956)
3/10/2008 11:25:51 PM
comp.lang.forth 7147 articles. 0 followers. markrobertwills (871) is leader. Post Follow

8 Replies
3952 Views

Similar Articles

[PageSpeed] 25

On Mar 11, 2:25 am, Bruce McFarling <agil...@netscape.net> wrote:
[...]
> \ .warning prints a cautionary warning ... you will want to use
> something
> \ more elaborate than TYPE for full screen applications
> [UNDEFINED] .warning [IF]
>     ' TYPE VALUE {.warning}
>     : .warning ( ca u -- ) {.warning} EXECUTE
> [THEN]
>
> \ .error prints a cautionary warning, then returns as an exception
> \ If you use CATCH/THROW, you will wish to use THROW for {error}
> [UNDEFINED] .error [IF]
>     ' ABORT VALUE {error}
>     : .error ( throw# ca u -- ) {.warning} EXECUTE {error} EXECUTE
> [THEN]
>
> For a long while, I was hung up on the fact that THROW required the
> throw code and ABORT did not, until it occurred to me that ... yeah,
> obviously, but then I never said programming was my field ... what
> harm is an extra parameter on the stack if you are calling ABORT?
>
> "At worst" ABORT will be throwing away the throw code, and at best the
> stack state will be displayed or available on ABORT, so that the throw
> code gives useful information in any event.

0 THROW is equivalent to 0 DROP
while 0 ABORT is equivalent to ABORT

Maybe, something like
: myerror ?DUP IF . ABORT THEN ;
?

By the way, ABORT" xyz" ( x -- ) checks for x being 0.



0
m_l_g3 (591)
3/12/2008 4:40:57 PM
On Mar 12, 12:40 pm, m_l...@yahoo.com wrote:
> On Mar 11, 2:25 am, Bruce McFarling <agil...@netscape.net> wrote:
> [...]
>
>
>
> > \ .warning prints a cautionary warning ... you will want to use
> > something
> > \ more elaborate than TYPE for full screen applications
> > [UNDEFINED] .warning [IF]
> >     ' TYPE VALUE {.warning}
> >     : .warning ( ca u -- ) {.warning} EXECUTE
> > [THEN]
>
> > \ .error prints a cautionary warning, then returns as an exception
> > \ If you use CATCH/THROW, you will wish to use THROW for {error}
> > [UNDEFINED] .error [IF]
> >     ' ABORT VALUE {error}
> >     : .error ( throw# ca u -- ) {.warning} EXECUTE {error} EXECUTE
> > [THEN]
>
> > For a long while, I was hung up on the fact that THROW required the
> > throw code and ABORT did not, until it occurred to me that ... yeah,
> > obviously, but then I never said programming was my field ... what
> > harm is an extra parameter on the stack if you are calling ABORT?
>
> > "At worst" ABORT will be throwing away the throw code, and at best the
> > stack state will be displayed or available on ABORT, so that the throw
> > code gives useful information in any event.
>
> 0 THROW is equivalent to 0 DROP
> while 0 ABORT is equivalent to ABORT

Thanks, that's an example of why use a resettable wrapper word Nicl
defines.

OK, I'll change it to:

VARIABLE Nicl-errorcode

: Nicl-err ( throw# ca u -- )
    {.Nicl-warn} EXECUTE DUP Nicl-errcode ! ?DUP IF
        {Nicl-err} EXECUTE
    THEN
;

> Maybe, something like
> : myerror ?DUP IF . ABORT THEN ;
> ?
>
> By the way, ABORT" xyz" ( x -- ) checks for x being 0.

I know ... but I want it to be non-parsing, and I don't want to need
THROW" lying around.
0
agila61 (3956)
3/12/2008 5:22:02 PM
On Mar 12, 8:22 pm, Bruce McFarling <agil...@netscape.net> wrote:
> On Mar 12, 12:40 pm, m_l...@yahoo.com wrote:
>
> VARIABLE Nicl-errorcode
>
> : Nicl-err ( throw# ca u -- )
>     {.Nicl-warn} EXECUTE DUP Nicl-errcode ! ?DUP IF
>         {Nicl-err} EXECUTE
>     THEN
> ;
>

0 S" abc" Nicl-err

would clear Nicl-errorcode. If it's built into the system, I do not
know if one will be able to examine Nicl-errorcode before it's
cleared. (OTOH, it may be no problem in your design, I do not know.)
0
m_l_g3 (591)
3/12/2008 5:52:47 PM
In article <630a34e5-a2f5-436c-8ac1-f755e0b5fb53@s8g2000prg.googlegroups.com>,
 <m_l_g3@yahoo.com> wrote:
>On Mar 11, 2:25 am, Bruce McFarling <agil...@netscape.net> wrote:
>[...]
>> \ .warning prints a cautionary warning ... you will want to use
>> something
>> \ more elaborate than TYPE for full screen applications
>> [UNDEFINED] .warning [IF]
>>     ' TYPE VALUE {.warning}
>>     : .warning ( ca u -- ) {.warning} EXECUTE
>> [THEN]
>>
>> \ .error prints a cautionary warning, then returns as an exception
>> \ If you use CATCH/THROW, you will wish to use THROW for {error}
>> [UNDEFINED] .error [IF]
>>     ' ABORT VALUE {error}
>>     : .error ( throw# ca u -- ) {.warning} EXECUTE {error} EXECUTE
>> [THEN]
>>
>> For a long while, I was hung up on the fact that THROW required the
>> throw code and ABORT did not, until it occurred to me that ... yeah,
>> obviously, but then I never said programming was my field ... what
>> harm is an extra parameter on the stack if you are calling ABORT?
>>
>> "At worst" ABORT will be throwing away the throw code, and at best the
>> stack state will be displayed or available on ABORT, so that the throw
>> code gives useful information in any event.
>
>0 THROW is equivalent to 0 DROP
>while 0 ABORT is equivalent to ABORT
>
>Maybe, something like
>: myerror ?DUP IF . ABORT THEN ;
>?

: ?ERROR SWAP IF  ( optionally store information) THROW ELSE DROP THEN ;

>
>By the way, ABORT" xyz" ( x -- ) checks for x being 0.

Groetjes Albert

--
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

0
albert37 (3001)
3/12/2008 10:43:07 PM
On Mar 12, 6:43 pm, Albert van der Horst <alb...@spenarnc.xs4all.nl>
wrote:
>  <m_l...@yahoo.com> wrote:
> >Maybe, something like
> >: myerror ?DUP IF . ABORT THEN ;
> >?

> : ?ERROR SWAP IF  ( optionally store information) THROW ELSE DROP THEN ;

(1) Obviously this is after the warning string has been show ... there
is nothing to swap.

(2) Not requiring THROW to be present but able to using THROW if it is
available and the configuration file asks for it, is the primary
design objective.

If THROW was assumed to always be present and always be desired, .Nicl-
err would be:

: .Nicl-err ( throw# ca u ) {.Nicl-warn} EXECUTE THROW ;
0
agila61 (3956)
3/12/2008 11:45:27 PM
On Mar 12, 1:52 pm, m_l...@yahoo.com wrote:
> On Mar 12, 8:22 pm, Bruce McFarling <agil...@netscape.net> wrote:
> > On Mar 12, 12:40 pm, m_l...@yahoo.com wrote:

> > VARIABLE Nicl-errorcode

> > : Nicl-err ( throw# ca u -- )
> >     {.Nicl-warn} EXECUTE DUP Nicl-errcode ! ?DUP IF
> >         {Nicl-err} EXECUTE
> >     THEN
> > ;

> 0 S" abc" Nicl-err

> would clear Nicl-errorcode. If it's built into the system, I do not
> know if one will be able to examine Nicl-errorcode before it's
> cleared. (OTOH, it may be no problem in your design, I do not know.)

Yes, it could.

(1) It starts with

' ABORT VALUE {Nicl-err}

In that case ... if the interpretors working after you abort, you can
check the error code.

(2) It commonly will be upgraded to THROW

' THROW TO {Nicl-err}

.... in which case the Nicl-err seems to be redundant but harmless.

(3) Someone other than me ever uses the library oversight system
(probably a retro computer hobbyist) and decides to do "something
else".

.... in which case its on their head.

Actually, now that you raise the point, I'm inclined to overwrite the
err-code more often ... in .Nicl-err to write the err-code before the
call to the {.Nicl-warn} xt, and in .Nicl-warn to write 0 into the err-
code ... to let someone catch and correct problems silently if they
are willing to put in place a {.Nicl-warn} that checks the .Nicl-err
value to silence (or perhaps redirect to a log) a message for a
problem that they are handling.
0
agila61 (3956)
3/13/2008 2:34:48 AM
In article <3a3113f4-8db9-451e-9809-768277b15ebc@m44g2000hsc.googlegroups.com>,
Bruce McFarling  <agila61@netscape.net> wrote:
>On Mar 12, 6:43 pm, Albert van der Horst <alb...@spenarnc.xs4all.nl>
>wrote:
>>  <m_l...@yahoo.com> wrote:
>> >Maybe, something like
>> >: myerror ?DUP IF . ABORT THEN ;
>> >?
>
>> : ?ERROR SWAP IF  ( optionally store information) THROW ELSE DROP THEN ;
>
>(1) Obviously this is after the warning string has been show ... there
>is nothing to swap.

I see, I overlooked the .
So it should have been
: ?ERROR ?DUP IF ( store information) THROW THEN ;

The idea is that information is not shown at this point yet.
The error can still be caught and cause no output. If the exception
leads to a message to the end user the information stored can be put
to good use.
That is the difference with a throw.

For example you could have an exception "root of negative number"
that sometimes is caught and causes an application to switch
to using complex numbers.  This is not for the square root itself
to decide, nor do you want spurious messages.

>
>(2) Not requiring THROW to be present but able to using THROW if it is
>available and the configuration file asks for it, is the primary
>design objective.

>
>If THROW was assumed to always be present and always be desired, .Nicl-
>err would be:
>
>: .Nicl-err ( throw# ca u ) {.Nicl-warn} EXECUTE THROW ;

Phrased otherwise :
if {.Nicl-warn} at this point unconditionally and direct outputs
information, one of the advantages of THROW would be lost.

The alternative is not hard. It could store a string somewhere.
Then a f.p. application is started with an overall catch.
At that point the exception is confirmed as a problem and the
string printed.

Note that one string buffer is sufficient.
(Flash! I've got to improve ABORT" in this way.)

Groetjes Albert

--
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- like all pyramid schemes -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

0
albert37 (3001)
3/13/2008 10:30:31 AM
On Mar 13, 6:30 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
wrote:
> >: .Nicl-err ( throw# ca u ) {.Nicl-warn} EXECUTE THROW ;

> Phrased otherwise :
> if {.Nicl-warn} at this point unconditionally and direct outputs
> information, one of the advantages of THROW would be lost.

Thanks.

The same person or script who knows that {Nicl-error} exists and sets
it to THROW or some wrapper around THROW also knows that (.Nicl-warn}
exists and can set it appropriately to the use.

The general bias is to expect more of the more capable implementations
than of the less capable implementations, so if there is to be any
creation of a buffer and copying of strings into the buffer, its going
to be in the word that has been vectored in that adds the THROW, not
into the base definition.

Fortunately, the semantics to line up .Nicl-error most directly as a
non-parsing version of ABORT" means that {.Nicl-warn} can detect
whether its been called to throw or to warn, when .Nicl-error contains
a THROW.

Omitting the conditional compilation wrappers:

VARIABLE Nicl-error#
' TYPE VALUE {.Nicl-warn}
: .Nicl-warn ( ca u -- ) Nicl-error# OFF {.Nicl-warn} EXECUTE ;

' ABORT VALUE {Nicl-error}
: .Nicl-error ( throw# ca u -- )
    ROT ?DUP IF
        >>R Nicl-error ! {.Nicl-warn} EXECUTE {.Nicl-error} EXECUTE
    ELSE 2DROP
    THEN
;

\ ******** UNTESTED ************
\ ... something like???
: Nicl-error" ( throw# "...message" -- )
    [CHAR] " PARSE SLITERAL .Nicl-error ;

0
agila61 (3956)
3/13/2008 12:40:17 PM
Reply: