Jump to content

Photo

Adding CALL to CAMEL Forth

Forth Fun April

3 replies to this topic

#1 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 307 posts
  • Location:The Great White North

Posted Fri Mar 31, 2017 10:19 AM

Those of us who have loved TI BASIC and TI Extended BASIC for these many
years we have grown to love the unique way that we use the various sub-programs
in the TI-99 system. How could we survive without CALL CLEAR, CALL SCREEN,
CALL HCHAR and how about CALL MYSUBROUTINE like we do in XB?  Awesome!
It isn't bad enough that you have to do your math backwards in Forth
but for some reason, implementations of the Forth programing language like
TI-Forth, Turbo Forth and FBForth have completely failed to respect this noble
tradition.
 
Well I say "No More!"
In my new CAMEL99 Forth I have added this staple TI-99 feature to the
language. Here is how it works.

Forth contains a large list of functions that for some reason are called
WORDs. Not a lot of computer language savvy in that community I guess. I mean
what's wrong with SUB-PROGRAM, FUNCTIONS, METHODS or MONADS? Some people just
don't have the gift of creating good jargon. Everybody knows what "WORDS" are.
 
Now if we want to CALL those so-called "WORDS" we need a way to find them.
Fortunately FORTH has a SUB-PROGRAM called FIND. (See what I mean?)
FIND takes a string argument and returns a true or false number and the
actual string where the SUB-PROGRAM resides in the forth "DICTIONARY" or words.
So that sounds like a good place to start.
 
Now using a string in ANS/ISO Forth can be complicated because the people on
the language committee could never agree on how to do strings one way. So there
are byte counted strings, stack strings, text bytes in raw memory and if you
want to you can even make strings like 'C' with a zero on the end.
Make up my mind... please.
 
Fortunately there is a FUNCTION called WORD that lets us parse out a word
from what we type into the console, delimited by any character. Thank
goodness it returns a simple string that we understand.
 
We can pass that string from WORD to FIND and check the flag to see if we found the
SUB-PROGRAM. That's great. But the string that it returns does not get us a
way to CALL the Forth SUB-PROGRAM. It just gives us another string. Useless!
Even worse it's actually not a REAL string. It's the ACTUAL address in memory
where the string starts. They call it the "NAME FIELD ADDRESS". (NFA)
Of course they do.
 
So inside each Forth SUB-PROGRAM, right after the string, is a pointer to
the machine code that needs to run to make the SUB-PROGRAM start. So we have
to get that. This ADDRESS is called the "CODE FIELD ADDRESS" (CFA) and we can
use a Forth FUNCTION to convert the NFA string to a CFA. So that is solved.
But the CODE FIELD ADDRESS is not the address of the code we need. It is
just the place where the CODE's address is stored. So now we need another
CAMEL Forth sub-program ... I mean "WORD".
 
The word we need is EXECUTE. EXECUTE calls a SUB-PROGRAM called FETCH which
gets the contents of a memory location. Why Forth could not call it PEEK is
more than I will ever understand. Once EXECUTE calls "FETCH" then and only then
can EXECUTE run the SUB-PROGRAM. Of course in typical Forth "take the easy way"
fashion, EXECUTE just uses one pathetic little assembly language instruction to
run the SUB-PROGRAM.
 
So it looks like we have all the things we need to make a "CALL" keyword for
Forth and yet NOBODY in that world got off their butts to make it happen.

Here is how it looks when we put it all together as a new definition.
: CALL    ( <TEXT> )
          32 WORD     ( read the program text until char 32 ie: space char)
                      ( pass output to FIND no variables in between Huh?)
           FIND       ( FIND returns a string and a true/false flag)
                      ( if the flag is zero stop with a useful message)
          0= ABORT" *  BAD NAME"
          NFA>CFA     ( from the name string get the code field address)
          EXECUTE     ( EXECUTE the code held in the CFA)
;

So after all that coding we finally bring Forth into the TI-99 universe
where we can write code that is a little more normal.
(even though the parameters are still backwards)

: MYPROGRAM
           CALL CLEAR
           6 CALL SCREEN
           9 9 102 12 CALL HCHAR
;
  CALL MYPROGRAM

theBF


PS After showing this to Lee Stewart he has "optimized" my CALL code to this.
 
: CALL ;
 
   Looks to me like it defines a SUB-PROGRAM that does nothing...
   What? Like sub-programs are going to call themselves?
   These Forth people are REALLY weird.
 
Happy April 1st


#2 Willsy OFFLINE  

Willsy

    River Patroller

  • 3,009 posts
  • Location:Uzbekistan (no, really!)

Posted Fri Mar 31, 2017 11:19 AM

Ha ha! I read all the way to the end with the same "optimisation" in mind as Lee.

However, I can actually improve on Lee's highly optimal code with the following:

: CALL ( -- ) ; IMMEDIATE

I thank you :-)

#3 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 8,246 posts
  • Location:Cookeville, TN

Posted Fri Mar 31, 2017 11:42 AM

Hilarious....

#4 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,311 posts
  • Location:Silver Run, Maryland

Posted Fri Mar 31, 2017 3:09 PM

Ha!  Well done!  I was on that track until I read that I had already done it—how telepathic of us!  :grin:  [edit:  Or, should I say, “telepathetic”?]

 

...lee







Also tagged with one or more of these keywords: Forth, Fun, April

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users