Benutzer-Werkzeuge

Webseiten-Werkzeuge


papierkorb:4th_lesson_4

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

papierkorb:4th_lesson_4 [2025-08-16 19:07] – ↷ Seite von projects:4th_lesson_4 nach papierkorb:4th_lesson_4 verschoben mkapapierkorb:4th_lesson_4 [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1
Zeile 1: Zeile 1:
-=== Lesson 4 === 
  
-<code> 
-\       Lesson 4 - Forth Decisions 
-\       The Forth Course 
-\       by Richard E. Haskell 
-\          Dept. of Computer Science and Engineering 
-\          Oakland University, Rochester, MI 48309 
-comment: 
- 
- 
-                              Lesson 4 
- 
-                           FORTH DECISIONS 
- 
-                4.1  BRANCHING INSTRUCTIONS AND LOOPS           4-2 
- 
-                4.2  CONDITIONAL WORDS                          4-3 
- 
-                4.3  FORTH LOGICAL OPERATORS                    4-4 
- 
-                4.4  THE IF STATEMENT                           4-5 
- 
-                4.5  THE DO LOOP                                4-6 
- 
-                4.6  THE UNTIL LOOP                             4-10 
- 
-                4.7  THE WHILE LOOP                             4-11 
- 
-                     EXERCISES                                  4-12 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-4.1  BRANCHING INSTRUCTIONS AND LOOPS 
- 
-        All computer languages must have some way of producing a conditional 
-        branch (if...then) and implementing loops.  Forth uses the following 
-        well-structured constructs: 
- 
-        IF ... ELSE ... THEN 
- 
-        DO ... LOOP 
- 
-        BEGIN ... UNTIL 
- 
-        BEGIN ... WHILE ... REPEAT 
- 
-        BEGIN ... AGAIN 
- 
-        These instructions work somewhat differently than they do in other 
-        languages.  The words IF, UNTIL and WHILE are Forth words that 
-        expect a true/false flag to be on top of the stack when the words 
-        are executed.  A false flag has a value of 0.  A true flag has a 
-        value of -1. 
- 
-        F-PC defines the two constants 
- 
-                -1 CONSTANT  TRUE 
-                 0 CONSTANT  FALSE 
- 
-        The flag may be generated in any way, but the usual way is to use 
-        some type of conditional expression that leaves a flag on the stack. 
- 
-        We will first look at Forth conditional words and then give examples 
-        of each of the branching and looping statements shown above. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-4.2  CONDITIONAL WORDS -- true/false flags 
- 
-        The following Forth conditional words produce a true/false flag: 
- 
-        <       ( n1 n2 -- f )          ( "less-than" ) 
-                flag, f, is true if n1 is less than n2. 
- 
-        >       ( n1 n2 -- f )          ( "greater-than" ) 
-                flag, f, is true if n1 is greater than n2. 
- 
-        =       ( n1 n2 -- f )          ( "equals" ) 
-                flag, f, is true if n1 is equal to n2. 
- 
-        <>      ( n1 n2 -- f )          ( "not-equal" ) 
-                flag, f, is true if n1 is not equal to n2. 
- 
-        <=      ( n1 n2 -- f )          ( "less-than or equal" ) 
-                flag, f, is true if n1 is less than or equal to n2. 
- 
-        >=      ( n1 n2 -- f )          ( "greater-than or equal" ) 
-                flag, f, is true if n1 is greater than or equal to n2. 
- 
-        0<      ( n -- f )              ( "zero-less" ) 
-                flag, f, is true if n is less than zero (negative). 
- 
-        0>      ( n -- f )              ( "zero-greater" ) 
-                flag, f, is true if n is greater than zero (positive). 
- 
-        0=      ( n -- f )              ( "zero-equals" ) 
-                flag, f, is true if n is equal to zero. 
- 
-        0<>     ( n -- f )              ( "zero-not-equal" ) 
-                flag, f, is true if n is not equal to zero. 
- 
-        0<    ( n -- f )              ( "zero-less-than or equal" ) 
-                flag, f, is true if n is less than or equal to zero. 
- 
-        0>    ( n -- f )              ( "zero-greater-than or equal" ) 
-                flag, f, is true if n is greater than or equal to zero. 
- 
-        The following conditional words compare two unsigned numbers on 
-        the stack. 
- 
-        U<      ( u1 u2 -- f )          ( "U-less-than" ) 
-                flag, f, is true if u1 is less than u2. 
- 
-        U>      ( u1 u2 -- f )          ( "U-greater-than" ) 
-                flag, f, is true if u1 is greater than u2. 
- 
-        U<    ( u1 u2 -- f )          ( "U-less-than or equal" ) 
-                flag, f, is true if u1 is less than or equal to u2. 
- 
-        U>    ( u1 u2 -- f )          ( "U-greater-than or equal" ) 
-                flag, f, is true if u1 is greater than or equal to u2. 
- 
- 
-4.3  FORTH LOGICAL OPERATORS 
- 
-        Some Forths have the word NOT which reverses the truth value of the 
-        flag on top of the stack.  In F-PC the word NOT performs a one's 
-        complement of the word on top of the stack.  As long as TRUE is 
-        -1 (hex FFFF) then NOT TRUE will be FALSE.  You must be careful 
-        because any non-zero value may, at times, be treated as a true flag. 
-        The one's complement of anything other than hex FFFF will not 
-        produce zero (FALSE).  You can always complement any flag by using 
-        the comparison word 0=. 
- 
-        In addition to the logical operator NOT, Forth also has the following 
-        binary logical operators: 
- 
- 
-        AND     ( n1 n2 -- and ) 
-                Leaves n1 AND n2 on top of the stack. 
- 
-                This is a bitwise AND.  For example, if you type 
- 
-                        255 15 AND      ( mask lower 4 bits ) 
- 
-                the value 15 will be left on top of the stack. 
- 
- 
-        OR      ( n1 n2 -- or ) 
-                Leaves n1 OR n2 on top of the stack. 
- 
-                This is a bitwise OR.  For example, if you type 
- 
-                        9 3 OR 
- 
-                the value 11 will be left on top of the stack. 
- 
- 
-        XOR     ( n1 n2 -- xor ) 
-                Leaves n1 XOR n2 on top of the stack. 
- 
-                This is a bitwise XOR.  For example, if you type 
- 
-                        240 255 XOR     ( Hex F0 XOR FF = 0F ) 
- 
-                the value 15 will be left on top of the stack. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-4.4  THE IF STATEMENT 
- 
-        The Forth IF statement works somewhat differently than an IF 
-        statement in other languages.  A typical IF ... THEN ... ELSE 
-        statement that you may be familiar with works like this: 
- 
-              IF  <cond>  THEN  <true statements>  ELSE  <false statements> 
- 
-        In Forth the IF statement works like this: 
- 
-              <cond>  IF  <true statements>  ELSE  <false statements>  THEN 
- 
-        Note that a true/false flag must be on top of the stack when the 
-        IF word is executed.  If a true flag is on top of the stack, then 
-        the <true statements> are executed.  If a false flag is on top of 
-        the stack, then the <false statements> are executed.  After the 
-        <true statements> or <false statements> are executed, the words 
-        following THEN are executed.  The ELSE clause is optional. 
- 
-        The IF word must be used within a colon definition. 
-        As an example, define the following words: 
-comment; 
- 
-        : iftest        ( f -- ) 
-                        IF 
-                           CR ." true statements" 
-                        THEN 
-                        CR ." next statements" ; 
- 
-        : if.else.test  ( f -- ) 
-                        IF 
-                           CR ." true statements" 
-                        ELSE 
-                           CR ." false statements" 
-                        THEN 
-                        CR ." next statements" ; 
- 
-comment: 
- 
-        Then type 
- 
-                TRUE iftest 
- 
-                FALSE iftest 
- 
-                TRUE if.else.test 
- 
-                FALSE if.else.test 
- 
- 
- 
- 
- 
- 
- 
- 
-4.5  THE DO LOOP 
- 
-        The Forth DO loop must be defined inside a colon definition. 
-        To see how it works, define the following word: 
-comment; 
- 
-        : dotest        ( limit ix -- ) 
-                        DO 
-                           I . 
-                        LOOP ; 
- 
-comment: 
- 
-        Then if you type 
- 
-                5 0 dotest 
- 
-        the values 0 1 2 3 4 will be printed on the screen.  Try it. 
- 
-        The DO loop works as follows.  The word DO takes the top two values 
-        from the top of the parameter stack and moves them to the return 
-        stack.  At this point the two values are no longer on the parameter 
-        stack.  The word LOOP adds one to the index value and compares the 
-        result to the limit value.  If the incremented index value is less 
-        than the limit value, then a branch is taken to the word following 
-        DO.  If the incremented index value is equal to the limit value, 
-        then the two values are removed from the return stack and the word 
-        following LOOP is executed.  We will take a close look at how the 
-        DO loop is actually implemented in Lesson 9. 
- 
-        The Forth word I copies the index value from the return stack to the 
-        top of the parameter stack.  Therefore, the execution of the above 
-        example can be illustrated as follows: 
- 
-                        5               \ 5 
-                        0               \ 5 0 
-                        DO 
-                                      \ ix    ( ix = 0,1,2,3,4) 
-                           . 
-                        LOOP 
- 
-        Note that the limit value must be one greater than the largest 
-        index value you want.  For example, 
- 
-                11 1 DO 
-                       I . 
-                     LOOP 
- 
-        will print out the values 
- 
-                1 2 3 4 5 6 7 8 9 10 
- 
- 
- 
-The +LOOP Word 
- 
-        The index in the Forth DO loop can be incremented by a value other 
-        than 1 by using the word +LOOP instead of LOOP.  To see how this 
-        works, define the following word: 
-comment; 
- 
-        : looptest      ( limit ix -- ) 
-                        DO 
-                           I . 
-                        2 +LOOP ; 
-comment: 
-        Then if you type 
- 
-                5 0 looptest 
- 
-        the values 0 2 4 will be printed on the screen.  Try it. 
- 
-        The word +LOOP takes the value from the top of the parameter stack 
-        and adds it to the index value on the return stack.  It then behaves 
-        the same as LOOP, branching back to the word following DO as long as 
-        the incremented index value is less than the limit value (if the 
-        increment value is positive).  If the increment value is negative, 
-        then the loop will exit when the index value becomes less than the 
-        limit value.  For example, if you define 
-comment; 
- 
-        : neglooptest   ( limit ix -- ) 
-                        DO 
-                           I . 
-                        -1 +LOOP ; 
-comment: 
-        and then type 
- 
-                0 10 neglooptest 
- 
-        the values 10 9 8 7 6 5 4 3 2 1 0 will be printed on the screen. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-Nested Loops - The Word J 
- 
-        Forth DO loops can be nested.  When you do this two pairs of 
-        index/limit values are moved to the return stack.  The word I 
-        copies the index value of the inner loop from the return stack 
-        to the parameter stack, and the word J copies the index value of 
-        the outer loop from the return stack to the parameter stack. 
-        As an example of nested loops, define the following word: 
-comment; 
- 
-        : 1.to.9        ( -- ) 
-                        8 1 DO 
-                             CR 
-                             3 0 DO 
-                                  J I + . 
-                             LOOP 
-                        3 +LOOP ; 
-comment: 
-        If you execute this word by typing 1.to.9 the following will be 
-        printed: 
-                        1 2 3 
-                        4 5 6 
-                        7 8 9 
- 
-        Do you see why?  Try it. 
- 
-        Nested loops are used much less frequently in Forth than in other 
-        languages.  It is usually better to define smaller words that 
-        contain only a single DO loop, and then call this word within 
-        another loop. 
- 
- 
- 
-The Word LEAVE 
- 
-        The Forth word LEAVE can be used to exit a DO loop prematurely. 
-        It is normally used within an IF statement inside the DO loop. 
-        The word LEAVE causes the immediate exit from the DO loop.  (The 
-        address of the word following LOOP has been stored as the third 
-        word on the return stack.)  A related word ?LEAVE (flag --) will 
-        exit a DO loop if the flag on top of the stack is true.  This can 
-        avoid the need for an IF statement. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-        As an example, suppose you want to define a word called find.n 
-        that will search for a specific value in a table and return the 
-        index of the value (i.e. its position in the table) under a true 
-        flag if the value is found; otherwise, a false flag will be left 
-        on top of the stack.  The Forth statement 
-comment; 
-                CREATE table 50 , 75 , 110 , 135 , 150 , 300 , 600 , 
-comment: 
-        will create the following table in the code segment. 
- 
-                                table 
-                      ________        | 
-                  CFA | CODE | <------| 
-                      |------| 
-                  PFA |  50  | 0 
-                      |------| 
-                      |  75  | 1 
-                      |------| 
-                      |  110 | 2 <---index, ix 
-                      |------| 
-                      |  135 | 3 
-                      |------| 
-                      |  150 | 4 
-                      |------| 
-                      |  300 | 5 
-                      |------| 
-                      |  600 | 6 <---imax-1 
-                      |------| 
-                  Code Segment ?CS: 
- 
-        The number of values in the table is imax (7 in this case).  The 
-        value to be searched for in n.  These two values will be on the 
-        stack when find.n is executed.  The following is a definition of 
-        find.n. 
-comment; 
-        : find.n        ( imax n -- ff | index tf ) 
-                        0 SWAP ROT              \ 0 n imax 
-                        0 DO                    \ 0 n 
-                           DUP I table          \ 0 n n ix pfa 
-                           SWAP 2* +            \ 0 n n pfa+2*ix 
-                           @ =                  \ 0 n f 
-                           IF                   \ 0 n 
-                              DROP I TRUE       \ 0 ix tf 
-                              ROT LEAVE         \ ix tf 0 
-                           THEN 
-                        LOOP                    \ 0 n 
-                        DROP ;                  \ 0 | ix tf 
-comment: 
-        Study this definition until you see how it works.  In general, 
-        when using a DO loop the stack picture should be the same after 
-        executing DO as it is after executing LOOP.  You will often need 
-        to DUP some stack value(s) inside a DO loop and then DROP something 
-        after you leave the loop.  Note in this case how the ROT before 
-        LEAVE is used to set up the stack so that the final DROP will leave 
-        the true flag on top of the stack. 
- 
-4.6  THE UNTIL LOOP 
- 
-        The Forth UNTIL loop must be used within a colon definition. 
-        The form of the UNTIL loop is 
- 
-                BEGIN <Forth statements> <flag> UNTIL 
- 
-        If the <flag> is FALSE, the program branches to the word following 
-        BEGIN.  If the <flag> is TRUE, the program continues with the word 
-        following UNTIL. 
- 
-        The following two F-PC words can sense and read the keyboard. 
- 
-        KEY?    ( -- flag ) 
-                produces a TRUE flag if you have pressed a key. 
- 
-        KEY     ( -- char ) 
-                waits for a key to be pressed and leaves the ASCII code 
-                of the key on the stack. 
- 
-        The F-PC word 
- 
-        EMIT    ( char -- ) 
-                will print on the screen the character whose ASCII code 
-                is on top of the stack. 
- 
-        Define the word 
-comment; 
-                : dowrite       ( -- ) 
-                                BEGIN 
-                                   KEY          \ char 
-                                   DUP EMIT     \ print on screen 
-                                   13 =         \ if equal to CR 
-                                UNTIL ;         \ quit 
-comment: 
-        Executing this word will write all characters you type on the screen 
-        until you press the <Enter> key (ASCII code = 13). 
- 
-        Note that the word UNTIL removes the flag from the stack. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-4.7  THE WHILE LOOP 
- 
-        The Forth WHILE loop must be used within a colon definition. 
-        The form of the WHILE loop is 
- 
-                BEGIN  <words>  <flag> WHILE  <words>  REPEAT 
- 
-        If the <flag> is TRUE, the words between WHILE and REPEAT are 
-        executed, and then a branch is taken to the word following BEGIN. 
-        If the <flag> is FALSE, the program branches to the word following 
-        REPEAT. 
- 
-        As an example, consider the following algorithm to compute the 
-        factorial of n. 
- 
-                x = 1 
-                i = 2 
-                DO WHILE i <= n 
-                    x = x * i 
-                    i = i + 1 
-                ENDDO 
-                factorial = x 
- 
-        The following Forth word will compute this factorial. 
-comment; 
- 
-        : factorial     ( n -- n! ) 
-                        1 2 ROT                 \ x i n 
-                        BEGIN                   \ x i n 
-                           2DUP <=              \ x i n f 
-                        WHILE                   \ x i n 
-                           -ROT TUCK            \ n i x i 
-                           * SWAP               \ n x i 
-                           1+ ROT               \ x i n 
-                        REPEAT                  \ x i n 
-                        2DROP ;                 \ x 
-comment: 
- 
-        Note that the stack arrangement must be the same at the words 
-        BEGIN and REPEAT for the WHILE loop to work properly.  Note also 
-        that whereas the algorithm given above uses the three variables 
-        x, i and n, the Forth implementation uses no variables at all! 
-        This is characteristic of Forth.  You will find that you use far 
-        fewer variables than in other languages.  Test this definition of 
-        of factorial by typing 
- 
-                3 factorial . 
-                4 factorial . 
-                0 factorial . 
- 
- 
- 
- 
- 
-EXERCISE 4.1 
- 
-        The Fibonacci sequence is a sequence of numbers in which each 
-        number (starting with the third) is the sum of the two immediately 
-        preceding numbers.  Thus, the beginning of the sequence looks like 
-        this. 
-                1 1 2 3 5 8 13 21 34 
- 
-        Define a Forth word called 
- 
-                fib     ( n -- ) 
- 
-        that will print the fibonacci sequence for all values less than n. 
-        Test your word by typing 
- 
-                1000 fib 
- 
- 
-EXERCISE 4.2 
- 
-        Create a table called weights that contains the following values: 
- 
-                75 135 175 115 220 235 180 167 
- 
-        Define a Forth word called 
- 
-                heaviest        ( pfa -- max.value ) 
- 
-        that will put the maximum value from the table on the top of the 
-        stack.  If you type 
- 
-                weights heaviest . 
- 
-        the value 235 should be printed on the screen. 
-comment; 
- 
-</code> 
papierkorb/4th_lesson_4.1755364027.txt.gz · Zuletzt geändert: 2025-08-16 19:07 von mka