Jump to content
IGNORED

Forth Tutorials


matthew180

Recommended Posts

2 minutes ago, DavidC said:

Now this is gonna come off as weird, but ....LOGO is a bit like Forth..define definitions of stuff, what was first?  LOGO or Forth?

You are perfectly correct.  TO   in LOGO  is like :  in Forth.

 

I think Forth was first.  It was one guy who made it for himself in 1969 ish.   and then developed it over the next few years.

It was a stack of punched cards in the beginning. :) 

 

https://www.forth.com/resources/forth-programming-language/

 

 

  • Like 1
Link to comment
Share on other sites

13 minutes ago, GDMike said:

Just back up your screens, as nothing is worse than losing a formula that wasn't easy to come up with.

The great thing about today's TI-99 programmer is Classic99's ability to take pasted text.

You can have great fun just using text files for your programs and pasting them into the emulator at blazing speed.

 

I am working again here with floppy drives and I wish they had a "Viagra" for their floppy-ness. :)

 

It is slooooowwww.

 

 

  • Haha 3
Link to comment
Share on other sites

Regarding leaving DO LOOP early, there are times you may want to leave the loop with other conditions to continue the program without aborting. Enter, LEAVE .

: MYWORD  ( n -- )   \ Execute loop n times or until <Enter> hit
   ( n ) 0 DO
      <do loop things>
      ?KEY 13 = IF           \ <Enter> hit?
         <do other things>   \ yup
         LEAVE               \ this is the last time through loop
      THEN
   LOOP  ;

 

...lee

Link to comment
Share on other sites

The problem with using ?KEY is that it almost certainly needs to be de-bounced, i.e., Forth code is fast enough that, if ?KEY is executed again in near code, it will catch the key just tested before the user can release the key. The following word demonstrates this phenomenon:

: BOUNCE  \ test for bounce of <Enter>..end with 'E'
   BEGIN
      ?KEY
      CASE
         13 OF 13 . ENDOF   \ print '13' if <Enter> detected
         69 OF ABORT ENDOF  \ abort if 'E' detected
      ENDCASE
   AGAIN
;

BOUNCE will print '13' for every time through the loop that it detects <Enter> and exit when 'E' is tapped. In fact, you will notice that, when you type the word BOUNCE and tap <Enter> to execute it, execution likely starts before you can release <Enter> as evidenced by the one or more '13's at the start. This and tapping <Enter> after first executing BOUNCE demonstrate why de-bouncing is often (usually?) necessary.

 

The word ?TERMINAL as defined in the fbForth kernel is written in Assembler and is appropriately de-bounced, i.e., when <FCTN+4> is detected by ?TERMINAL , it waits until <FCTN+4> is no longer detected before returning to the calling procedure. This is how you could do this in high-level Forth:

: ?TERMINAL  ( -- flag )  \ test for <clear> (<break> or <FCTN+4>)
   ?key 2 = dup         \ check for <clear> and dup flag
   if                   \ true?
      begin             \ start de-bounce loop
         ?key 2 =       \ as long as <clear>
      while             \   is detected,
      repeat            \     check again
   then
;

 

...lee

  • Like 2
Link to comment
Share on other sites

All right!!  I spent about a hour this afternoon after work, pulling my hair out but I finally am getting somewhere.  What I finally figured out was.. : LOOPY BEGIN KEY? 1 AND WHILE ." HELLO WORLD"  REPEAT ;     ( using turboforth )       this prints HELLO WORLD forever and ever until I press a EVEN numbered key.   2, 4, 6 ect.  COOL!   It's a start!    @Lee Stewart   I will try out your example.    I didn't want to look at any posts on here today until I figured SOMETHING out on my own, mission accomplished!    

Edited by DavidC
  • Like 2
Link to comment
Share on other sites

2 hours ago, Lee Stewart said:

Regarding leaving DO LOOP early, there are times you may want to leave the loop with other conditions to continue the program without aborting. Enter, LEAVE .


: MYWORD  ( n -- )   \ Execute loop n times or until <Enter> hit
   ( n ) 0 DO
      <do loop things>
      ?KEY 13 = IF           \ <Enter> hit?
         <do other things>   \ yup
         LEAVE               \ this is the last time through loop
      THEN
   LOOP  ;

 

...lee

I had to change it to ?KEY 14, because I imagine just like you said, it is so fast that I couldn't release the <enter> key quick enough when I typed MYWORD <enter>.   And..just out of pure coinicidence ?KEY 14 is <F5> on my laptop...ALMOST <F4> hahaha!!. 

  • Like 1
Link to comment
Share on other sites

On 5/11/2020 at 10:03 PM, DavidC said:

Now this is gonna come off as weird, but ....LOGO is a bit like Forth..define definitions of stuff, what was first?  LOGO or Forth?

Now everyone knows that God speaks Forth but some people have this view about LOGO

 

LOGO is the Language Of God, and we are His turtles.
    L: Language
    O: Of
    G: God
    O: Only God knows what the last "O" stands for.

?

  • Haha 3
Link to comment
Share on other sites

Just a fyi. I put together a little"Turboforth" manual in word format.

It's basically the words and definitions categorized from the Tf.net web site. It's available in the file section in ti99er Facebook page.

But it's great to have it in a booklet when you're looking for a word. 

Edited by GDMike
  • Like 3
Link to comment
Share on other sites

7 hours ago, GDMike said:

Just a fyi. I put together a little"Turboforth" manual in word format.

It's basically the words and definitions categorized from the Tf.net web site. It's available in the file section in ti99er Facebook page.

But it's great to have it in a booklet when you're looking for a word. 

Reminds me of those great "cheat sheets" that TI made for BASIC and XBASIC. Mine were well worn. :)

Come to think of it I had one for ANS Forth made back in the 90s after the standard was published. Wonder where that might be...

  • Haha 1
Link to comment
Share on other sites

6 hours ago, TheBF said:

Reminds me of those great "cheat sheets" that TI made for BASIC and XBASIC. Mine were well worn. :)

Come to think of it I had one for ANS Forth made back in the 90s after the standard was published. Wonder where that might be...

I think what would help the group is an example of each command. I started doing that then got sidetracked into assembly. But if it doesn't get done by next year I'll try to pull it off.

 

 

Link to comment
Share on other sites

13 minutes ago, GDMike said:

I think what would help the group is an example of each command. I started doing that then got sidetracked into assembly. But if it doesn't get done by next year I'll try to pull it off.

 

 

The real challenge for newbies with Forth is there are a lot more words to learn than in other languages. It makes a reference sheet into a multi-page document. This gave rise to the Forth "Glossary" something I have yet to complete for Camel99 Forth.

  • Thanks 1
Link to comment
Share on other sites

It gets confusing. Quickly.  The deeper I dig the more confused I get.  That says more about me than it does about Forth.  I sort of get it, and I have those moments where it all makes sense..but they are fleeting. I think about it in my sleep and it is gone in the morning.   It all made sense...and then I forget what I was thinking.   

Link to comment
Share on other sites

Forth is a very different approach to programming.  If you have any experience with Assembly Language that can help. 

Forth looks like a high level language from the outside having an interpreter and a compiler but...

 

Forth is actually the Assembly Language of a computer that uses two stacks instead of registers.  Start there.

On top of the Forth "virtual" machine instructions like fetch (@) , store (!), DUP, DROP, SWAP etc... there are a bunch of small "programs" which are the rest of the words in the system.

 

A word like DEPTH that gives you the stack depth is actually a tiny program written in the "instructions" of the stack computer.

 

You should program Forth by making more tiny programs that let you do the job you want done.

Each of these tiny programs work together to complete your larger project.

You use the interpreter to quickly test your tiny programs and use FORGET to remove the incorrect versions. This is the key to using Forth.

 

We can think of the tiny programs like Lego blocks that fit together.  

This is challenging at first because you have to make the lego blocks yourself and then assemble those lego blocks to make a program.

Compare this to BASIC which is more like a Lego set with the blocks pre-made. 

 

So if you come BASIC where the system is protecting you from mis-steps at every turn, Forth feels like chaos.

Forth like Assembler lets you shoot yourself in the foot, in the head or anywhere you point the gun. :) 

 

Not sure if that helps but sometimes getting a fundamental concept of something makes for clearer thinking.

 

This is a first level understanding of Forth. After you get more familiar with these underlying concepts there is another level.

(Enhancing/Extending the compiler is possible but not for the novice)

 

Exercises:

1. Write a program (a Forth word) that waits for a KEY and prints "TRUE" if a '1' is pressed and "FALSE" if any other key is pressed. Call your program "ONE?"

2. Write a program that  loops and prints "HELP!" continuosly UNTIL any key is pressed. Call your program "HELP"

3. Write a program the loops and prints "PRESS Q" continously until "Q" is pressed. Call your program WAITFORQ.

4. BONUS: Write a program that loops forever waiting for the ascii key you give it as a parameter. 

                Call the program WAITFOR. Usage:  65 WAITFOR (waits for "A")

 

Show your work here. :) 

 

 

  • Like 3
Link to comment
Share on other sites

One of the most difficult problems in learning Forth is other computer languages. For most of us, Forth was not our first computer language. We had become comfortable with infix notation:

a + b - d * 3

and did not find it easy to wrap our heads around the postfix notation (also known as reverse Polish notation or RPN) resulting from the stack-oriented basis of Forth:

a b + d - 3 *

This stack basis of Forth presents another problem in that many Forth words have the same names as functions in other languages but their postfix operation appears to be illogical. Putting the test condition for IF in front of the word just seems wrong, somehow. That

x IF BEEP THEN    <--Forth

means the same as

IF x THEN BEEP    <--Basic

seems perverse. But, until you get acclimated to the use of stacks, Forth will remain elusive.

 

...lee

  • Like 4
Link to comment
Share on other sites

It took me some time but now either I got used to it or I just started paying more attention to values in the statement rather than the arrangement of words then I looked at the arrangement as my last look. It gets easier the more you work with it. Be patient

Link to comment
Share on other sites

It took quite a while for me to recover from BASIC. 

I remember wondering "How do I make a loop like with a GOTO that scans for a key?"   ?

 

Doh!   "KEY" is a loop that waits for a key and gives it to you when one is pressed.

Link to comment
Share on other sites

On 5/16/2020 at 9:47 AM, TheBF said:

 

 

So if you come BASIC where the system is protecting you from mis-steps at every turn, Forth feels like chaos.

Forth like Assembler lets you shoot yourself in the foot, in the head or anywhere you point the gun. :) 

 

 

This sums it up perfectly.

  • Like 1
Link to comment
Share on other sites

On 5/16/2020 at 9:47 AM, TheBF said:

 

 

 

 

Exercises:

1. Write a program (a Forth word) that waits for a KEY and prints "TRUE" if a '1' is pressed and "FALSE" if any other key is pressed. Call your program "ONE?"

2. Write a program that  loops and prints "HELP!" continuosly UNTIL any key is pressed. Call your program "HELP"

3. Write a program the loops and prints "PRESS Q" continously until "Q" is pressed. Call your program WAITFORQ.

4. BONUS: Write a program that loops forever waiting for the ascii key you give it as a parameter. 

                Call the program WAITFOR. Usage:  65 WAITFOR (waits for "A")

 

Show your work here. :) 

 

 

This is a great idea!  I will work on these and post my results. Kind of like a interactive tutorial/book exercise where folks can get feedback from the teachers. I will try to come up with some answers within the next few days. When I get some alone time.. :)  

  • Like 2
Link to comment
Share on other sites

Not sure if the audience here is ready for this but I found this a few years ago in some docs for the TI MSP430 CPU.

 

I looked at this C program and thought how would I do this in Forth?

This demonstrates why it is not always best to translate directly from one language to another.

 

(Back then I posted this on comp.lang.forth and asked the experts how they would do it and there were a large number of options that I would never think of.)

 /******************************************************************************
 *
 * Name : 8-bit 2-dim Matrix
 * Purpose : Benchmark copying 8-bit values.
 *
 *****************************************************************************/
 typedef unsigned char UInt8;
 const UInt8 m1[16][4] = {
                            {0x12, 0x56, 0x90, 0x34},
                            {0x78, 0x12, 0x56, 0x90},
                            {0x34, 0x78, 0x12, 0x56},
                            {0x90, 0x34, 0x78, 0x12},
                            {0x12, 0x56, 0x90, 0x34},
                            {0x78, 0x12, 0x56, 0x90},
                            {0x34, 0x78, 0x12, 0x56},
                            {0x90, 0x34, 0x78, 0x12},
                            {0x12, 0x56, 0x90, 0x34},
                            {0x78, 0x12, 0x56, 0x90},
                            {0x34, 0x78, 0x12, 0x56},
                            {0x90, 0x34, 0x78, 0x12},
                            {0x12, 0x56, 0x90, 0x34},
                            {0x78, 0x12, 0x56, 0x90},
                            {0x34, 0x78, 0x12, 0x56},
                            {0x90, 0x34, 0x78, 0x12}
                                                     };
 void  main(void)
 {
      int i,j;
      volatile UInt8 m2[16][4], m3[16][4];
      for(i=0;i<16;i++)
      {
         for(j=0;j<4;j++)
         {
            m2[i][j]=m1[i][j];
            m3[i][j]=m2[i][j];
         }
      }
      return;
 }

Forth using the same method. It would be possible that a Forth system would have an array library that goes faster than what I did here.

\ Matrix move demo for Camel99 Forth
\ Forth Equivalent written in C "style"
NEEDS BUFFER: FROM DSK1.BUFFER
NEEDS ELAPSE  FROM DSK1.ELAPSE

CREATE M1   HEX  12 C, 56 C, 90 C, 34  C,
                 78 C, 12 C, 56 C, 90  C,
                 34 C, 78 C, 12 C, 56  C,
                 90 C, 34 C, 78 C, 12  C,
                 12 C, 56 C, 90 C, 34  C,
                 78 C, 12 C, 56 C, 90  C,
                 34 C, 78 C, 12 C, 56  C,
                 90 C, 34 C, 78 C, 12  C,
                 12 C, 56 C, 90 C, 34  C,
                 78 C, 12 C, 56 C, 90  C,
                 34 C, 78 C, 12 C, 56  C,
                 90 C, 34 C, 78 C, 12  C,
                 12 C, 56 C, 90 C, 34  C,
                 78 C, 12 C, 56 C, 90  C,
                 34 C, 78 C, 12 C, 56  C,
                 90 C, 34 C, 78 C, 12  C,

DECIMAL
  4 16 * CONSTANT 4x16

  4x16 BUFFER: M2
  4x16 BUFFER: M3

\ ==================================================================
\ forth needs byte matrix operators but they are simple

: []     ( x y addr -- addr' ) + SWAP 4 * + ;
: []C@   ( x y addr -- char )  [] C@ ;
: []C!   ( char x y addr -- )  [] C! ;

: MAIN()
            16 0 DO
               4 0 DO
                   J I M1 []C@  J I M2 []C!
                   J I M2 []C@  J I M3 []C!
               LOOP
            LOOP ;

And here is how one could do it in Forth :)

: FMAIN
            M1 M2 4x16 CMOVE
            M2 M3 4x16 CMOVE ;
            

MAIN() runs in about 160 milli-seconds

FMAIN runs in about     4 milli-seconds

 

 

Edited by TheBF
TYPO
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...