home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / FORTH_86.ZIP / CELCIUS.WLK < prev    next >
Text File  |  1993-12-09  |  11KB  |  314 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.    4th_86 version 4.01           CELCIUS.WLK                        page  1
  8.    
  9.    
  10.  
  11.                 ( November  1993 - 4th_86 version 4.01 - MFB )
  12.  
  13.           While the functional source CEL4.4TH is provided -- this note
  14.    leads you through the process of developing the code yourself.
  15.  
  16.           Let's suppose we want to print on screen a table comparing
  17.    Celsius and Fahrenheit temperatures. This is in fact the first example
  18.    in Kernighan & Richie's book "The C Programming Language".
  19.  
  20.           The first step is to create a file on disk to develop the code in.
  21.    We don't want to type code in [ as with a BASIC interpreter ] directly
  22.    from keyboard to memory and risk losing it all if a bug in the code
  23.    "blows up" the system.
  24.  
  25.           Let's name the file CEL.4TH [ **not** CEL4.4TH which is already
  26.    on disk ]. We will need to use the version of 4th_86 which contains
  27.    floating point routines -- 4th_86FP.COM
  28.  
  29.           Fire up 4th_86FP and then type  [ in upper or lower case - it
  30.                                                doesn't matter which ]
  31.                    using cel.4th
  32.                    : strt ;
  33.                    redit
  34.  
  35.      You should now have left 4th_86 and be in your editor with a blank
  36.    screen. Start to enter some code
  37.  
  38.                    forget strt
  39.                    : strt ;
  40.                    off redefine
  41.                    on printload
  42.                    using cel.4th
  43.                                  [ redundant here -- but it can be useful
  44.                                       in case of mishap ]
  45.  
  46.           To make life simple at the initial stages -- let's create storage
  47.    locations for the variables we may need -- and define any constants we
  48.    may need. Once it is working we can "clean it up" and maybe get rid of a
  49.    lot of the intermediate storage -- as well as speed things up a bit.
  50.  
  51.           32 const lower           ( lower value of Fahrenheit range )
  52.           220 const upper          ( higher value of Fahrenheit range )
  53.           15 const step            ( incrememnt between adjacent table
  54.                                                                 values )
  55.  
  56.    All the above are 16 bit [ single precision ] integers. They are also
  57.    decimal by default.
  58.  
  59.     If we had wanted double precision we could have written ,32 ,const lower
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.    4th_86 version 4.01           CELCIUS.WLK                        page  2
  67.    
  68.    
  69.    If we had wanted floating point we'd have written 32.0 ,const lower --
  70.    because floating point numbers are stored in double precision format.
  71.  
  72.    Although our answers will be floating point -- we chose the input
  73.    parameters as integer because we need a  DO -- LOOP construct -- or a
  74.    REPEAT -- WHILE -- ENDWHILE construct  and we can not do that other than
  75.    in integer steps.
  76.  
  77.     The first thing we must do therefore is define a word which will convert
  78.    single precision integer values into floating point values. Let's call
  79.    this word SFLOAT
  80.  
  81.    word 1
  82.    %%%%%%
  83.                 : sfloat  double  float  ;
  84.  
  85.     The words double and float are built into 4th_86.
  86.  
  87.      Now comes the salient benefit of Forth as a language. We have defined
  88.    our first word in building a pyramid -- we must test -- ie debug it to
  89.    make sure it works BEFORE we ever go on to define other words or use this
  90.    one as a "building brick".
  91.  
  92.           type 32 sfloat f.        [ note that f. means print the top stack
  93.                                       value as a floating point number ]
  94.  
  95.     Let's try something more critical
  96.  
  97.           type   22 sfloat 7 sfloat f/ f.
  98.  
  99.  
  100.    Of course we didn't get any answers -- because we aren't in 4th_86. We're
  101.    in the editor.
  102.  
  103.           Exit from the editor and you should see the file load into 4th_86
  104.    displaying the text -- and printing the answers to the last two "direct"
  105.    statements.
  106.  
  107.           We can now type in further debug tests
  108.  
  109.           3.14159 7 sfloat   f*   f.
  110.  
  111.           If we are satisfied that SFLOAT works properly we can carry on and
  112.    define another word which uses it.
  113.  
  114.           type REDIT and you should be back in the editor
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.    4th_86 version 4.01           CELCIUS.WLK                        page  3
  122.    
  123.    
  124.  
  125.      We want to multiply our fahrenheit values by 5 and divide by 9 --
  126.    after we have subtracted 32 from each one. Clearly it would be wasteful
  127.    to have to calculate 5 divided by 9 for every entry. We want to do it
  128.    once -- and store the answer as a constant. The answer will not be an
  129.    integer even though the Fahrenheit values are integers. So -- let's
  130.    decide to use SFLOAT to convert the fahrenheit values to floating point
  131.    -- calculate 5.0 divided by 9.0 as floating point and subtract 32.0 as
  132.    floating point.
  133.  
  134.           DATA[ 0 ] fahr           ( single precision integer variable )
  135.           DATA[ 0.0 ] celsius      ( float variable )
  136.           DATA[ 0.0 ] scle         ( float variable equal to 5.0 / 9.0 ]
  137.  
  138.    word 2
  139.    %%%%%%%
  140.                  : SSCLE  5.0  9.0  f/  scle  ,!  ;
  141.  
  142.           F/ is floating point divide
  143.           ,! is a double precision ( or floating point ) store.
  144.  
  145.     We don't want to get involved in a DO .. LOOP construct at this stage.
  146.    Let's stick to one single fahrenheit value and see if we can get the
  147.    correct centigrade value from it.
  148.  
  149.           But first let's exit the editor again to test SSCLE
  150.  
  151.           when you are back in 4th_86 with your source loaded,
  152.  
  153.           type  SSCLE ( which should load the value of 5.0 / 9.0 into SCLE )
  154.  
  155.           and then type SCLE ,@ f.  to make sure we have actually stored
  156.                                                            the
  157.                  correct quotient
  158.  
  159.    Now return to the editor with REDIT and let's defibe a word CALCULATE
  160.  
  161.    word 3
  162.    %%%%%%
  163.                 : CALCULATE fahr @ sfloat
  164.                        32.0   f-
  165.                        scle  ,@  f*
  166.                        celsius  ,!  ;
  167.  
  168.        To test this we exit the editor again an type something such as
  169.  
  170.              212  fahr  !   calculate  celsius  ,@  f.
  171.  
  172.           which should print on screen the answer 100.00
  173.  
  174.     now REDIT back to the editor again.
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.    4th_86 version 4.01           CELCIUS.WLK                        page  4
  182.    
  183.    
  184.           It's bad Forth programming to write very complicated and lengthy
  185.    definitions. What we should strive for is lots of short simple [ but
  186.    meaningful ] words that we build together into more complicated
  187.    consttructs. Let's therefore take care of incrementing FAHR at each point
  188.    in the loop
  189.  
  190.     word 4
  191.     %%%%%%%
  192.           : INFAH  fahr  @  step  +  fahr !  ;
  193.  
  194.           Probably no need to test this one immediately -- let's define
  195.    another word and then do a test.
  196.  
  197.     word 5
  198.     %%%%%%%
  199.  
  200.           : ANS   tab  tab  fahr     @  .
  201.                   tab  tab  celsius  ,@  f.   crlf  ;
  202.  
  203.           The words TAB and CRLF are in fact part of 4th_86 vocabulary
  204.  
  205.     word 6
  206.     %%%%%%
  207.  
  208.           : CEL4  sscle           ( to calculate and store  5.0 / 9.0 )
  209.                lower fahr !            ( initial value )
  210.                    repeat
  211.                            upper fahr @ >=   ( test for upper limit )
  212.                    while                      ( not >= upper limit )
  213.                            calculate  ( evalauate celsius value and store )
  214.                             ans        ( print out two values on one line )
  215.                            infah        ( increment for next loop )
  216.                    endwhile
  217.                            lower   fahr  !  ( just to be tidy  )
  218.               ;
  219.  
  220.       Now is the time to exit the editor and test CEL4. It should print out
  221.    the required table of values. If it doesn't we'll have to work back and
  222.    check ANS and INFAH.
  223.  
  224.           If that still fails we'll have to break CEL4 down into smaller
  225.    sub-words for testing --- or use the DEBUG and TRACE facilities 4th_86
  226.    provides.
  227.  
  228.           All we have to add now is routines to print a heading and format
  229.    the display the way we want it.
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.    4th_86 version 4.01           CELCIUS.WLK                        page  5
  237.    
  238.    
  239.    Revision of code
  240.    ================
  241.  
  242.           It was inefficient to store the loop values in FAHR and CELSIUS,
  243.    and almost immediately retrieve them again for incrementing and/or
  244.    printing. It would have been faster and neater to keep them in memory --
  245.    specifically stored on the stack.
  246.  
  247.           This is one of the most difficult aspects of Forth for beginners -
  248.    - to know at each step just what remains on the stack -- how deep in the
  249.    parameter you want at any given time is -- and how to get it to the top
  250.    of the stack when you want to use it. This needs stack manipulation words
  251.    such as SWAP, ROT, OVER, DUP etc.
  252.  
  253.           Not only is it difficult for the programmer -- it makes the code
  254.    extremely difficult to read when you find complicated stack manipulations
  255.    and aren't really sure just what is being "retrieved" or thrown away as
  256.    redundant.
  257.  
  258.           By using named storage locations in the above code we have avoided
  259.    this issue.
  260.  
  261.           Notice also that we used Reverse Polish Notation without really
  262.    being aware of the alleged "problem" it causes.
  263.  
  264.             22 sfloat 7 sfloat f/ f.  is a good example.
  265.  
  266.           The value 22 is inserted first -- and THEN sfloat is called to
  267.    convert it from integer to float. This leaves 22.0 on the stack as the
  268.    numerator for the following  f/
  269.  
  270.           The value of 7 is then inserted -- and converted to 7.0 by sfloat.
  271.    This leaves 7.0 on the top of the stack [ TOS ] and 22.0 next on the
  272.    stack [ NOS ]. Each of these is a double precision value, so four 16-bit
  273.    values are stored on the stack.
  274.  
  275.           Next the word F/  [ floating point divide ] is called and this
  276.    operates on the 22.0 and 7.0 to produce 3.14159 as the result of 22.0 /
  277.    7.0.
  278.  
  279.         Then the word F. is called to print this value -- leaving the stack
  280.    empty.
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.    4th_86 version 4.01           CELCIUS.WLK                        page  6
  288.    
  289.    
  290.    Stack Depth
  291.    ===========
  292.  
  293.          You may have noticed a highlighted digit to the left of the 4th86
  294.    prompt. This is the "depth" of the stack -- the number of 16 bit entries
  295.    it holds at any given time. Repeat each step of the above 22 / 7
  296.    calculation and watch how this depth indicator changes.
  297.  
  298.           Type DEBUG and repeat the calculation again. You should now have a
  299.    display of the actual numeric stack contents at each stage of the
  300.    calculation. DEBUG is a toggle -- on and off.
  301.  
  302.           As n alternative you can use the word DS [ standing for Display
  303.    Stack ] at any time to see the stack contents.
  304.  
  305.     Effect of error messages
  306.     ========================
  307.  
  308.           If an error message is produced -- all files opened by the
  309.    offending definition are closed; any definition in progress is cancelled;
  310.    and the stack is cleared.
  311.  
  312.           A very useful method of clearing the stack therefore is simply to
  313.    type in garbage such as    asdjaisud   and hit return.
  314.