Manipulating >IN for fun and utility

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
Post Reply
JimBoyd
Posts: 931
Joined: 05 May 2017

Manipulating >IN for fun and utility

Post 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.

User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Manipulating >IN for fun and utility

Post by GARTHWILSON »

Even after 30 years of using Forth, its power continues to surprise me.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
IamRob
Posts: 357
Joined: 26 Apr 2020

Re: Manipulating >IN for fun and utility

Post 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
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Manipulating >IN for fun and utility

Post 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.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Manipulating >IN for fun and utility

Post 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.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Manipulating >IN for fun and utility

Post 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.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Manipulating >IN for fun and utility

Post 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.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Manipulating >IN for fun and utility

Post 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.
Post Reply