⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lessons.txt

📁 eForth is a small portable Forth design for a wide range of microprocessors. This is the first imple
💻 TXT
📖 第 1 页 / 共 2 页
字号:
: MULTIPLY ( -- )
        CR CR 6 SPACES
        1 11
        FOR     DUP 4 .R 1 +
        NEXT DROP 
        1 11
        FOR     DUP ONEROW 1 +
        NEXT DROP
        ;

( Type MULTIPLY to print the multiplication table )


( Example 11.  Calendars )

( Print weekly calendars for any month in any year. )
DECIMAL

VARIABLE JULIAN                         ( 0 is 1/1/1950, good until 2050 )
VARIABLE LEAP                           ( 1 for a leap year, 0 otherwise. )
( 1461 CONSTANT 4YEARS                  ( number of days in 4 years )

: YEAR ( YEAR --, compute Julian date and leap year )
        DUP
        1949 - 1461 4 */MOD             ( days since 1/1/1949 )
        365 - JULIAN !                  ( 0 for 1/1/1950 )
        3 =                             ( modulus 3 for a leap year )
        IF 1 ELSE 0 THEN                ( leap year )
        LEAP !
        DUP 2000 =                      ( 2000 is not a leap year )
        IF 0 LEAP ! THEN
        2001 <                          ( correction due to 2000 )
        IF ELSE -1 JULIAN +! THEN
        ;

: FIRST ( MONTH -- 1ST, 1st of a month from Jan. 1 )
        DUP 1 =
        IF DROP 0 EXIT THEN             ( 0 for Jan. 1 )
        DUP 2 =
        IF DROP 31 EXIT THEN            ( 31 for Feb. 1 )
        DUP 3 =
        IF DROP 59 LEAP @ + EXIT THEN   ( 59/60 for Mar. 1 )
        4 - 30624 1000 */
        90 + LEAP @ +                   ( Apr. 1 to Dec. 1 )
        ;

: STARS 60 FOR 42 EMIT NEXT ;           ( form the boarder )

: HEADER ( -- )                         ( print title bar )
        CR STARS CR 
        ."      SUN     MON     TUE     WED     THU     FRI     SAT"
        CR STARS CR                     ( print weekdays )
        ;

: BLANKS ( MONTH -- )                   ( skip days not in this month )
        FIRST JULIAN @ +                ( Julian date of 1st of month )
        7 MOD 8 * SPACES ;              ( skip colums if not Sunday   )

: DAYS ( MONTH -- )                     ( print days in a month )
        DUP FIRST                       ( days of 1st this month )
        SWAP 1 + FIRST                  ( days of 1st next month )
        OVER - 1 -                      ( loop to print the days )
        1 SWAP                          ( first day count -- )
        FOR  2DUP + 1 -
                JULIAN @ + 7 MOD        ( which day in the week? )
                IF ELSE CR THEN         ( start a new line if Sunday )
                DUP  8 U.R              ( print day in 8 column field )
                1 +
        NEXT
        2DROP ;                         ( discard 1st day in this month )

: MONTH ( N -- )                        ( print a month calendar )
        HEADER DUP BLANKS               ( print header )
        DAYS CR STARS CR ;              ( print days   )

: JANUARY       YEAR 1 MONTH ;
: FEBRUARY      YEAR 2 MONTH ;
: MARCH         YEAR 3 MONTH ;
: APRIL         YEAR 4 MONTH ;
: MAY           YEAR 5 MONTH ;
: JUNE          YEAR 6 MONTH ;
: JULY          YEAR 7 MONTH ;
: AUGUST        YEAR 8 MONTH ;
: SEPTEMBER     YEAR 9 MONTH ;
: OCTOBER       YEAR 10 MONTH ;
: NOVEMBER      YEAR 11 MONTH ;
: DECEMBER      YEAR 12 MONTH ;

( To print the calender of April 1999, type:
        1999 APRIL
)



( Example 12.      Sines and Cosines

Sines and cosines of angles are among the most often encountered
transdential functions, useful in drawing circles and many other
different applications.  They are usually computed using floating
numbers for accuracy and dynamic range.  However, for graphics
applications in digital systems, single integers in the range from
-32768 to 32767 are sufficient for most purposes.  We shall
study the computation of sines and cosines using the single
integers.

The value of sine or cosine of an angle lies between -1.0 and +1.0.
We choose to use the integer 10000 in decimal to represent 1.0
in the computation so that the sines and cosines can be represented
with enough precision for most applications.  Pi is therefore
31416, and 90 degree angle is represented by 15708.  Angles
are first reduced in to the range from -90 to +90 degrees,
and then converted to radians in the ranges from -15708 to
+15708.  From the radians we compute the values of sine and
cosine.

The sines and cosines thus computed are accurate to 1 part in
10000.  This algorithm was first published by John Bumgarner
in Forth Dimensions, Volume IV, No. 1, p. 7.

31415 CONSTANT PI
10000 CONSTANT 10K )
VARIABLE XS                             ( square of scaled angle )

: KN ( n1 n2 -- n3, n3=10000-n1*x*x/n2 where x is the angle )
        XS @ SWAP /                     ( x*x/n2 )
        NEGATE 10000 */                   ( -n1*x*x/n2 )
        10000 +                           ( 10000-n1*x*x/n2 )
        ;

: (SIN) ( x -- sine*10K, x in radian*10K )
        DUP DUP 10000 */                  ( x*x scaled by 10K )
        XS !                            ( save it in XS )
        10000 72 KN                       ( last term )
        42 KN 20 KN 6 KN                ( terms 3, 2, and 1 )
        10000 */                          ( times x )
        ;

: (COS) ( x -- cosine*10K, x in radian*10K )
        DUP 10000 */ XS !                 ( compute and save x*x )
        10000 56 KN 30 KN 12 KN 2 KN      ( serial expansion )
        ;

: SIN ( degree -- sine*10K )
        31415 180 */                       ( convert to radian )
        (SIN)                           ( compute sine )
        ;

: COS ( degree -- cosine*10K )
        31415 180 */
        (COS)
        ;


( To test the routines, type:

        90 SIN .                         9999 
        45 SIN .                         7070 
        30 SIN .                         5000 
         0 SIN .                            0 
        90 COS .                            0 
        45 COS .                         7071 
         0 COS .                         10000 )



( Example 13.      Square Root

There are many ways to take the square root of an integer.  The
special routine here was first discovered by Wil Baden.  Wil
used this routine as a programming challenge while attending
a FORML Conference in Taiwan, 1984.

This algorithm is based on the fact that the square of n+1 is equal
to the sum of the square of n plus 2n+1.  You start with an 0 on
the stack and add to it 1, 3, 5, 7, etc., until the sum is greater
than the integer you wished to take the root.  That number when
you stopped is the square root.
)

: SQRT ( n -- root )
        65025 OVER U<                   ( largest square it can handle)
        IF DROP 255 EXIT THEN           ( safety exit )
        >R                              ( save sqaure )
        1 1                             ( initial square and root )
        BEGIN                           ( set n1 as the limit )
                OVER R@ U<              ( next square )
        WHILE
                DUP CELLS 1 +           ( n*n+2n+1 )
                ROT + SWAP
                1 +                     ( n+1 )
        REPEAT
        SWAP DROP
        R> DROP
        ;


( Example 14.      Radix for Number Conversions )

DECIMAL

( : DECIMAL       10 BASE ! ; )
( : HEX           16 BASE ! ; )
: OCTAL         8 BASE !  ;
: BINARY        2 BASE !  ;

( Try converting numbers among different radices:

        DECIMAL 12345 HEX U.
        HEX ABCD DECIMAL U.
        DECIMAL 100 BINARY U.
        BINARY 101010101010 DECIMAL U.

Real programmers impress on novices by carrying a HP calculator
which can convert numbers between decimal and hexadecimal.  A
Forth computer has this calculator built in, besides other functions.
)



( Example 15.      ASCII Character Table )

: CHARACTER ( n -- )
        DUP EMIT HEX DUP 3 .R
        OCTAL DUP 4 .R
        DECIMAL 3 .R
        2 SPACES
        ;

: LINE ( n -- )
        CR
        5 FOR   DUP CHARACTER
                16 +
        NEXT
        DROP ;

: TABLE ( -- )
        32
        15 FOR  DUP LINE
                1 +
        NEXT
        DROP ;



( Example 16.  Random Numbers

Random numbers are often used in computer simulations and computer
games.  This random number generator was published in Leo Brodie's
'Starting Forth'.
)

VARIABLE RND                            ( seed )
HERE RND !                              ( initialize seed )

: RANDOM ( -- n, a random number within 0 to 65536 )
        RND @ 31421 *                   ( RND*31421 )
        6927 +                          ( RND*31421+6926, mod 65536)
        DUP RND !                       ( refresh he seed )
        ;

: CHOOSE ( n1 -- n2, a random number within 0 to n1 )
        RANDOM UM*                      ( n1*random to a double product)
        SWAP DROP                       ( discard lower part )
        ;                                ( in fact divide by 65536 )

( To test the routine, type

        100 CHOOSE .
        100 CHOOSE .
        100 CHOOSE .

and varify that the results are randomly distributed betweem 0 and
99 . )


( Example 17.      Guess a Number )

: GetNumber ( -- n )
        BEGIN
                CR ." Enter a Number: " ( show message )
                QUERY BL WORD NUMBER?   ( get a string )
        UNTIL                           ( repeat until a valid number )
        ;

( With this utility instruction, we can write a game 'Guess a Number.' )

: InitialNumber ( -- n , set up a number for the player to guess )
        CR CR CR ." What limit do you want?"
        GetNumber                       ( ask the user to enter a number )
        CR ." I have a number between 0 and " DUP .
        CR ." Now you try to guess what it is."
        CR
        CHOOSE                          ( choose a random number )
        ;                               ( between 0 and limit )

: Check ( n1 -- , allow player to guess, exit when the guess is correct )
        BEGIN   CR ." Please enter your guess."
                GetNumber
                2DUP =                  ( equal? )
                IF      2DROP           ( discard both numbers )
                        CR ." Correct!!!"
                        EXIT
                THEN
                OVER <
                IF      CR ." Too low."
                ELSE    CR ." Too high!"
                THEN    CR
        0 UNTIL                         ( always repeat )
        ;

: Greet ( -- )
        CR CR CR ." GUESS A NUMBER"
        CR ." This is a number guessing game.  I'll think"
        CR ." of a number between 0 and any limit you want."
        CR ." (It should be smaller than 32000.)"
        CR ." Then you have to guess what it is."
        ;

: GUESS ( -- , the game )
        Greet
        BEGIN   InitialNumber                   ( set initial number)
                Check                           ( let player guess )
                CR CR ." Do you want to play again? (Y/N) "
                KEY                             ( get one key )
                32 OR 110 =                     ( exit if it is N or n )
        UNTIL
        CR CR ." Thank you.  Have a good day."  ( sign off )
        CR
        ;


( Type 'GUESS' will initialize the game and the computer will entertain
a user for a while.  Note the use of the indefinite loop structure:

        BEGIN <repeat-clause> [ f ] UNTIL

You can jump out of the infinite loop by the instruction EXIT, which
skips all the instructions in a Forth definition up to ';', which
terminates this definition and continues to the next definition. )






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -