[...]
>And that's probably what triggered my NDCS esploration. The base
>problem comes from the standard's definitions of words. There are
>three cases:
>1) normal words
>2) immediate words
>3) NDCS words
>
>The standard only says how to handle cases 1) and 2).
Really? When I look at the standard, I find, e.g.
|3.4 The Forth text interpreter
|...
|
|b. Search the dictionary name space (see 3.4.2). If a definition name
|matching the string is found:
|
| 1. if interpreting, perform the interpretation semantics of the
| definition (see 3.4.3.2), and continue at a).
|
| 2. if compiling, perform the compilation semantics of the definition
| (see 3.4.3.3), and continue at a).
So here the standard does not talk about normal words, immediate
words, or NDCS words, but instead about the interpretation semantics
and compilation semantics of all words.
>The standard deliberately does not mandate implementation techniques
>and VFX uses a technique for NDCS words that is useful, but breaks
>careless tests.
The standard indeed does not mandate implementation techniques, but
instead specifies behaviour. Standard systems have to comply with
this specification; they can choose various implementation techniques
to achieve this, but if an implementation does not comply with the
specification, it is non-standard, and you can wave the "does not
mandate implementation techniques" card as much as you want, it won't
change that.
If a test shows that your system is non-standard, it's not the fault
of the test, but the fault of your system.
>The EuroForth papers are there to read, and nobody has
>said that my analysis is wrong.
I told you in <
597E1567.25...@stephen.mpeforth.com> what was
wrong in the draft version of your 2017 paper. Looking at 4 places
where I pointed out that what you wrote is wrong, and comparing that
to the final paper, I see that in three places you kept the wrong
statements. You ammended the fourth place, but the result is still
wrong.
So: I wrote to you that your analysis is wrong before you published
the paper, and I maintain that it is still wrong.
As for complexity, we used to use an approach that uses IFs for
separating various cases (aliases, interpret/compile:, intelligent
"compile,", words that you can TO to); these exceptions were easy to
add step-by-step, but they resulted in a complex mess (in a way,
similar to a text interpreter with five (or was it seven)
special-purpose hooks, one for each extension that had become
necessary over the years), and they are inflexible. So Bernd Paysan
redesigned the Gforth header (with some input from me), and this
resulted in a much more flexible header design that we described in
detail in [paysan19].
@InProceedings{paysan19,
author = {Bernd Paysan and M. Anton Ertl},
title = {The new {Gforth} Header},
crossref = {euroforth19},
pages = {5--20},
url = {
http://www.euroforth.org/ef19/papers/paysan.pdf},
url-slides = {
http://www.euroforth.org/ef19/papers/paysan-slides.pdf},
video = {
https://wiki.forth-ev.de/doku.php/events:ef2019:header},
OPTnote = {refereed},
abstract = {The new Gforth header is designed to directly
implement the requirements of Forth-94 and
Forth-2012. Every header is an object with a fixed
set of fields (code, parameter, count, name, link)
and methods (\texttt{execute}, \texttt{compile,},
\texttt{(to)}, \texttt{defer@}, \texttt{does},
\texttt{name>interpret}, \texttt{name>compile},
\texttt{name>string}, \texttt{name>link}). The
implementation of each method can be changed
per-word (prototype-based object-oriented
programming). We demonstrate how to use these
features to implement optimization of constants,
\texttt{fvalue}, \texttt{defer}, \texttt{immediate},
\texttt{to} and other dual-semantics words, and
\texttt{synonym}.}
}
>My conclusion from all this is that the standard has a bug in it.
>Unfortunately, fixing the bug will be a real pain.
I think the standard is mostly fine in this area. There are proposals
for specifying FIND in a way that would make user-defined text
interpreters standard
<
https://forth-standard.org/proposals/clarify-find?hideDiff#reply-165>
<
https://forth-standard.org/proposals/clarify-find-more-classic-approach?hideDiff#reply-682>
and for making the definition of the term "execution token" match it's
usage in FIND, ', ['], NAME>INTERPRET, NAME>COMPILE
<
https://forth-standard.org/proposals/reword-the-term-execution-token-?hideDiff#reply-486>.
Fixing these issues is therefore as painless as accepting one of the
Clarify FIND proposals, and accepting the rewording of execution
token.
There is also a case for disallowing ticking and POSTPONEing S" and
S\" (to allow STATE-smart implementations of these words), but I leave
it to those who are interested in such implementations to make such
proposals.
>> I had the
>>impression that you would fix it in VFX 5, but given your reaction,
>>this is now questionable; I work at a university, so I cannot test VFX
>>5 myself.
>
>It is fixed.
Good! I have now tested the test case I sent you in 2015 and VFX 5.11 passed.
Let's see about Ruvim's test from <s6qmbs$ki6$
1...@dont-email.me>:
: test-if
c" if" find dup 0= if ." unfound" 2drop exit then
1 = if ." executed" execute else ." compiled" compile, then
; immediate
] test-if [ .s
This fails on VFX 5.11. My guess is that you did not fix your broken
COMPILE, but instead rewrote your text interpreter such that my 2015
test does not invoke COMPILE,. So let's combine my scaffolded
COMPILE, from the 2015 test with Ruvim's test:
: defers
\ "defers X" produces a call to the current content of the deferred word X
' defer@ compile, ; immediate
:noname ( xt -- )
>in @ >r
depth 1- >r
defers compile,
depth r> <> abort" compile, stack effect wrong"
>in @ r> <> abort" compile, input stream effect wrong" ;
is compile,
: test-if
c" if" find dup 0= if ." unfound" 2drop exit then
1 = if ." executed" execute else ." compiled" compile, then
; immediate
] test-if [ .s
The last line outputs:
|compiledcompile, stack effect wrong
(why would it say "compiled" and not execute the .s after the [ ?)
Let's try a simple user-defined text interpreter based on the one
shown in
<
https://forth-standard.org/standard/rationale#rat:core:COMPILE,>
: int-line ( ... "rest of line" -- ... )
cr source type cr
begin
bl word dup c@ while
FIND ?DUP IF ( xt +-1 )
STATE @ IF ( xt +-1 )
0> IF EXECUTE ELSE COMPILE, THEN ( ??? )
ELSE ( xt +-1 )
DROP EXECUTE ( ??? )
THEN
ELSE ( c-addr )
-13 throw \ numbers are left as an exercise
THEN
repeat
drop ;
[upper case stuff from
<
https://forth-standard.org/standard/rationale#rat:core:COMPILE,>]
Note that Forth-94/2012 does not guarantee that this text-interprets,
e.g., IF (not even in compile state), because FINDing IF is ambiguous.
Anyway, let's see how various systems fare, on the following input:
int-line state @ .
int-line : foo if dup . then ;
int-line : bar s" bla" ;
int-line state @ true foo drop bar type
The outputs are, for various Forth systems:
SwiftForth 3.11.0, Gforth 0.7.9_20201015, iforth, and vfxlin-4.71 print:
int-line state @ .
0
int-line : foo if dup . then ;
int-line : bar s" bla" ;
int-line state @ true foo bar type
0 bla
vfx64 5.11 prints:
int-line state @ .
0
int-line : foo if dup . then ;
Err# -22 ERR: Control structure mismatch.
Source: "forth/text-interpreter.4th" on line 36
-> int-line : foo if dup . then ;
^sh: geany: command not found
ERROR on command line
The VFX 5.11 result was unexpected. VFX 4.71 works here because this
text interpreter does not keep any text-interpreter data on the data
stack during the call to COMPILE, (except of course the xt itself).
But let's change the user-defined text interpreter in a way that
should not change it's behaviour:
: int-line ( ... "rest of line" -- ... )
cr source type cr
begin
bl word dup c@ while
FIND ?DUP IF ( xt +-1 )
STATE @ IF ( xt +-1 )
0> IF EXECUTE ELSE >in @ swap COMPILE, >in ! THEN ( ??? )
ELSE ( xt +-1 )
DROP EXECUTE ( ??? )
THEN
ELSE ( c-addr )
-13 throw \ numbers are left as an exercise
THEN
repeat
drop ;
This saves >IN on the stack across the COMPILE,. Given that COMPILE,
is specified to only access the xt and not change >IN (by omitting any
mention of such an effect), this is equivalent to the INT-LINE above.
Let's see how the systems fare:
SwiftForth 3.11.0, Gforth 0.7.9_20201015 and iforth give the same
output as above (as they should).
vfxlin-4.71 now gives:
int-line state @ .
0
int-line : foo if dup . then ;
CS=0023 DS=002B ES=002B SS=002B FS=0000 GS=0063
EAX=6E65:683B EBX=110C:CBE8 ECX=F7F3:F626 EDX=0000:0020
ESI=08FF:9000 EDI=0804:A000 EBP=08FF:7FB0 ESP=08FE:7F1C
EIP=0804:B836 EFLAGS=0001:0206
--- RS top ---
$0805:7002 PARSE-WORD
$0000:0020
$0805:70E5 WORD
$080C:0938 INT-LINE
$0805:9C8B DEFER
$0805:97F3 (INTERPRET)
$0805:9C8B DEFER
$0805:EE90 ((INCLUDE-FILE))
Signal number SIGSEGV
at address 0804:B836, probably in SKIP
and VFX 5.11 produces similar output.
As mentioned, you can say that FINDing IF is ambiguous, so VFX is fine
as far as this test is concerned. Or alternatively, you can design
your system such that code like this works.
>You can test it, I hereby give
>you and other educators an exemption for university use.
Thank you.