Lesson 1

\       Lesson 1 - Introducing Forth
\       The Forth Course
\       by Richard E. Haskell
\          Dept. of Computer Science and Engineering
\          Oakland University, Rochester, MI 48309

comment:



                                Lesson 1

                           INTRODUCING FORTH


                1.1  INTRODUCTING FORTH                 1-2

                1.2  FORTH ARITHMETIC                   1-3

                1.3  FORTH ARITHMETIC OPERATORS         1-4

                1.4  STACK MANIPULATION WORDS           1-5

                1.5  MORE FORTH WORDS                   1-8

                1.6  COLON DEFINITIONS                  1-10

                     EXERCISES                          1-12




























1.1  INTRODUCING FORTH

        Everything in Forth is a word.

        Forth words must be separated by a space.

        Forth words are stored in a dictionary.

        Forth words may be either interpreted or compiled.

        When in the interpret mode, a Forth word is executed.

        When in the compile mode, a Forth word is stored in the dictionary.

        You form Forth phrases by stringing Forth words together.

        If you type a Forth word and press <Enter>, it will be executed.
                (Interpret mode).

        If you type a number (e.g. 6) and press <Enter>, the number will be
           stored on the stack as a 16-bit signed integer.

        Forth uses the stack extensively to pass parameters from one word
           to the next.  This means that the need for variables in Forth
           is greatly reduced.

        You can define new words in Forth (made up of previously defined
           Forth words) that become part of the Forth dictionary, and can
           be used like any other Forth word.


























1.2  FORTH ARITHMETIC

        Forth uses the stack to perform arithmetic operations using postfix
        notation.

        The stack stores 16-bit values in most Forths including F-PC.
        32-bit Forths, such as MacForth, store 32-bit values on the stack.
        Thus, values on the stack will occupy 2 bytes in 16-bit Forths and
        4 bytes in 32-bit Forths.

        When you type a number, it is placed on the stack.  You can enter
        numbers in any base.  We will see how to change the base later.
        The default base is decimal.  Therefore, if you type 35, the hex
        value 23h (the suffix h indicates a hex value) will be stored on
        the stack as follows
                 ___________       ___________________
                 | 0 0 2 3 |       | 0 0 0 0 0 0 2 3 |
                 |---------|       |-----------------|
             16-bit stack value     32-bit stack value


        If you type two numbers, separated by a space, they will both be
        stored on the stack.  For example, if you type

                127 256

        the two hex values 7Fh and 100h will be stored on the stack as
        follows:
                     ___________
                     | 0 1 0 0 |<--- top of stack
                     |---------|
                     | 0 0 7 F |
                     |---------|

        Typing .S (or .s) displays the contents of the stack
        non-destructively.

                127 256 .s  127 256 ok

        The word ok is the Forth prompt.

        Values are stored on the stack as signed two's complement numbers.

        Thus, for 16-bit Forths the values stored on the stack can range
        from -32,768 to +32,767.

        For 32-bit Forths the values stored on the stack can range from
        -2,147,483,648 to +2,147,483,647.







1.3  FORTH ARITHMETIC OPERATORS

        The Forth word . (dot) will print the value on top of the stack.

                7 9 . .  will print 9 7

        Carriage returns are generally ignored by Forth and are treated
        as a blank.  These can be used to make your program more readable.
        By writing your program in a "vertical" fashion you can indicate
        the "stack picture" to the right of your program following a
        backslash \.  Anything following a backslash on a line is treated
        as a comment and is ignored.  For example, to illustrate what is
        on the stack at each stage of the above example, we could write

                                        Stack picture (top of stack to right)

                        7                       \ 7
                        9                       \ 7 9
                        .                       \ 7
                        .                       \

        Note that the dot removes the value from the stack.

        The Forth word + (plus) adds the top two values on the stack and
        leaves the result on the stack.  For example,

                7 9 + .  will print 16

                        7                       \ 7
                        9                       \ 7 9
                        +                       \ 16
                        .                       \

        The Forth word - (minus) will subtract the value on top of the
        stack from the second value on the stack and leave the difference
        on the stack.

                8 5 - .  will print 3

                        8                       \ 8
                        5                       \ 8 5
                        -                       \ 3
                        .                       \

        The Forth word * (star) will multiply the top tow values on the
        stack and leave the product on the stack.

                4 7 * .  will print 28

                        4                       \ 4
                        7                       \ 4 7
                        *                       \ 28
                        .                       \


        The Forth word / (slash) will divide the second value on the stack
        by the value on top of the stack and leave the integer quotient
        on top of the stack.

                8 3 / .  will print 2

                        8                       \ 8
                        3                       \ 8 3
                        /                       \ 2
                        .


1.4  STACK MANIPULATION WORDS

        Stack picture ( before -- after )
                before = elements on stack before word is executed.
                after  = elements on stack after word is executed.

        DUP     ( n -- n n )
                Duplicates the top element on the stack

                5 DUP . .  will print 5 5

                        5                       \ 5
                        DUP                     \ 5 5
                        .                       \ 5
                        .                       \

        SWAP    ( n1 n2 -- n2 n1 )
                Interchanges the top two elements on the stack.

                3 7 SWAP . .  will print 3 7

                        3                       \ 3
                        7                       \ 3 7
                        SWAP                    \ 7 3
                        .                       \ 7
                        .                       \

        DROP    ( n -- )
                Removes the top element from the stack.

                6 2 DROP .  will print 6

                        6                       \ 6
                        2                       \ 6 2
                        DROP                    \ 6
                        .







        OVER    ( n1 n2 -- n1 n2 n1 )
                Duplicates the second element on the stack.

                6 1 OVER . . .  will print 6 1 6

                        6                       \ 6
                        1                       \ 6 1
                        OVER                    \ 6 1 6
                        .                       \ 6 1
                        .                       \ 6
                        .

        TUCK    ( n1 n2 -- n2 n1 n2 )
                Duplicates the top element on the stack under the second
                element.  This is equivalent to SWAP OVER.

                6 1 TUCK . . .  will print 1 6 1

                        6                       \ 6
                        1                       \ 6 1
                        TUCK                    \ 1 6 1
                        .                       \ 1 6
                        .                       \ 1
                        .

        ROT     ( n1 n2 n3 -- n2 n3 n1 )
                Rotates the top three elements on the stack.  The third
                element becomes the first element.

                3 5 7 ROT . . .  will print 3 7 5

                        3                       \ 3
                        5                       \ 3 5
                        7                       \ 3 5 7
                        ROT                     \ 5 7 3
                        .                       \ 5 7
                        .                       \ 5
                        .


        -ROT     ( n1 n2 n3 -- n3 n1 n2 )
                Rotates the top three elements on the stack backwards.
                The top element is rotated to third place.

                3 5 7 -ROT . . .  will print 5 3 7

                        3                       \ 3
                        5                       \ 3 5
                        7                       \ 3 5 7
                        -ROT                    \ 7 3 5
                        .                       \ 7 3
                        .                       \ 7
                        .


        NIP     ( n1 n2 -- n2 )
                Removes the second element from the stack.
                This is equivalent to SWAP DROP.

                6 2 NIP .  will print 2

                        6                       \ 6
                        2                       \ 6 2
                        NIP                     \ 2
                        .


        2DUP    ( n1 n2 -- n1 n2 n1 n2 )
                Duplicates the top 2 elements on the stack.

                2 4 2DUP .S  will print 2 4 2 4


        2SWAP   ( n1 n2 n3 n4 -- n3 n4 n1 n2 )
                Interchanges the top two numbers on the stack with the
                third and fourth numbers on the stack.

                2 4 6 8 2SWAP .S  will print 6 8 2 4


        2DROP   ( n1 n2 -- )
                Removes the top two elements from the stack.


        PICK    ( n1 -- n2 )
                Duplicates the value at position n1 from the top of the
                stack (not counting n1).  The top of the stack corresponds
                to n1 equal to 0.

                0 PICK  is the same as DUP
                1 PICK  is the same as OVER

                2 4 6 8 2 PICK .S  will print 2 4 6 8 4


        ROLL    ( n -- )
                Rotate the value at position n (not counting n) to the
                top of the stack.  n must be greater than 0.

                1 ROLL  is the same as SWAP
                2 ROLL  is the same as ROT

                2 4 6 8 3 ROLL .S  will print 4 6 8 2







1.5  MORE FORTH WORDS

        MOD     ( n1 n2 -- n3 )
                Divides n1 by n2 and leaves the remainder n3 on the stack.

                8 3 MOD .  will print 2


        /MOD    ( n1 n2 -- n3 n4 )
                Divides n1 by n2 and leaves the quotient n4 on top of the
                stack and the remainder n3 as the second element on the
                stack.

                10 3 /MOD .S  will print 1 3


        MIN     ( n1 n2 -- n3 )
                Leaves the smaller of n1 and n2 on the stack.

                8 3 MIN .  will print 3


        MAX     ( n1 n2 -- n3 )
                Leaves the larger of n1 and n2 on the stack.

                8 3 MAX .  will print 8


        NEGATE  ( n1 -- n2 )
                Changes the sign of n1.

                8 NEGATE .  will print -8


        ABS     ( n1 -- n2 )
                Leaves the absolute value of n1 on the stack.

                -8 ABS .  will print 8


        2*      ( n1 -- n2 )
                Multiplies n1 by 2 by performing an arithmetic shift left.

                8 2* .  will print 16

                This is equivalent to 8 2 * but is faster.


        2/      ( n1 -- n2 )
                Divides n1 by 2 by performing an arithmetic shift right.

                8 2/ .  will print 4

                This is equivalent to 8 2 / but is faster.

        U2/     ( n1 -- n2 )
                Performs a 16-bit logical shift right.

                40000 U2/ .   will print 20000
                but  40000 2/ .  will print -12768


        8*      ( n1 -- n2 )
                Multiplies n1 by 8 by performing a 3-bit arithmetic shift
                left.

                7 8* . will print 56

                This is equivalent to 7 8 * but is faster.


        1+      ( n1 -- n2 )
                Increments the top of the stack by one.


        1-      ( n1 -- n2 )
                Decrements the top of the stack by one.


        2+      ( n1 -- n2 )
                Increments the top of the stack by two.


        2-      ( n1 -- n2 )
                Decrements the top of the stack by two.


        U/16    ( u -- u/16 )     \ u signifies an unsigned 16-bit integer
                Divides the unsigned integer u by 16 by performing a 4-bit
                logical shift right.



















1.6  COLON DEFINITIONS

        You can define your own Forth words, made up of other Forth words,
        by using the Forth word : (colon) in the following form:

                : <name>   --- --- --- --- ;

        where
                the colon : begins the definition
                <name> is the name of your Forth word
                --- --- are the Forth words making up you definition
                the semi-colon ; ends the definition.

        Examples:

        If you don't like the period to print the value of the top of the
        stack, you could redefine it to be == (We'll use the double equal
        sign because the single equal sign = is already a Forth word).

        Note: Paren ( is a Forth word that treats everything to the closing
              paren ) as a comment.  Therefore, there MUST be a space after
              the (.

comment;        \ the words comment: --- comment; have bracketed all of
                \ Lesson 1 up to this point.  When you type FLOAD LESSON1
                \ all of the words between comment: and comment; will be
                \ treated as a comment and ignored.  However, the following
                \ colon definitions will be compiled by loading them into
                \ the dictionary.  You can type them in one at a time by
                \ yourself from the keyboard, or you can just type
                \ FLOAD LESSON1.

: ==            ( n -- )        \ print the top value of the stack
                . ;

                \ Type in this colon definition and then try it by
                \ typing  5 7 + ==

: squared       ( n -- n**2 )   \ compute the square of n
                DUP * ;

                \ Try typing
                \       5 squared ==
                \       3 squared ==
                \       7 squared ==

: cubed         ( n -- n**3 )   \ compute the cube of n
                DUP                     \ n n
                squared                 \ n n**2
                * ;                     \ n**3

                \ Try typing
                \       3 cubed ==
                \       5 cubed ==
                \       10 cubed ==

comment:
        The following are two useful Forth words:

        CR      ( -- )     ( "carriage return" )
                Produces a "carriage return" and line feed on the screen.

        ."      ( -- )     ( "dot-quote" )
                Prints a string consisting of characters to closing ".
comment;
        \ Define the following words:

: bar           ( -- )          \ print a bar
                CR ." *****" ;

                \ Type bar

: post          ( -- )          \ print a post
                CR ." *"
                CR ." *" ;

                \ Type post

: C             ( -- )          \ print a C
                bar
                post
                post
                bar ;

                \ Type C

: E             ( -- )          \ print an E
                bar post
                bar post
                bar ;

                \ Type E

comment:
        Note that new Forth words are defined in terms of previously
        defined words.  This is the way Forth works.  New, more powerful
        words are continually being defined.  When you get done, your
        entire main program will be just one word.

        The words you define are stored in the Forth dictionary along with
        all the pre-defined Forth words.  They become part of the Forth
        language and are treated just like any other Forth word.  The Forth
        interpreter cannot tell the difference between words that you define
        and words that come as part of the language.  This means that every
        Forth application program is really a specialized language that is
        designed to solve a particular problem.





EXERCISE 1.1
        A rectangle can be defined by giving its top-left (t l) and
        bottom-right (b r) coordinates.  Let the x-coordinate increase
        from left to right and the y-coordinate increase from top to
        bottom.  Define three Forth words, AREA, CIRCUM and CENTER that
        will calculate the area, circumference and center of the rectangle
        given the top, left, bottom and right values on the stack as follows:

        AREA   ( t l b r -- area )

        CIRCUM   ( t l b r -- circum )

        CENTER   ( t l b r -- xc yc )

        Test your three words using the following two sets of values for
        top, left, bottom and right:

        top:    31      10
        left:   16      27
        bottom: 94     215
        right:  69     230

comment;