Page 2 of 3

Re: Redesigning Forth

Posted: Tue Jun 02, 2020 8:50 pm
by GARTHWILSON
JimBoyd wrote:
Also, some Forths have a word, EMPTY , that will remove all words added since Forth was last loaded. Loaded as in, the Forth language program is called in from removable media and run on the computer.

That sounds the same as the Forth word COLD .

Re: Redesigning Forth

Posted: Tue Jun 02, 2020 9:24 pm
by JimBoyd
In Fleet Forth, COLD executes EMPTY. Unlike COLD, EMPTY just performs a FORGET with a known address, after first setting CONTEXT and CURRENT to FORTH. Files in use are left open and the stacks are unchanged. In other words, You can EMPTY the dictionary and resume working just as if you had typed:

Code: Select all

FORTH DEFINITIONS FORGET <FIRST.WORD.ADDED.SINCE.BOOT>
COLD resets the machine just as if Forth had first been loaded.

Re: Redesigning Forth

Posted: Wed Jun 03, 2020 3:41 am
by IamRob
JimBoyd wrote:
But then you wouldn't have any data available to see what went wrong. As an example, suppose you wanted to add a new control structure to your Forth. It compiles successfully, but it's not quite right. When you test it in a new word, that word fails to compile. Now, wouldn't you rather have the data available to use tools such as DUMP and SEE to try to find out what went wrong?
Also, some Forths have a word, EMPTY , that will remove all words added since Forth was last loaded. Loaded as in, the Forth language program is called in from removable media and run on the computer.

I take it that DUMP and SEE don't use FIND to find a word, since the word cannot be found when the SMUDGE bit is on, correct?

I don't have any words yet that can do anything with a word that has been SMUDGE'd.

The word that I wrote to decipher a word is called DECODE, but it uses FIND and can't find SMUDGE'd words.

If I have quite a few words, then I use screens and just LIST the word description there.

Or if doing just one or two words at a time, then I scroll those words to the top of the monitor screen, and then lock those monitor lines so they don't scroll up.

Been using alternatives and work-arounds so far. So SMUDGE'ing is on the list of things to do.

Re: Redesigning Forth

Posted: Wed Jun 03, 2020 4:43 am
by GARTHWILSON
The only use of the smudge bit I've ever seen is to have a word smudged while it is being compiled (so it can call a previous version of itself if necessary); and then part of the semicolon's job is to unsmudge it. I have never heard of a completed word being smudged, let alone multiple words. What would such smudging be used for?

DUMP prints a range of addresses, starting from the beginning address specified and going through the number of bytes specified. It wouldn't matter what's in those addresses.

Re: Redesigning Forth

Posted: Wed Jun 03, 2020 9:25 pm
by JimBoyd
IamRob wrote:
I take it that DUMP and SEE don't use FIND to find a word, since the word cannot be found when the SMUDGE bit is on, correct?
As Garth said, DUMP takes an address and count from the data stack and performs a memory dump.
SEE does use find. In my post on SEE , I mentioned in my fifth point that I define SEE as this:

Code: Select all

: SEE   ' (SEE) ;
' ( pronounced tick) uses find to find the next word in the text stream and leaves the address on the stack ( or aborts if the name is not found) . (SEE) takes the address of a word's code field and decompiles that word. LATEST will return the address of the name field of the latest word defined ( in that vocabulary ) regardless of whether it's smudged. With the above definition of SEE, you could type

Code: Select all

LATEST NAME> (SEE)
To examine the body of the latest word defined even if it's smudged. It's also helpful if SEE is factored into useful components such as :DIS . When given the address of a section of threaded code ( such as in the body of a colon definition ) where the address is lined up on one of the words that make up this section of threaded code, :DIS will decompile the code at that point on. For this example I left the number base set to DECIMAL .

Code: Select all

SEE FIND
FIND
  8045  2638 CONTEXT
  8047  4903 @
  8049  2841 (FIND)
  8051  5177 ?DUP
  8053  2436 ?EXIT
  8055  2652 CURRENT
  8057  4903 @
  8059  8034 VFIND
  8061  2406 EXIT
18 
 OK
8051 :DIS
  8051  5177 ?DUP
  8053  2436 ?EXIT
  8055  2652 CURRENT
  8057  4903 @
  8059  8034 VFIND
  8061  2406 EXIT
12 
 OK
If not lined up

Code: Select all

8050 :DIS
  8050 14603
  8052 33812
  8054 23561
  8056  9994
  8058 25107
  8060 26143
  8062 25609
14
 OK
You get the idea.
:DIS can come in handy if the smudged word has a section that is so badly messed up that SEE can not correctly decompile it at that point and you have to try an address and resume decompiling there.
That is how, with right tools, you can SEE a word that has been smudged.

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 5:14 am
by IamRob
The only use of the smudge bit I've ever seen is to have a word smudged while it is being compiled (so it can call a previous version of itself if necessary); and then part of the semicolon's job is to unsmudge it. I have never heard of a completed word being smudged, let alone multiple words. What would such smudging be used for?


During compiling, if there is a error in the word being compiled, the smudge bit gets left on and you can't correct the word where the error happened or forget the word being created. The only way to get rid of the word is to first unsmudge it, which is easy enough.

I just find it tedious that the word just sits there like a 10,000 pound marshmallow and one has to do extra work to get rid of it.

I imagine it would be easy enough to tap into the error routine and reset HERE and LATEST to there previous addresses before the word causing the error.

Maybe a word that captures the current HERE and LATEST addresses before trying to compile a new colon word and another word called RESET that resets those values to just before the last word on the dictionary.

Would this work or is there more to it? Like a simplified version of FORGET but only on the last word whether it is smudged or not?

The FORTH I am working with is pretty incomplete. But it is the best one for the Apple so far.

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 5:19 am
by IamRob
JimBoyd wrote:
IamRob wrote:
I take it that DUMP and SEE don't use FIND to find a word, since the word cannot be found when the SMUDGE bit is on, correct?
As Garth said, DUMP takes an address and count from the data stack and performs a memory dump.
SEE does use find. In my post on SEE , I mentioned in my fifth point that I define SEE as this:

Code: Select all

: SEE   ' (SEE) ;
' ( pronounced tick) uses find to find the next word in the text stream and leaves the address on the stack ( or aborts if the name is not found) . (SEE) takes the address of a word's code field and decompiles that word. LATEST will return the address of the name field of the latest word defined ( in that vocabulary ) regardless of whether it's smudged. With the above definition of SEE, you could type

Code: Select all

LATEST NAME> (SEE)
To examine the body of the latest word defined even if it's smudged. It's also helpful if SEE is factored into useful components such as :DIS . When given the address of a section of threaded code ( such as in the body of a colon definition ) where the address is lined up on one of the words that make up this section of threaded code, :DIS will decompile the code at that point on. For this example I left the number base set to DECIMAL .

Code: Select all

SEE FIND
FIND
  8045  2638 CONTEXT
  8047  4903 @
  8049  2841 (FIND)
  8051  5177 ?DUP
  8053  2436 ?EXIT
  8055  2652 CURRENT
  8057  4903 @
  8059  8034 VFIND
  8061  2406 EXIT
18 
 OK
8051 :DIS
  8051  5177 ?DUP
  8053  2436 ?EXIT
  8055  2652 CURRENT
  8057  4903 @
  8059  8034 VFIND
  8061  2406 EXIT
12 
 OK
If not lined up

Code: Select all

8050 :DIS
  8050 14603
  8052 33812
  8054 23561
  8056  9994
  8058 25107
  8060 26143
  8062 25609
14
 OK
You get the idea.
:DIS can come in handy if the smudged word has a section that is so badly messed up that SEE can not correctly decompile it at that point and you have to try an address and resume decompiling there.
That is how, with right tools, you can SEE a word that has been smudged.


I don't have any version of SEE yet, but it is definitely a utility I could use. Is there a word description listed any where for it?

Or is this an exercise left for me?

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 5:40 am
by GARTHWILSON
IamRob wrote:
I don't have any version of SEE yet, but it is definitely a utility I could use. Is there a word description listed any where for it?

Or is this an exercise left for me?

The ANS Forth standard book, ANSI X3.215-1994 says on page 115:

  • ("<spaces>name" — )

    Display a human-readable representation of the named word's definition. The source of the representation (object-code decompilation, source block, etc.) and the particular form of the display is implementation-defined.

    SEE may be implemented using pictured numeric output words. Consequently, its use may corrupt the transient region identified by #>.


Mine uses one line per cell, and for each cell, gives the unsigned and signed number in both hex and decimal, plus what it represents in ASCII in case that's what it's there for. Most cells will be the CFAs of other words, so the name is displayed, with the length truncated and control characters replaced so you don't get in trouble when it's not a valid CFA (for example if it's a literal, or if the word is headerless). I do allow the special DOS/ANSI [Edit: that should say IBM437] characters above $7F though. It stops when it gets to an unnest, which is why I have EXIT as a separate word (even though they share the same code and do the same thing), so SEE doesn't stop prematurely if it comes to an EXIT before getting to the end of the word. I still have some tail-call optimizations in the kernel that could fool SEE, but in that case I'd probably just turn off the line printer when I get as much as I want. I seldom use SEE.

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 4:17 pm
by IamRob
Sorry for the confusion. I see the difference now.

I have SEE (my word is DECODE) and it just decompiles the words back into a form exactly how you typed it in on the keyboard without each word description's address and on a single line.

If I want to see a word's address, I have the word FIND, which verifies if a word exists, or not, and prints all the Field addresses like so.

FIND DECODE
Immediate mode word: no
name len = 6
nfa = 259C
lfa = 25A3
cfa 25A5
pfa = 25A7


I probably could use a word like DISP to display all the addresses of a word, though. That is easy enough to create.

Most of my compile errors are caused by silly spelling mistakes. Instead of having to un-SMUDGE a word, then FORGET it, (or LATEST NAME> SEE) I will try a different method of just RESETing HERE and LATEST to the previous values.

Less typing causes less SILLY errors. I think I will rename RESET to SILLY. (or in Homer Simpsons famous expression DOH!)

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 6:22 pm
by GARTHWILSON
When I originally wrote my SEE word, I called it VIEW, but then changed it when I found out SEE was the ANS name. I've done that with a few others as well. I don't want to be forced to adhere to ANS, because I saw some things in it that would make Forth less efficient on the 65's; but otherwise I want to avoid unnecessarily adding to the complaint of "no effective standard."

My SEE displays every cell in various forms though since SEE won't know what's important in the particular context, regarding for example whether something is ASCII or a constant that's more meaningful in hex or in decimal. I don't have it print the NFA, LFA, CFA, and PFA since in the ITC model I use where headers are not separate from the code, three will always be totally predictable if you know the other one of the four.

Again though, unsmudging is a standard part of the job of ; so you shouldn't have to explicitly unsmudge something to FIND or FORGET it. FORGET is not the preferred way in ANS, but it was used so much before that that I don't have any qualms about it. (ANS prefers MARKER; but MARKER requires planning ahead more.) FORGET is included in the ANS Programming Tools word set, with a note saying, "This word is obsolescent and is included as a concession to existing implementations."

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 7:55 pm
by IamRob
GARTHWILSON wrote:
Again though, unsmudging is a standard part of the job of ; so you shouldn't have to explicitly unsmudge something to FIND or FORGET it. FORGET is not the preferred way in ANS, but it was used so much before that that I don't have any qualms about it. (ANS prefers MARKER; but MARKER requires planning ahead more.) FORGET is included in the ANS Programming Tools word set, with a note saying, "This word is obsolescent and is included as a concession to existing implementations."

I don't know if I follow, since a word with the SMUDGE bit set was meant to prevent from being found. And the compiler keeps the SMUDGE bit set of a word until it compiles properly.

Is this different on other Forths?

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 8:48 pm
by GARTHWILSON
IamRob wrote:
I don't know if I follow, since a word with the SMUDGE bit set was meant to prevent from being found. And the compiler keeps the SMUDGE bit set of a word until it compiles properly.

Is this different on other Forths?

My understanding and experience is that the smudge bit is always cleared when you reach the ; and that the only reason to have it is so you can involve the old definition in the new, for example if you wanted

Code: Select all

: FOOBAR
   NEW_CONDITION @
   IF    <do-this-new-stuff>
   ELSE  FOOBAR
   THEN         ;
where the old FOOBAR is found and can be used at execution time if the newer condition is not met. Subsequent invocations of FOOBAR will always be for the new one, which may conditionally call on the old one; but the old one is no longer directly accessible. Offhand, I can't think of any situation where you'd want a word to remain smudged after its compilation is completed. If an error is encountered during compilation, you'll normally get an error message, for example, "incomplete structure," and an abort. The ABORT" won't unsmudge it, but it won't change the dictionary pointer either, so the incomplete word takes up some memory but the next header will be linked back to the previous word, in the linked list.

Again, that's per my understanding and experience. I always welcome being shown something new and useful that I hadn't thought of.

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 9:13 pm
by IamRob
That is my understanding as well, but it just annoys me that an incomplete word takes up memory. With limited memory one tries to be as efficient as possible. And in my Forth, a new word must still link to the incomplete word as I can still see the incomplete word using some form of a dictionary LIST.

I now wonder if it is possible to remove a word in the middle of a dictionary, then have every word that comes after that removed word, to be decompiled and recompiled at its new address? Will start another thread for this one after attempting it.

Re: Redesigning Forth

Posted: Thu Jun 04, 2020 9:26 pm
by GARTHWILSON
IamRob wrote:
I now wonder if it is possible to remove a word in the middle of a dictionary, then have every word that comes after that removed word, to be decompiled and recompiled at its new address? Will start another thread for this one after attempting it.

That would be where FORGETting and recompiling would come in, which ideally is very fast (which is where your original idea of the sort comes in). Compilation on my '02 Forth is not very fast, but in spite of using the long linked list for FIND, I have other more-major time-takers in my '02 Forth, involving receiving and parsing the input stream with a lot of secondaries (which are converted to primitives in my '816 Forth since the '816 is so much more memory-efficient for primitives than the '02 is). Another consideration however is that variables' and arrays' contents won't survive the recompilation unless extra measures are taken. Overall, I don't find all of this to be much of a problem though.

Re: Redesigning Forth

Posted: Fri Jun 05, 2020 7:38 pm
by JimBoyd
GARTHWILSON wrote:
the incomplete word takes up some memory but the next header will be linked back to the previous word, in the linked list.

Again, that's per my understanding and experience. I always welcome being shown something new and useful that I hadn't thought of.
It's my understanding that the smudged word is still linked into the dictionary, as WORDS will show. If it were not, there would be no need to smudge the count byte to hide it.