Digest #69 2019-08-01
Contributions
The test example shows BL being 20. From looking at the test suite code, it seems to mostly be in decimal. Maybe I need to get better acquainted with the test harness, but shouldn't this be 32? Decimal?
Replies
' ' CATCH foo
produces a non-zero value because '
produces an exception (although the standard does not guarantee that). Therefore the code between [if]
and [then]
is text-interpreted.
If you think that "just after CATCH
" means that THROW should restore the input stream to where it was when CATCH was entered, no, I don't think that the standard means this. If you think that needs clarifying, make a proposal.
What it means is that in the following example:
: bar parse-name type 1 throw ." end of bar" ;
: bar1 bar ." end of bar1" ;
: bar2 ['] bar catch ." end of bar2" ;
bar2 bla \ prints "blaend of bar2"
the THROW
jumps to the point between CATCH
and ."
. In your example, the point just after CATCH is inside the text interpreter.
Another aspect is that THROW
specifies "restore the input source specification". Gforth (and apparently other popular systems) have implemented this as unnesting all the INCLUDED
s, EVALUATE
s, and LOAD
s that the THROW
terminates, but not as restoring anything if there is no such word unnested. Given that there have been no complaints about this behaviour in the last 25 years, and that it could be very expensive to restore the input stream of the user input device (an arbitrary number of REFILL
s could happen between entering the CATCH
and the THROW
), we may want to clarify/fix the specification of THROW
.
I would agree that the ambiguous condition be removed, and istead a note be added to the specification of POSTPONE and [COMPILE] to the effect that, unless the compilation semantics of XYY are specified as in e.g. ( 'Perform the execution semantics given below' then it is an error for the code compiled by POSTPONE xyz to be executed other than during compilation.
So you have suggested to make the following code non-standard:
: foo 123 . ;
: bar postpone foo ;
: baz [ bar ] ;
I don't think that it is a good idea. This code does not contain any error.
In general case, an ambiguous condition exist if you try to append something to the current definition when it is absent.
So you have suggested to make the following code non-standard:
: foo 123 . ;
: bar postpone foo ;
: baz [ bar ] ;
I don't think that it is a good idea. This code does not contain any error.
But does it serve any useful purpose? Why not just write : baz foo ;
?
In general case, an ambiguous condition exist if you try to append something to the current definition when it is absent.
To which this is an exception because you are interpreting in the middle of a current definition. But why would you switch from compiling to interpreting in order to compile? Normally you do that for one reason only - to calculate a literal whose value will be known at compile time. Or is there some other reason that I am missing?
It's always handy to have readable references for things like TAB, CR, LF, ESC, etc. This word could be optional, but it's certainly handy.