Page 1 of 1

Manipulating >IN for fun and utility

Posted: Tue Dec 07, 2021 2:42 am
by JimBoyd

>IN can be modified while the text stream is being processed to achieve some useful results.
Here is an example I've already mentioned elsewhere. Suppose that during the course of testing and refining a Forth word, the old versions were left in the dictionary. Assuming the first one is not smudged, here is a way to remove all of them at one time:

Code: Select all

FORGET TESTWORD >IN OFF

Here is a simple compile time loop.

Code: Select all

// CONDITIONAL COMPILATION/EXECUTION
: [BEGIN]  ( -- )
   >IN @ >A ; IMMEDIATE
: [UNTIL]  ( FLAG -- )
   IF
      A> DROP  EXIT
   THEN
   A@ >IN ! ; IMMEDIATE

Here it is used in a Forth screen:

Code: Select all

CREATE TABLE
   0
   [BEGIN] DUP C, 1+ DUP 255 > [UNTIL]
   DROP

or even from the command line (the TIB ) or an evaluated string:

Code: Select all

CREATE TABLE  OK
0 [BEGIN] DUP C, 1+ DUP 255 > [UNTIL] DROP  OK

It's even nestable.

Code: Select all

CREATE TABLE2
   0 0
   [BEGIN]
      [BEGIN]
         2DUP C, C, 1+ DUP 4 >
      [UNTIL]
         DROP 0  1 UNDER+ OVER 2 >
   [UNTIL]
   2DROP

Here is a version if there is no auxiliary stack:

Code: Select all

VARIABLE <IN
: [BEGIN]  ( -- )
   >IN @ <IN ! ; IMMEDIATE
: [UNTIL]  ( F -- )
   ?EXIT
   <IN @ >IN ! ; IMMEDIATE

Of course, this version is not nestable.


Re: Manipulating >IN for fun and utility

Posted: Tue Dec 07, 2021 3:03 am
by GARTHWILSON
Even after 30 years of using Forth, its power continues to surprise me.

Re: Manipulating >IN for fun and utility

Posted: Thu Dec 09, 2021 4:26 am
by IamRob
I do something similar with my Line Load definition. The interpreter pointer points to the beginning of most recently load buffer, and I adjust >IN to a multiple of C/L (chars per line), where to start an interpretation of a word.My Line Load has the word definition of "LL" and has the inputs of SCR and LINE. Note also I programmed into Forth the ability to ignore a word if a word definition already exists to prevent duplicate loads of a definition.

In another post I uploaded examples of some screen editing definitions. Now to put them all together to make an automatic editor I load and interpret each line needed for the program. I have enough collection of words that I am starting to write my programs this way, since some words are grouped in ways that may not be used with all applications:

: THRU ( frmscr toscr -- )
: LL ( scr line -- ) ( updates >IN to a multiple of C/L to get the line to start interpreting a definition )
: LLTHRU ( scr linestart linend -- )( >IN is used to calculate if the last line has been surpassed )
: LOAD ( scr -- )
: EDITOR ( -- ) 15 LOAD 16 1 C LLTHRU 17 E LL 18 1F THRU
...etc

Re: Manipulating >IN for fun and utility

Posted: Sat Dec 11, 2021 12:52 am
by JimBoyd
IamRob wrote:
I do something similar with my Line Load definition. The interpreter pointer points to the beginning of most recently load buffer, and I adjust >IN to a multiple of C/L (chars per line), where to start an interpretation of a word.My Line Load has the word definition of "LL" and has the inputs of SCR and LINE.

Fleet Forth's LINELOAD has the stack effect shown in the Forth-83 Standard's section 'UNCONTROLLED REFERENCE WORDS'. It takes the line number and the number of the screen to load.

Code: Select all

: LINELOAD  ( LINE# BLK# -- )
   DUP 0=
   ABORT" CAN'T LOAD 0"
   RB DECIMAL
   BLK 2@ 2>R
   BLK !  C/L * >IN !
   INTERPRET  2R> BLK 2! ;

Here is LOAD

Code: Select all

: LOAD  ( BLK# -- )
   0 SWAP LINELOAD ;

As for why LINELOAD has BLK 2@ and BLK 2! , here are the definitions of BLK and >IN .

Code: Select all

VARIABLE BLK   HERE 0 , CONSTANT >IN

IamRob wrote:
Note also I programmed into Forth the ability to ignore a word if a word definition already exists to prevent duplicate loads of a definition.

The FORTH 2012 Standard has the word [DEFINED] to return a true flag if the word following [DEFINED] in the text stream is defined in the specified search order. Some other Forths have something similar. Used with conditional compilation, it is handy to avoid recompiling an oft used utility word which may be defined in multiple lexicons. However, it is a facility which is under the control of the programmer.

Re: Manipulating >IN for fun and utility

Posted: Sun Apr 30, 2023 10:34 pm
by JimBoyd
JimBoyd wrote:
IamRob wrote:
Note also I programmed into Forth the ability to ignore a word if a word definition already exists to prevent duplicate loads of a definition.

The FORTH 2012 Standard has the word [DEFINED] to return a true flag if the word following [DEFINED] in the text stream is defined in the specified search order. Some other Forths have something similar. Used with conditional compilation, it is handy to avoid recompiling an oft used utility word which may be defined in multiple lexicons. However, it is a facility which is under the control of the programmer.

I'd like to add that the ability to redefine a word is useful. My Forth is built with a metacompiler. When I test changes to my Forth kernel on the host, I am redefining words. I will not give the words under test different names. I do not need to alter the source after testing just to change names back. There is less chance of a typo causing problems after the testing showed that a modification works.

Re: Manipulating >IN for fun and utility

Posted: Sun Apr 30, 2023 11:12 pm
by GARTHWILSON
Being able to re-define words is important in development.  I have the word EXISTS?, but I only use it in interpretation, not compilation.  You follow it with the name, and it displays "No" if it's not found, or "Yes" followed by the CFA if it is found.

Re: Manipulating >IN for fun and utility

Posted: Sun Apr 30, 2023 11:21 pm
by JimBoyd
Although my Forth does not have EXISTS? , Scott Ballantyne's Blazin' Forth does. Blazin' Forth's EXISTS? is also followed by a name but it does not display anything. It returns the same parameters as FIND .

Code: Select all

EXISTS? SOMEWORD
" SOMEWORD" FIND

Both return the same thing.

Re: Manipulating >IN for fun and utility

Posted: Sun Sep 03, 2023 10:38 pm
by JimBoyd

My Forth's CREATE is another place where >IN is manipulated.
>IN is preserved when a name is parsed the first time so it can be parsed again.

Code: Select all

   >IN @  NAME  SWAP >IN !

NAME is basically BL WORD with case insensitivity.

The first time the name is parsed is to check for redefinition in the CURRENT vocabulary as well as use the name length to determine if a byte needs allotted to avoid placing the code field on a page boundary, thanks to that indirect jump bug.
The optional VIEW field and the LINK field are laid down.
The text stream is parsed once again (for the same name) to lay down the NAME field.

My Forth's metacompiler is a place where >IN is manipulated even more.
For the same word in the kernel's source, a header is built in virtual memory and a header is built in the host memory to serve as the handle to that word.