home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / forth040.zip / FORTH.DOC < prev    next >
Text File  |  1994-05-22  |  58KB  |  1,481 lines

  1.  
  2.  
  3.                    Forth/2 Preliminary Documentation
  4.                             May 11, 1993
  5.  
  6.  
  7. Forth/2 is a fully 32-bit, native Forth for OS/2 2.0.  It requires an
  8. 80386SX or compatible microprocessor, and OS/2 2.0 or subsequent
  9. versions.
  10.  
  11. Forth/2 was created specifically for OS/2 using MASM 6.0 Currently it is
  12. a text-mode application which can be run either in a full screen or in a
  13. window.  It presently does not conform to any single Forth standard.
  14. Most of the major Forth functions are included.
  15.  
  16.  
  17.  
  18.  
  19.                            Table of Contents
  20.  
  21. 0.   Introduction
  22.  
  23. 1.   Using Forth/2
  24. 1.1  Installing Forth/2
  25. 1.2  Starting Forth/2
  26. 1.3  Basic information about Forth/2
  27. 1.4  Quitting Forth/2
  28. 1.5  Executing OS/2 Commands from Forth/2
  29. 1.6  Creating and Loading Forth Source Code
  30. 1.7  Error Detection
  31.  
  32. 2.   For Beginners
  33.  
  34. 3.   Special Functions IN Forth/2
  35. 3.1  Case Statements
  36. 3.2  TO Variables (or VALUE's)
  37. 3.3  String Handling Words
  38. 3.4  Threads
  39. 3.5  Arrays and Structures
  40. 3.6  Vocabularies
  41. 3.7  Local Variables
  42.  
  43. 4.   List of Words
  44. 4.1  Parameters
  45. 4.2  Parameter Naming Conventions
  46. 4.3  List of Word Definitions (INCOMPLETE)
  47.  
  48. 5.   Technical Description
  49. 5.1  Internals
  50. 5.2  OS/2 Interface
  51. 5.3  USER Variables and Multi-Tasking
  52. 5.4  TO Variables (VALUE's)
  53. 5.5  Vocabularies
  54. 5.6  Specifications and Limits
  55.  
  56.  
  57. 6.   Compatibility Issues
  58. 7.   Where to send comments/suggestions
  59.  
  60.  
  61.  
  62. 0.  INTRODUCTION
  63.  
  64. Forth is an interactive, hierarchical programming language.  Forth is a
  65. collection of functions which can be combined to create new functions,
  66. which in turn can be used in other functions.  A "program" in Forth is
  67. simply a word which performs a series of these functions.
  68.  
  69. For example, most books on programming show you how to create a minimal
  70. program in a particular language, one which simply types the words
  71. "Hello, world!" on the screen.  In Forth, this would be:
  72.  
  73.    : HELLO   ." Hello, world!" ;
  74.  
  75. Then, typing the word HELLO and tapping the Enter key will print the
  76. message.  The word  :  defines the new word HELLO, and defines its
  77. function to be all the words following up to the  ; . In this case, the
  78. only function it performs is  ."  (pronounced "dot-quote"), which 
  79. simply types the text to the screen up to the ending  " .
  80.  
  81. All the words  :  ."  and  "  are functions which reside in Forth's 
  82. vocabulary, the list of defined functions.  Then,  HELLO  was simply 
  83. added to this list of functions.  To see other available functions,
  84. type  WORDS  and tap the Enter key.
  85.  
  86. This documentation cannot hope to explain Forth to newcomers as well as 
  87. others have.  Two very readable and highly recommended books which
  88. explain Forth are:
  89.  
  90.    Starting Forth (2nd ed.) by Leo Brodie
  91.    Thinking Forth  also by Leo Brodie.
  92.  
  93. Look for them in your local library or bookstore, or obtain these and
  94. other books by writing or calling FORTH, Inc. at:
  95.  
  96.    FORTH Inc.
  97.    <I have to find their address>
  98.  
  99.  
  100.    John D. Hall, President
  101.    Forth Interest Group
  102.    P.O. Box 2154
  103.    Oakland, CA  94621
  104.    (510) 893-6784, Fax (510) 535-1295
  105.  
  106.  
  107.  
  108.  
  109. 1.  Using Forth/2
  110.  
  111. 1.1  Installing Forth/2
  112.  
  113. The Forth/2 beta is currently distributed as a single .ZIP (compressed) 
  114. file called FORTHxxx.ZIP where xxx is the version number (currently at 
  115. xxx=028).  Copy this file into any folder, and use PKWare's pkunzip
  116. utility or equivalent to uncompress the files.  
  117.  
  118. Forth/2 reads and compiles the file FORTH.INI upon startup.  This file
  119. helps minimize the size of the FORTH.EXE file while maximizing the 
  120. ability to customize Forth/2.  Make sure this file is in the same 
  121. directory that FORTH.EXE is called from.
  122.  
  123.  
  124.  
  125. 1.2  Starting Forth/2
  126.  
  127. To run Forth/2 from the OS/2 command line, simply change to the
  128. directory containing FORTH.EXE and FORTH.INI and type:
  129.  
  130.    FORTH
  131.  
  132. Or, create an OS/2 .CMD file to automate this process.  If you have 
  133. installed Forth/2 in a directory called FORTH2 on drive  C: then create
  134. a file called FORTH.CMD as follows:  
  135.  
  136.    REM FORTH.CMD  -  Starts Forth/2
  137.    C:
  138.    CD \FORTH2
  139.    FORTH
  140.  
  141. From the WorkPlace Shell, simply open the folder containing FORTH.EXE
  142. and FORTH.INI and double-click on FORTH.EXE.  To set it up to run in a
  143. window or in a full screen, bring up the menu for this object with Mouse
  144. Button 2, and select Open-->Settings, click on Session, and check either 
  145. the Windowed or Full Screen buttons to select.  
  146.  
  147.  
  148.  
  149. 1.3  Basic information about Forth/2
  150.  
  151. All Forth/2 commands are case insensitive.  When new definitions are 
  152. added to the dictionary, the letters are converted to uppercase first.  
  153. To see a listing of functions available in Forth/2, type Words then tap 
  154. the Enter key.
  155.  
  156. In the Words listing, you will see a fairly long list of words in the 
  157. Forth vocabulary, followed by the words available in the System 
  158. vocabulary.  The System vocabulary contains the names of many OS/2 
  159. system calls which would otherwise clutter up the main Forth dictionary.  
  160.  
  161. To remove these system calls from the Words listing, type Forth ONLY and
  162. tap the Enter key.  To see or use the system calls again, type System 
  163. and they will reappear.  
  164.  
  165. See Section 3.6  VOCABULARIES for more information.
  166.  
  167. You may also look up individual words from the Forth prompt.  If the
  168. file FORTH2.DOC (this file) is in the same directory that FORTH.EXE
  169. is in, type
  170.  
  171.    VIEW wordname
  172.  
  173. to get a brief description of a word and what parameters it requires
  174. and leaves on the stack.  Try  VIEW VIEW for example.
  175.  
  176. Use the function key F3 to recall the previous command, or F1 to recall
  177. the previous command one letter at a time.
  178.  
  179.  
  180.  
  181. 1.4  Quitting Forth/2
  182.  
  183. To exit from Forth/2, type
  184.  
  185.     BYE
  186.  
  187. and tap the Enter key.
  188.  
  189. If Forth/2 has locked up, or is caught in an endless (or very long) 
  190. loop, use Ctrl-C to exit the program.  
  191.  
  192.  
  193.  
  194. 1.5  Executing OS/2 Commands from Forth/2
  195.  
  196. To temporarily exit to the OS/2 command line prompt, type
  197.  
  198.     CommandPrompt
  199.  
  200. and tap the <Enter> key.  Feel free to redefine this to a shorter word.  
  201. When you have finished using OS/2 commmands, type 
  202.  
  203.     EXIT
  204.  
  205. and tap the <Enter> key to return to Forth/2.  The state of Forth/2 will
  206. be preserved.
  207.  
  208.  
  209. For frequently used system calls, you may wish to have OS/2 run the program
  210. directly.  To invoke an editor from Forth/2, and pass it the name of a
  211. file to edit, create the following word:
  212.  
  213.     : ED  ( -- )  ARGS" filename.4th"  SHELL" editor.exe" ;
  214.  
  215. You must give the exact path of the editor.exe program.  Omit the ARGS"
  216. if you do not want to pass the program any arguments.  To create a word 
  217. called ED" <filename>" which will edit the file after it, create this 
  218. word:  
  219.  
  220.     : ED" ( name-- )  [COMPILE] ARGS"    SHELL" editor.exe" ;
  221.  
  222.  
  223. To have OS/2's command shell execute a command, such as copy, del, start,
  224. etc., use a /C in front of the arguments passed to CMD.EXE.  For example,
  225. to create a Forth-based Copy command, do the following:
  226.  
  227.     : COPY  " /C COPY "   Arguments "MOVE
  228.             BL Word       Arguments "CAT
  229.             "  "          Arguments "CAT
  230.             BL Word       Arguments "CAT  CommandShell ;
  231.  
  232. To copy a file  test.4th  to  a:test.4th, type:
  233.  
  234.     COPY test.4th a:test.4th
  235.  
  236. See Section 3.3 on string handling for more information.
  237.  
  238.  
  239.  
  240. 1.6  Creating and Loading Forth Source Code
  241.  
  242. Create Forth definitions directly from the command line, or create an 
  243. ASCII sequential file using your favorite text editor.  To load in the 
  244. file, use the following word:  
  245.  
  246.     INCLUDE" FileName.TXT"
  247.  
  248. You may freely nest INCLUDE" inside other INCLUDE"ed files.  However,
  249. when compiled, the files must not alter the stack, either by requiring
  250. numbers or by leaving extra numbers on the stack.
  251.  
  252.  *** BUG ALERT! ***  INCLUDE" in FORTH.INI does not return control
  253.  
  254. You may also use OS/2's cut and paste ability to copy just a few words 
  255. from your editor, paste them into a windowed Forth/2 session, and try 
  256. them out until they work correctly.  
  257.  
  258. The file FORTH.INI contains basic definitions required by most Forth
  259. programmers, as well as a few utility programs like  MORE"  and  DIR.
  260. You may add your own programs to this file, or make any changes you 
  261. desire.  However, it is recommended that you instead use the
  262. STARTUP.4TH file for any customizations.  This way, you will avoid 
  263. having to reconcile the latest version of Forth/2 with your own 
  264. changes.  
  265.  
  266. Use ECHO ON and ECHO OFF within .4TH files to echo portions of a 
  267. document to the screen while they are being loaded.
  268.  
  269. When debugging programs it is common to load and re-load a program many
  270. times.  Avoid cluttering up the dictionary by using the word  FORGET.
  271. Use the command  FORGET <word>  to remove all definitions from <word> 
  272. onward.  
  273.  
  274.  
  275.  
  276. 1.7.  Error Detection
  277.  
  278. Unlike DOS, OS/2 catches any reads or writes to memory outside of the
  279. application's allocated space.  This helps keep applications protected
  280. from one another, and notifies you that you have a bug.  Almost nothing 
  281. you can do will crash anything but the one Forth/2 session.
  282.  
  283. All this protection is nice, but when things go wrong there is no way
  284. to trace back what happened, nor examine the values of specific memory
  285. locations.  (OS/2 has system calls to do this, but they have not been
  286. utilized in Forth/2 yet.)  Fortunately, Forth makes it so easy to test 
  287. out small chunks of code that wild memory references can be narrowed 
  288. down to the culprit quickly.
  289.  
  290. Note: These exceptions will handled gracefully in a future release.
  291.  
  292.  
  293.  
  294. 2.  FOR BEGINNERS
  295.  
  296. Under construction!  If you would like to know how Forth works, find a
  297. book on programming in Forth at your local library.  Or, obtain a file
  298. from an Internet ftp site which describes how to use Forth.
  299.  
  300. The ftp site asterix.inescn.pt (192.35.246.17) contains a great deal of
  301. information about Forth and Forth programs.  Look in the directory
  302. /pub/forth.
  303.  
  304.  
  305.  
  306. 2.1  Forth Structure and Syntax
  307.  
  308. The following are some basic statements about Forth's stucture and
  309. syntax:
  310.  
  311.   Forth is made up of a DICTIONARY of words.
  312.  
  313.   The DICTIONARY can be organized into separate VOCABULARIES.
  314.  
  315.   Each word in the dictionary performs some kind of function.
  316.  
  317.   All words and numbers must be separated by at least one SPACE.
  318.  
  319.   To use a word or series of words, type them in and tap Enter.
  320.  
  321.   Some words, like CONSTANTs, simply return a value.
  322.  
  323.   Other words perform various functions.
  324.  
  325.  
  326.   Forth is STACK-ORIENTED, and uses Reverse Polish Notation.
  327.  
  328.   The stack is used to pass PARAMETERS to words.
  329.  
  330.   Many words OPERATE on a certain number of parameters on the stack,
  331.    THEN RETURN zero or more parameters on the stack.
  332.  
  333.   For example, the word '+' adds two numbers from the stack, leaving one.
  334.  
  335.   To see the CONTENTS OF THE STACK, use the word  .S
  336.  
  337.  
  338.   The defining word  :  CREATES a new word in the dictionary.
  339.  
  340.   Create this:   : TEN+  10 + ;   Try:  100 TEN+ .S   -10 TEN+ .S
  341.  
  342.   The word  :  is just another word in the dictionary, which creates
  343.     a dictionary entry for the word which follows it, and defines
  344.     the word's funtion to be to perform all the words which follow
  345.     it up to the  ;
  346.  
  347.   Forth allows ANY ASCII characters to be used in word names.
  348.  
  349.   Other words, like VARIABLE <variable_name>  or
  350.            <number> CONSTANT <constant_name>  also create new words.
  351.  
  352.   VARIABLE's push the address where the variable is stored onto the stack.
  353.   To FETCH the contents of the variable, use          <variable_name> @
  354.   To STORE a number into the variable, use   <number> <variable_name> !
  355.   The word  @  is pronounced "FETCH", and  !  is pronounced "STORE".
  356.  
  357.   To print and remove the number from the top of the stack, use  . (DOT)
  358.  
  359.   One convention in Forth is to use  .  in any word which prints things.
  360.  
  361.  
  362. Planned sections:
  363.  
  364. 2.2  Simple math, .S, ."
  365. 2.3  : routines, IF...THEN
  366. 2.4  DO...LOOP   BEGIN...AGAIN
  367. 2.5  Number formatting
  368. 2.9  Making something work inside  :  definitions (e.g. COPY)
  369.  
  370.  
  371.  
  372.  
  373. 3.  SPECIAL FUNCTIONS IN FORTH/2
  374.  
  375. This section describes special words available in Forth/2.
  376.  
  377.  
  378. 3.1  CASE STATEMENTS
  379.  
  380. CASE statements are for when you evaluate a number of different options, 
  381. as in typing the day of the week.  Try the following word:
  382.  
  383. : DAY ( n ) CASE  1 OF  ." Monday"       ENDOF
  384.                   2 OF  ." Tuesday"      ENDOF
  385.                   3 OF  ." Wednesday"    ENDOF
  386.                   4 OF  ." Thursday"     ENDOF
  387.                   5 OF  ." Friday"       ENDOF
  388.                   6 OF  ." Saturday"     ENDOF
  389.                   7 OF  ." Sunday"       ENDOF
  390.                         ." Day " . ." ?" ENDCASE ;
  391.  
  392. Simply type  5 DAY  and it will print "Friday".
  393.  
  394. Note that you need a  DROP  or a similar effect between the last ENDOF 
  395. and the ENDCASE, which differs from other implementations of CASE..ENDOF.
  396.  
  397.  
  398.  
  399. 3.2  TO VARIABLES (or VALUE's)
  400.  
  401. TO variables help make Forth simpler to use and to read.  They are most
  402. useful when you fetch a value much more often then you store into that
  403. variable.
  404.  
  405. To create a TO variable, simply type:
  406.  
  407.     INTEGER X_LOC
  408.  
  409. and it is initialized to 0.  To examine the value of X_LOC, simply type:
  410.  
  411.     X_LOC .
  412.  
  413. No @ is necessary.  To store a new value into X_LOC simply type
  414.  
  415.    100 TO X_LOC
  416.  
  417. Then,  X_LOC .  will show 100.  To add to a TO variable, use +TO as in:
  418.  
  419.    50 +TO X_LOC
  420.  
  421. Then,  X_LOC .  will show 150.  To create a TO variable initialized
  422. with a certain value, use:
  423.  
  424.     1020 TO INTEGER Taxes
  425.  
  426.  
  427. Create arrays of integers with another word:
  428.  
  429.    100 INTARRAY XP[]    ( Creates an array called XP[] of 100 elements )
  430.  
  431.    100 0 DO  100 RND  I TO XP[]  LOOP   ( Store random numbers into XP )
  432.  
  433.    0  100 0 DO  I XP[] +  LOOP          ( Calculates the sum of all XP )
  434.  
  435. And, using  n index +TO XP[]  will add n to the indexed integer.
  436.  
  437. You can also create STRING TO variables.  See section 3.3.
  438.  
  439.  
  440.  
  441. 3.3  STRING HANDLING WORDS
  442.  
  443. All of the string words such as  ."  can be used outside colon definitions.
  444. A number of words have been included with Forth/2 to facilitate string
  445. handling.  
  446.  
  447.  
  448. 3.3.1  Creating and Typing Strings
  449.  
  450. To create a string constant, use the word " as follows:  
  451.  
  452.     " April 4, 1999"  "CONSTANT Deadline
  453.  
  454. Then, use  ".  (quote-dot) to type it out:
  455.  
  456.     Deadline ".
  457.  
  458. Develop your own synonyms for ". like  @Type  or  $.  etc.  Or, a
  459. simpler way to create a string constant is like this:
  460.  
  461.     Call" Bill Clinton" President
  462.  
  463. To create a zero-terminated string, such as for use with OS/2 system
  464. calls, use 0" as follows:
  465.  
  466.     : Invoice_File   0" Invoices.DAT" ;
  467.  
  468. Then, use  0".  to type the string out:
  469.  
  470.     Invoice_File 0".
  471.  
  472. or either type or load a file:
  473.  
  474.     0" Calendar.4TH" MORE
  475.     0" Calendar.4TH" INCLUDE
  476.  
  477. Use  0"COUNT  to obtain the size of a 0-terminated string.  In the
  478. example below, the 0" string is counted, then moved into TempStr as
  479. a counted string with MOVE>"
  480.  
  481.     CREATE TempStr   80 ALLOT
  482.     0" FileName.TXT"  0"COUNT  TempStr  MOVE>"
  483.  
  484.  
  485. You may want to terminate a regular counted string with a zero
  486. (if you have alloted room beyond the string).  To do this, use
  487.  
  488.     CREATE StrA  80 ALLOT
  489.     " To be zero-terminated"  StrA  "MOVE
  490.     StrA 0-Terminate
  491.     StrA W+ 0".               \ Skip length and use 0". to print
  492.  
  493. These words all work in colon definitions as well.
  494.  
  495.  
  496. 3.3.2  Copying and Concatenating Strings
  497.  
  498. The word  "MOVE  will move a counted string to another area of memory.
  499. To copy a string to another memory area, do the following:
  500.  
  501.    ( Make room for strings up to 80 characters long )
  502.    VARIABLE StringBuf  80 ALLOT
  503.  
  504.    Call" Warning: " WarnMsgBeg
  505.  
  506.    : InitWarning   WarnMsgBeg StringBuf "MOVE ;
  507.  
  508.    : TempWarning   InitWarning
  509.                    " Temperature over limit!"  StringBuf "CAT ;
  510.  
  511.    : PresWarning   InitWarning
  512.                    " Pressure overload!"       StringBuf "CAT ;
  513.  
  514.  
  515.    TempWarning  StringBuf ".   ( Will print the warning message )
  516.  
  517.  
  518. The word  "CAT  will add one string to the end of a second string.
  519. It accepts two strings on the stack, ( string1 string2 -- ) which are 
  520. both counted-strings, and adds  string1  to the end of  string2.
  521.  
  522. Because both  WORD  and  "  return the address of a counted string, most
  523. string handling words act upon a single address.  That address points to
  524. a 32-bit length, followed by the characters which make up the string.
  525. However, it is often required to manipulate a string which does not have
  526. a length at the address, but instead the length is on the stack.  To use 
  527. words like "CAT or =" with a string and length, first move it to a
  528. temporary string buffer with the word MOVE>" as follows:
  529.  
  530.     0" First Second Third Word"  6  StringBuf  MOVE>"
  531.  
  532.     StringBuf ".                 \ Will type "First "
  533.  
  534. The above code copies the first six charcters from the 0" string to
  535. StringBuf, because 0" returns the address of the first charcter of the
  536. string.
  537.  
  538. The word  MOVE>"  will copy a character string of a given length to an
  539. address and save it as a counted string.
  540.  
  541.     MOVE>"  ( address length dest_address -- )
  542.  
  543.  
  544. 3.3.3  Comparing Strings
  545.  
  546. You can check if two strings are equal with  ="  which accepts the
  547. addresses of two counted strings, and returns true or false if they are
  548. equal or not.  This word is case insensitive, so
  549.  
  550.  
  551.    Call" AbC" String1
  552.    String1  " aBc"  ="
  553.  
  554. ( Note that you cannot type in from the command line two quoted strings
  555. in a row, because the second is parsed into the same location as the
  556. first one, overwriting it.)
  557.  
  558. Often, however, you will have to compare one string, which is given as
  559. an address and length, with another counted string.  Instead of using
  560. MOVE>"  every time you wish to compare the string with another 
  561. (counted) string, use the word  =STRING  as follows:
  562.  
  563.    address length  " Compare String"  =STRING  IF  ...  ELSE  ...  THEN
  564.  
  565.  
  566.  
  567.  
  568. 3.3.4  String TO Variables
  569.  
  570. String  TO  variables are also available.  They are used in the same way
  571. as regular  TO  variables:
  572.  
  573.     STRING S1                         \ Create string S1
  574.  
  575.     " This is String 1" TO S1         \ Store string into S1
  576.  
  577.     " Initial String 2" TO STRING S2  \ Create string with initial value
  578.  
  579.     " Plus some extra" +TO S2         \ Adds "Plus some..." to end of S2
  580.  
  581.     S1 ".    S2 ".                    \ Type contents of strings S1 and S2
  582.  
  583.  
  584.  
  585.  
  586.  
  587. 3.4  THREADS
  588.  
  589. Threads are separate processes which run concurrently with other 
  590. programs.  They share memory space with the program that created them.  
  591.  
  592. OS/2 supports thread creation and management through the functions 
  593. DosCreateThread, DosKillThread, DosResumeThread, DosSuspendThread, and
  594. DosWaitThread.  
  595.  
  596. To load thread support into Forth/2, issue the command
  597.  
  598.     INCLUDE" THREADS.4TH"
  599.  
  600. in your  STARTUP.4TH  file, which should itself be INCLUDE"ed in 
  601. FORTH.INI.
  602.  
  603.  
  604. 3.4.1  Creating Threads and USER Variables
  605.  
  606. In Forth/2 a thread can be created to perform some action in the 
  607. background, and free up the main program for other uses.  For example, 
  608. you may want to start a separate thread to load a large table of numbers 
  609. into memory and perform computations.  Or, a thread can simply put 
  610. itself to sleep and wake up at hourly intervals to perform some 
  611. function.  
  612.  
  613. Most self-contained words in Forth/2 can be performed as a separate
  614. thread.  When the thread starts, it is given its own stack, and its own 
  615. copies of USER variables.  
  616.  
  617. USER variables are variables which multiple threads may use without
  618. interfering with each other.  For example, if you define a variable X1,
  619. but two different threads use this variable, then problems may arise.
  620. One thread may store into the value, only to have the intended value
  621. overwritten by another thread.
  622.  
  623. If X1 was created as a USER variable, however, then although the code for
  624. each thread uses a USER variable called X1, they will be in entirely 
  625. different locations and will not interfere with each other.  This allows
  626. you to create what is commonly referred to as reentrant code.
  627.  
  628. A good example is variables which hold file handles, file pointers, etc.  
  629. Without USER variables, if two threads tried to read or write files at
  630. the same time, the handles and pointers would overwrite each other.  You 
  631. would need two separate words which use different sets of variables in 
  632. order to get just two threads to do the same function at the same time.  
  633.  
  634. With USER variables, when the thread is created it is given a copy of
  635. the current USER variables.  After that, can freely modify them,
  636. while using the exact same Forth words that other threads use.
  637.  
  638.  
  639. In many cases, you may want to share a variable between threads.  For
  640. example, you may want to create a "watchdog" thread which continually
  641. examines a variable for a certain number.  This is a great help in
  642. debugging programs.
  643.  
  644.     variable XV1
  645.     : WatchDog  begin  XV1 @ 0< IF  CR ." XV1 < 0 !"  1 sleep  then
  646.                        100 usleep
  647.                 0 until ;
  648.  
  649. To run this as a separate thread, simply type
  650.  
  651.     Thread WatchDog
  652.  
  653. and test it by storing different values into XV1.  The  1 sleep  is
  654. there to prevent a huge number of warning messages, and the 100 usleep
  655. is there to prevent the thread from slowing down the system too much.
  656.  
  657.  
  658.  
  659. 3.4.2  Exiting and Terminating Threads
  660.  
  661. When Forth/2 is exited via BYE, all threads created by it will also be 
  662. terminated.  (This may be controlled by an option in an upcoming version
  663. of Forth/2).  If you wish to kill separate threads, use the ThreadID
  664. variable to obtain the identification number of the most recently 
  665. created thread, and type
  666.  
  667.     ThreadID @ KillThread
  668.  
  669. Look at the examples in the  THREADS.4TH  file for two other examples of
  670. using threads.  If the word, such as Timer, finishes executing and
  671. gets to the  ;  then the thread will terminate itself.  The thread may
  672. also use  BYE  and  EXIT  to terminate before the  ;
  673.  
  674.  
  675.  
  676. 3.4.3  Using ABORT in Threads
  677.  
  678. The word  ABORT  is vectored through  'ABORT.  In effect, ABORT is
  679.  
  680.     : ABORT  ( -- )  'ABORT @ EXECUTE ;
  681.  
  682. If your thread calls  ABORT  or  ABORT"  you may want to redirect ABORT to
  683. terminate the thread.  If you do not, it will halt the main program from
  684. doing whatever it is doing.  To redirect  ABORT  do the following:
  685.  
  686.     : ThreadAbort   ' BYE  CFA @  'ABORT ! ;
  687.  
  688. Then, simply call  ThreadAbort  in the beginning of the code for the
  689. thread.  When  ABORT  is called from the thread, the thread will 
  690. gracefully terminate.
  691.  
  692.  
  693.  
  694. 3.4.4  The USER Variable Area
  695.  
  696. Currently, a number of system variables such as BASE, the dictionary 
  697. pointer, STATE, et al., are not USER variables yet.  (It requires some 
  698. slight changes in how things are coded:  see Part 5 for details).  
  699.  
  700. Consequently, threads cannot request input from the terminal (although 
  701. they may send harmless output to the screen), nor can they compile new
  702. definitions.  These limitations may change in a future release.  
  703.  
  704. If you wish to initialize a thread with a different default USER 
  705. variable area other than the current thread's area, then store the 
  706. address of the new default area into the variable  'USER.  The size of
  707. the USER area is  UDP @  USER0 -  where  UDP  is the USER area free
  708. memory pointer, and  USER0  is the current thread's USER variable base.
  709.  
  710.  
  711.  
  712.  
  713. 3.5  ARRAYS AND STRUCTURES
  714.  
  715. Arrays and structures are supported in the file  STRUCT.4TH which you
  716. can load via  INCLUDE" STRUCT.4TH"
  717.  
  718. Structures hold groups of various information, such as a transaction 
  719. which has an identification number, a time/date stamp, a text 
  720. description, codes, and various other parameters.  A structure brings 
  721. all of this information into one convenient element which can be easily 
  722. manipulated.
  723.  
  724. <<See the file  STRUCT.4TH  for more information and examples.>>
  725.  
  726.  
  727.  
  728. 3.6  VOCABULARIES
  729.  
  730. Vocabularies under Forth/2 work like most other Forths.  To create a 
  731. vocabulary to hold a group of words, use
  732.  
  733.     VOCABULARY <vocabulary_name>
  734.  
  735. In order to tell Forth which vocabulary you wish to add new colon 
  736. definitions, variables, constants, etc. to, use
  737.  
  738.     <vocabulary_name> DEFINITIONS
  739.  
  740. Two vocabularies are already defined,  FORTH  and  SYSTEM.  When you 
  741. use the command WORDS to list the current Forth words, you will see the
  742. Forth vocabulary and possibly other vocabularies as well.  To only show 
  743. the FORTH vocabulary, simply type 
  744.  
  745.     Forth ONLY
  746.  
  747. Then,  WORDS  will show only the definitions in the Forth vocabulary.
  748. To see the SYSTEM vocabulary, simply type 
  749.  
  750.     SYSTEM WORDS
  751.  
  752. and you will see the system vocabulary, followed by the Forth 
  753. vocabulary.  Then, type FORTH words and you will instead see the Forth 
  754. vocabulary first, followed by the system vocabulary.  
  755.  
  756. Forth/2 keeps track of a  CURRENT  vocabulary, where all new definitions
  757. are added, as well as a list of  CONTEXT  vocabularies.  CONTEXT vocab-
  758. ularies are where Forth searches to find a word, either to execute it or
  759. to compile it.  What you see in the WORDS listing is the same order that 
  760. Forth/2 will use to search for words when compiling.  
  761.  
  762. Whenever you invoke the name of a vocabulary, if it is already in 
  763. CONTEXT  then it will simply be moved into the top of the search order.
  764. If it is not already in  CONTEXT, then it will be added to the top of 
  765. the search order.
  766.  
  767. To create two vocabularies, then define the search order for the words 
  768. as Voc2 first, then Voc1, then Voc3, then System, then Forth, do the 
  769. following:  
  770.  
  771.     VOCABULARY Voc1     : XV1  ... ;   : XV2   ... ;
  772.     VOCABULARY Voc2     : XV3  ... ;   : XV4   ... ;
  773.     VOCABULARY Voc3     : XV1  ... ;   : XV2   ... ;
  774.  
  775.     Forth ONLY
  776.     Forth System Voc3 Voc1 Voc2 DEFINITIONS
  777.  
  778. New words will be added to Voc2.  In the example above, the same word
  779. XV1 is defined in both vocabularies Voc1 and Voc3.  In this case, 
  780. because of the search order defined, if  XV1  is invoked, then the XV1
  781. from Voc1 will be executed, even though the  XV1  from Voc3 was defined
  782. later.  
  783.  
  784. The  Forth ONLY  above clears out any other unwanted vocabularies.
  785.  
  786.  
  787.  
  788. 3.7  LOCAL VARIABLES
  789.  
  790. Local variables enhance Forth by reducing the complexity of stack 
  791. operations, and allow you to assign descriptive labels to the numbers 
  792. passed to the word on the stack.
  793.  
  794. Local variables are supported in the file called  LOCALS.4TH.  Use 
  795. INCLUDE" LOCALS.4TH" in STARTUP.4TH to load local variable support every
  796. time Forth/2 is started.
  797.  
  798. If you pass three parameters to a word, perhaps ( addr len dest -- )
  799. and want to copy addr,len to the dest address, you could label these 
  800. parameters as:
  801.  
  802.     LOCALS| addr len dest |
  803.  
  804. After that, you are free to use the words  addr, len, and dest just as 
  805. if they were regular Forth words.  When the word containing the LOCALS|
  806. is executed, at the point  LOCALS|  appears the top three numbers on the
  807. stack are saved into a special data area, and the numbers are dropped 
  808. off the stack.  When  addr  gets executed, it fetches the value of the
  809. thrid element in the locals data area, and pushes it onto the stack.
  810.  
  811. The general format of this is as follows:
  812.  
  813. : WordName  LOCALS|  local1  local2  local3  ...  local8 |
  814.                      ...  local1  ...
  815.                      ...  local2  ...  local3  ... etc.  ;
  816.  
  817. The entire  LOCALS| ... |  must be on the same line.
  818.  
  819. One simple example is below:
  820.  
  821.    : DIGITS    LOCALS|  digit1 digit2 digit3 |
  822.                         digit1  100 *
  823.                         digit2   10 *
  824.                         digit3  + + ;
  825.  
  826. DIGITS  turns  1 2 3 DIGITS  into  123
  827.  
  828.  
  829. In regular Forth you would need code like this to do the same thing:
  830.  
  831. : DIGITS       ROT  100 *   ROT  10 *  + + ;
  832.  
  833. It is much less clear what the second version of DIGITS does.
  834.  
  835. LOCAL's are somewhat slower than regular Forth words, although this may 
  836. be changed if some words are turned into assembly words.  
  837.  
  838.  
  839.  
  840.  
  841. 4.  DESCRIPTION OF WORDS
  842.  
  843. This is an incomplete list of the words included in Forth/2.  Some are
  844. included in the FORTH.EXE file, others are in the FORTH.INI file.
  845.  
  846.  
  847. 4.1  Parameters
  848.  
  849. The parameters each Forth word requires, and the parameters it returns
  850. are specified by the following convention:  
  851.  
  852.     ( n1 n2 n3 ... -- r1 r2 r2 ... )
  853.  
  854. where n1, n2, n3, etc.  are the required parameters, and r1, r2, r3, 
  855. etc.  are the results.  For example, the word DUP duplicates the top 
  856. number on the stack, so it has the stack definition:  
  857.  
  858. DUP       ( n -- n n )  Duplicates the number on top of the stack
  859.  
  860. The word ?DUP duplicates the number on the stack if it is non-zero.  It
  861. returns different numbers of parameters depending on the top of stack:
  862.  
  863. ?DUP ( n -- n 1 -- 0 )  DUPlicates n if non-zero.
  864.  
  865. The word ' (tick) fetches the address of the following word, e.g.  ' DUP 
  866. will return the starting address of the DUP definition header, the Link 
  867. Field Address (LFA).  
  868.  
  869. '       ( word-- LFA )  gets the LFA address of the following word
  870.  
  871. So, when something is right up against the --'s, it expects a word or 
  872. set of words from the input stream.  
  873.  
  874.  
  875.  
  876. 4.2  Parameter Naming Conventions
  877.  
  878. Some naming conventions for the parameters are:
  879.  
  880. addr     a 32-bit address (or just 'a')
  881. b        an 8-bit byte
  882. char     an ASCII character
  883. n        a 32-bit number
  884. "        the address of a string
  885. ?        the number of parameters is unknown
  886.  
  887.  
  888.  
  889. 4.3  List of Word Definitions (INCOMPLETE)
  890.  
  891. --Begin--
  892. !        ( n addr -- )  Stores the number n into address addr
  893. "       ( word" -- a )  Returns the addr of the counted string ending in "
  894. "CAT   ( addr1 addr2 )  ConCATenates counted string at addr1 to end of addr2
  895. "CONSTANT     ( " -- )  Creates a string constant  Does> ( -- a )
  896. "MOVE  ( addr1 addr2 )  Copies counted string from addr1 to addr1
  897. #OUT       ( -- addr )  Variable holding # of characters written to line
  898. #TIB          ( -- n )  Address of the current offset in the TIB
  899. '       ( word-- LFA )  Gets the LFA address of the following word
  900. 'ABORT     ( -- addr )  Pointer to code to execute when ABORT is called
  901. 'USER      ( -- addr )  Pointer to the default USER area for new threads
  902. (               ( -- )  Skips interpreting words up to the next )
  903. *   ( n1 n2 -- n1*n2 )  Multiplies numbers on top of the stack
  904. */      ( a b c -- d )  Calculates  d = a * b/c  i.e. mutliply by ratio
  905. */MOD ( a b c -- r d )  Calculates  d = a * b/c  r=remainder
  906. +   ( n1 n2 -- n1+n2 )  Adds the two numbers on top of the stack
  907. +!       ( n addr -- )  Adds n to contents of addr
  908. +LOOP         ( n -- )  Adds n to loop counter and loops back
  909. +TO             ( -- )  Sets flag for adding value into integer:  1 +TO X1
  910. ,             ( n -- )  Stores n at dictionary pointer, increments DP by 4
  911. -   ( n1 n2 -- n1-n2 )  Subtracts numbers on top of the stack
  912. -ROT ( a b c - c a b )  Rotates top of stack to the third position
  913. -TRAILING ( a n1 -- a n2 )  Truncates extra spaces at end of string at a[ddr]
  914. .             ( n -- )  Prints the value of the top number on the stack
  915. ."      ( <string>== )  Prints a string up to the first "
  916. .(      ( <string>-- )  Prints a string up to the first )
  917. .S              ( -- )  Prints the contents of the stack non-destructively
  918. /   ( n1 n2 -- n1/n2 )  Divides numbers on top of the stack
  919. /MOD ( n1 n2 - n3 n4 )  Divides n1/n2, n3=remainder, n4=quotient
  920. 0"      ( word" -- n )  Returns the addr of the 0-terminated string ending in "
  921. 0"COUNT ( a -- a len )  Returns address and length of the 0-terminated string
  922. 2CONSTANT ( n1 n2 name ) Creates a two-number constant: 100 0 2CONSTANT CNTDWN
  923. 2DROP     ( n1 n2 -- )  Drops two numbers from the stack
  924. 2DUP ( n1 n2 -- n1 n2 n1 n2 )  Duplicates the double number on the stack
  925. :               ( -- )  Creates a new word to perform the words up to the ;
  926. ;               ( -- )  Marks the end of a definition
  927. <       ( n1 n2 -- f )  True if n1 < n2
  928. <<     ( n1 n2 -- n3 )  Shifts n1 by n2 bits left,  e.g. 100 5 << = 100 2^5 *
  929. ="      ( a1 a2 -- f )  True if counted strings at a1 and a2 equal. See STRING"
  930. =STRING ( a1 len a2 -- f ) True if string at a1,len equal to counted string a2
  931. >       ( n1 n2 -- f )  True if n1 > n2
  932. >>     ( n1 n2 -- n3 )  Shifts n1 by n2 bits right, e.g. 100 3 >> = 100 2^3 /
  933. >IN        ( -- addr )  Variable holding number of bytes left in input line
  934. >R            ( n -- )  Pushes number onto return stack.  Use in pairs with R>
  935. ?COMPILE        ( -- )  Gives error if not called in compile mode
  936. ?CR           ( -- f )  Does a CR if #OUT is greater than 64
  937. ?DUP ( n -- n 1 -- 0 )  DUPlicates n if non-zero. Eliminates an ELSE DROP THEN
  938. ?STACK          ( -- )  Gives error if the stack is out of bounds
  939. @        ( addr -- n )  Replaces address addr with it's contents
  940. @+    ( a -- a+4 [a] )  Returns address a+4 and contents of a.  See COUNT
  941. ABORT           ( -- )  Halts execution and returns to the Forth command line
  942. ABORT"        ( f -- )  If true shows an error msg ending in " and calls ABORT
  943. ABS       ( n -- |n| )  Calculates absolute value
  944. ALLOT         ( n -- )  Allocates storage space after VARIABLE or CREATE
  945. ALONG ( a b -- a+b a )  Use before DO when you have an address and length
  946. AND    ( n1 n2 -- n3 )  Returns the bit-wise AND of  n3 = n1 AND n2
  947. ARGS"   ( arguments" )  Passes arguments to the SHELL" :  ARGS" FILE.TXT"
  948. ASCII       ( char-- )  Returns ASCII value of character:  ASCII A
  949. BASE       ( -- addr )  Variable holding base for number conversion
  950. BL            ( -- c )  ASCII character for a blank space, 32
  951. BYE             ( -- )  Terminates current process (BYE == Leave forth)
  952. C!          ( b n -- )  Stores  byte at address n
  953. C,            ( b -- )  Compiles a byte into the dictionary
  954. C@          ( n -- b )  Fetches byte at address n
  955. CALL" ( <string><word> )  Creates a string constant, CALL" Clinton" President
  956. CMOVE ( a1 a2 len -- )  Moves len bytes from address a1 to address a2
  957. CMOVE> ( a1 a2 len - )  Moves len bytes from a a1 to a2, high memory first
  958. COMMANDLINE( -- addr )  Returns the linear address of the command line
  959. CommandShell    ( -- )  Temporarily exits to the OS/2 command line
  960. COMPILE         ( -- )  Postpones compilation of the following word
  961. COMPILECALL ( adr -- )  Compiles a call to the address given
  962. CONSTANT ( n word -- )  Creates the constant <word> which represents n
  963. CONTEXT    ( -- addr )  Address of CONTEXT, list of vocabularies to search
  964. COUNT ( a -- a+1 [a] )  Returns the address+1 and the byte at addr
  965. CR              ( -- )  Outputs a carriage return and line feed.
  966. CREATE      ( word-- )  Creates a word which returns its address when called
  967. CURRENT    ( -- addr )  Pointer to vocabulary where new words are added
  968. D>F         ( n -- R )  Converts the top stack entry to a Real
  969. DECIMAL         ( -- )  Start entering and printing all decimal numbers
  970. DEFINITIONS     ( -- )  Sets the vocabulary where new words are created
  971. DEPTH         ( -- n )  Number of elements on stack
  972. DO        ( n2 n1 -- )  Repeats from n1 up to n2.  Use with LOOP
  973. DOES>           ( -- )  Used after CREATE to define run-time action of word
  974. DP!           ( n -- )  Sets the dictionary pointer to a new value: DP !
  975. DPL        ( -- addr )  Variable holding decimal point location from NUMBER?
  976. DROP          ( n -- )  Drops the top number from the stack
  977. DROPS         ( n -- )  Drops n words from the stack
  978. DUMP   ( addr len -- )  Shows contents of a range of memory
  979. DumpRegisters   ( -- )  Shows the current contents of the CPU registers
  980. DUP       ( n -- n n )  Duplicates the number on top of the stack
  981. ECHO       ( -- addr )  Use ECHO ON or ECHO OFF to echo the file being loading
  982. ELSE            ( -- )  Executes following words when IF condition false
  983. EMIT       ( char -- )  Outputs an ASCII character
  984. ENVIRONMENT( -- addr )  Returns the linear address of the Environment Space
  985. EOF?          ( -- f )  True if at the end of file read with FRead
  986. EXECUTE    ( addr -- )  Executes the code at address, ' .S CFA @ EXECUTE
  987. EXITCODE   ( -- addr )  Variable holding exit code returned to OS/2 after BYE
  988. F!       ( R addr -- )  Stores a Real at memory address
  989. F*  ( R1 R2 -- R1*R2 )  Multiplies the two numbers on the floating point stack
  990. F+  ( R1 R2 -- R1+R2 )  Adds the two numbers on the floating point stack
  991. F-  ( R1 R2 -- R1-R2 )  Subtracts R2 from R1
  992. F.            ( R -- )  Prints and consumes, the top floating point number
  993. F/  ( R1 R2 -- R1/R2 )  Divides R1 by R2
  994. F0<         ( R -- f )  True if R < 0.0
  995. F0=         ( R -- f )  True if R = 0.0
  996. F<      ( R1 R2 -- f )  True if R2 < R1
  997. F>D         ( R -- n )  Converts the top Real to a Number
  998. F@       ( addr -- R )  Reads a Real from an address
  999. FABS        ( R -- R )  Returns the ABSOLUTE value of the stack top
  1000. FALIGN          ( -- )  Assures that the next allot will be float aligned
  1001. FALIGNED (addr -- f-addr) f-addr is the first f-alligned address >= addr
  1002. FALSE         ( -- 0 )  Returns the constant FALSE = 0
  1003. FBUFFER    ( -- addr )  Address of a 16K buffer for loading files
  1004. FCLEAR          ( -- )  Initializes the Floating Point Stack
  1005. FCONSTANT   ( R word )  Creates the constant <word> which represents R
  1006. FCOS    ( R -- Cos<r>)  Returns the Consine of angle R in radians
  1007. FDEPTH        ( -- n )  Returns the depth of the floating point stack
  1008. FDROP         ( R -- )  Drops the top floating point entry
  1009. FDUP       ( R - R R )  Duplicates the top floating point entry
  1010. FENCE      ( -- addr )  Sets lowest point to which you can FORGET words
  1011. FILL   ( addr n b -- )  Fills n bytes at addr with byte b
  1012. FLOOR       ( R -- R )  Truncates R towards -infinity
  1013. FOR       ( n2 n1 -- )  Repeats from n1 to n2 if n2>n1.  Use with NEXT
  1014. FORGET      ( word-- )  Forgets all words up to and including the word
  1015. FORTH           ( -- )  Sets FORTH as the current vocabulary
  1016. FROUND      ( R -- R )  Rounds to nearest integer
  1017. FSEEK   ( h ptr -- f )  Sets file handle h's position to ptr, f=0 successful
  1018. FSIN    ( R -- Sin<r>)  Returns the Sine of angle R in radians
  1019. FSINCOS ( R -- Sin<r> Cos<r>) Returns sine and consine of angle R in radians
  1020. FSQRT ( R -- Sqrt<r> )  Returns the square root of R
  1021. FSWAP (R1 R2 -- R2 R1)  Swaps the two reals on the stack
  1022. FVARIABLE ( <name>-- )  Creates a REAL variable called <name>
  1023. HELP            ( -- )  Displays some usefull help information
  1024. HERE          ( -- n )  Returns dictionary pointer
  1025. HEX             ( -- )  Start entering and printing all hexadecimal numbers
  1026. I             ( -- n )  Current LOOP value of innermost LOOP
  1027. IF            ( f -- )  Executes the following words if flag f is non-zero
  1028. IMMEDIATE       ( -- )  Marks last word defined as IMMEDIATE.
  1029. INCLUDE       ( " -- )  Loads and compiles the file name given at the address
  1030. INCLUDE"   ( file"-- )  Loads and compiles the file name ending with a "
  1031. INTEGER    ( word -- )  Creates an integer which returns it's value. See TO +TO
  1032. J             ( -- n )  Current LOOP value of second nested LOOP
  1033. K             ( -- n )  Current LOOP value of third  nested LOOP
  1034. KEY           ( -- b )  Waits for a key to be received, returns ASCII value
  1035. KEYNOWAIT     ( -- n )  Returns the raw keyboard scan code: 27=no key
  1036. LAST       ( -- addr )  Address containing pointer to last word defined
  1037. LEAVE           ( -- )  Causes DO...LOOP to terminate at next LOOP
  1038. LITERAL         ( -- )  Compiles a literal number into word: [ 100 ] LITERAL
  1039. LOCALS|       ( ? -- )  Defines local variables:  LOCALS| a b c |  ...
  1040. LOOP            ( -- )  Branches back to  DO
  1041. MAX    ( n1 n2 -- n3 )  Returns the greater of n1 and n2
  1042. MIN    ( n1 n2 -- n3 )  Returns the lesser  of n1 and n2
  1043. MOD    ( n1 n2 -- n3 )  Returns n1 modulo n2 (i.e. the remainder)
  1044. MORE" ( <filename>-- )  Types the contents of a text file: MORE" THREADS.4TH"
  1045. MOVE>" ( a len a2 -- )  Moves string at address a,len to counted string at a2
  1046. MS            ( n -- )  Suspends the current thread for at least n milliseconds
  1047. NDROP         ( n -- )  Drops n elements off the stack
  1048. NEGATE     ( n -- -n )  Multiplies n by -1
  1049. NEXT            ( -- )  Loops back to FOR
  1050. NIP    ( n1 n2 -- n2 )  Removes the second number from the stack
  1051. NUMBER? ( " -- n 1 -- 0 ) Converts string to number: true if success else false
  1052. OFF        ( addr -- )  Stores a FALSE at the address
  1053. ON         ( addr -- )  Stores a TRUE  at the address
  1054. ONLY            ( -- )  Makes the most recently cited vocabulary the only one
  1055. OPEN       ( 0" -- h )  Opens the 0-terminated file name and returns handle,    aborts if file not found
  1056. OPENNEW    ( 0" -- h )  Opens the 0-terminated file name, returns handle,       creating file if non-existant
  1057. OR     ( n1 n2 -- n3 )  Returns the bit-wise OR of  n3 = n1 OR n2
  1058. OUT        ( -- addr )  Address of variable holding output cursor position
  1059. OVER  ( a b -- a b a )  Copies the second number to the top of the stack
  1060. PAD        ( -- addr )  Address of scratch-pad memory
  1061. PI            ( -- R )  Returns the constant PI 3.1415926....
  1062. PICK      ( ? i -- ? )  Copies the i'th element on the stack to the top
  1063. POSTPONE        ( -- )  Compiles the next words run time action, even if immediate
  1064. QUIT            ( -- )  Quits execution and returns to Forth command line
  1065. R>            ( -- n )  Pops number from return stack.  Used with >R
  1066. R@            ( -- n )  Copy number from top of return stack
  1067. READLN  ( h -- a len )  Reads next line of input from file h, then try TYPE
  1068. RECURSE         ( -- )  Compiles a recursive call to the definition itself
  1069. ROLL      ( ? i -- ? )  Rolls the i'th element on the stack to the top
  1070. ROT ( a b c -- b c a )  Rotates third element to top of stack
  1071. SHELL"  ( string" -- )  Runs the given program:  SHELL" EDITOR.EXE" See ARGS"
  1072. SP!        ( addr -- )  Sets stack pointer to address.  SP0 SP! to clear stack
  1073. SP0        ( -- addr )  Base address of the stack
  1074. SP@        ( -- addr )  Stack pointer address
  1075. SPACE           ( -- )  Outputs a space
  1076. SPAN          ( -- n )  Address of the current offset in the TIB (same as #TIB)
  1077. STATE      ( -- addr )  Address of variable holding compilation state
  1078. STRING    ( <name>-- )  Creates a TO variable string: STRING S1  " YES" TO S1
  1079. SWAP    ( a b -- b a )  Swaps the two numbers on the stack
  1080. SYSCALL ( ? sys$ -- ? )  Calls a system routine starting with SYS$
  1081. THEN            ( -- )  Marks the end of an IF .. THEN  or IF .. ELSE .. THEN
  1082. THREAD   ( <word> -- )  Starts a thread to execute <word>: THREAD Bunny
  1083. TIB           ( -- n )  A variable holding a pointer to the Terminal Input Buf.
  1084. TO              ( -- )  Sets flag for storing value into integer, e.g. 1 TO X1
  1085. TOGGLE   ( n addr -- )  Toggles bits n at word address addr
  1086. TONE   ( freq dur -- )  Emits a tone for a given frequency(Hz) and duration(ms)
  1087. TRUE         ( -- -1 )  Returns the constant TRUE = -1
  1088. TUCK ( n1 n2 -- n2 n1 n2 )  Makes a copy of n2 under n1
  1089. TYPE     ( addr n -- )  Types out the n characters at address addr
  1090. U*     ( n1 n2 -- n3 )  Unsigned multiply  n3 = n1 * n2
  1091. U*/MOD ( a b c - r d )  Unsigned  d = a * b/c  r=remainder
  1092. U.            ( n -- )  Prints the unsigned value of the number
  1093. U/     ( n1 n2 -- n3 )  Unsigned divide,   n3 = n1 / n2
  1094. UALLOT        ( n -- )  Allot n words of USER variable space
  1095. UDP        ( -- addr )  Address of USER variable pointer
  1096. USER      ( <name>-- )  Creates a USER variable called <name>
  1097. USER0      ( -- addr )  Address of beginning of USER varaible area
  1098. VARIABLE  ( <name>-- )  Creates a variable called <name>
  1099. VIEW      ( <name>-- )  Views the description for a word.  VIEW VIEW
  1100. VOCABULARY ( <name>- )  Creates a new vocabulary: VOCABULARY VOC1
  1101. W             ( -- 4 )  Word size for addresses, variables, etc.  Also CELL
  1102. W!     ( addr 16b -- )  Stores  the 16-bit word at addr.  DO NOT CONFUSE WITH W
  1103. W*        ( n -- n*4 )  Multiplies by the word size 4.            Also CELLS
  1104. W+        ( n -- n+4 )  Adds the word size 4.                     Also CELL+
  1105. W-        ( n -- n-4 )  Subtracts the word size 4.                Also CELL-
  1106. W@     ( addr -- 16b )  Fetches the 16-bit word at addr.  DO NOT CONFUSE WITH W
  1107. WORD ( char string-- a )  Parse string delimited by char, return counted string
  1108. WORDS           ( -- )  Shows the forth words in CONTEXT
  1109. XOR    ( n1 n2 -- n3 )  Returns the bit-wise exclusive-OR of  n3 = n1 XOR n2
  1110. XY          ( x y -- )  Move cursor to screen location (x,y)=(col,row)
  1111. [               ( -- )  Stops   compilation in : definitions
  1112. [COMPILE]       ( -- )  Compiles the following immediate word into definition
  1113. \               ( -- )  Signals that the rest of the line is a comment
  1114. ]               ( -- )  Resumes compilation in : definitions
  1115. --End--
  1116. STRINGS  String words:  WORD  "   ="  "CAT  "MOVE   MOVE>"  =STRING  STRING
  1117.  
  1118.  
  1119.  
  1120. 5.  TECHNICAL DESCRIPTION
  1121.  
  1122. 5.1  Internals
  1123.  
  1124. Forth/2 is a direct, subroutine threaded Forth.  Colon definitions are 
  1125. made up of a series of 32-bit relative calls to other words.  The opcode 
  1126. for these calls is E8h, followed by a four-byte offset to the code.  
  1127.  
  1128. The return stack pointer (RP) is the ESP register.
  1129. The   user stack pointer (SP) is the EBX register and grows downward.
  1130. The   user area  pointer (UP) is the EBP register.
  1131. There is no need for an instruction pointer (IP).
  1132.  
  1133. So, a DUP instruction would be coded this way in MASM:
  1134.              mov       eax,[ebx]
  1135.              sub       ebx,4
  1136.              mov       [ebx],eax
  1137.              ret
  1138.  
  1139. DO...LOOP's are created as in-line code, thereby maximizing performance.
  1140. Literal numbers are also coded in-line.  They would take up 9 bytes to
  1141. code using the more traditional call to LIT, followed by the literal.
  1142. However, in only ten bytes it can be done much more quickly using
  1143. in-line code.
  1144.  
  1145. Currently, Forth/2 is case insensitive.  All defined words are converted 
  1146. to upper-case before being entered into the dictionary.  Forth words can 
  1147. be entered in any mix of upper and lower case, they are all the same.  
  1148.  
  1149. All math words like * / + - etc.  are fully 32-bit.  In addtion, the 
  1150. words */ and */MOD use 32-bit arguments but do generate 64-bit 
  1151. intermediate results.  No 64-bit double-number words such as D+, M*, or 
  1152. UM/MOD have been defined.  
  1153.  
  1154.  
  1155.  
  1156. 5.2  OS/2 Interface
  1157.  
  1158. OS/2 32-bit system calls are implemented by saving most registers, 
  1159. saving the ESP in EBP, setting ESP to EBX, calling the system routine,
  1160. then restoring ESP and the other registers.  Basically, this switches 
  1161. the stacks so that the parameters passed to OS/2 calls do not need to be
  1162. shuffled around.  The function which makes the system call must drop all 
  1163. the parameters it put on, as OS/2 does not do this (just as in C).  
  1164.  
  1165. To call OS/2 system functions, you must use the word SYSCALL which 
  1166. requires the address of the system call on the top of the stack.  Words
  1167. such as SYS$BEEP, SYS$READ, SYS$WRITE, SYS$OPEN et.  al.  return the 
  1168. addresses corresponding to the OS/2 functions DosBeep, DosRead, 
  1169. DosWrite, DosOpen, etc.  All use 32-bit arguments.  
  1170.  
  1171. The function calls are kept in a separate vocabulary called SYSTEM.  
  1172. Before you use any of these system calls, make sure SYSTEM gets executed 
  1173. to put the vocabulary into CONTEXT so that these calls will be visible.  
  1174.  
  1175. To translate OS/2 documentation, usually given with C calling 
  1176. conventions, into equivalent Forth/2 code, remember that in C the 
  1177. parameters are pushed onto the stack from right to left.  For the 
  1178. function DosBeep, the OS/2 Technical Library lists the function this 
  1179. way:
  1180.  
  1181.     APIRET DosBeep (ULONG ulFrequency, ULONG ulDuration)
  1182.  
  1183. To call this from Forth, do the following:
  1184.  
  1185.     Duration @  Frequency @  SYS$BEEP  SYSCALL  3 DROPS
  1186.  
  1187. You must drop all parameters after each SYSCALL.
  1188.  
  1189.  
  1190. To pass pointers to OS/2 functions, simply use the names of the 
  1191. variables, which place their address on the stack.  DosGetDateTime is 
  1192. listed as:  
  1193.  
  1194.     APIRET DosGetDateTime (PDATETIME ppPDateTime)
  1195.  
  1196. so call it as follows:
  1197.  
  1198.     VARIABLE DateTime   7 ALLOT  ( DateTime structure is 11 bytes long )
  1199.  
  1200.     DateTime SYS$GetDateTime SYSCALL  2DROP
  1201.  
  1202. The ASCII characters representing the date and time will be stored in 
  1203. the memory structure at DateTime.
  1204.  
  1205.  
  1206.  
  1207. 5.3  USER Variables and Multi-Tasking
  1208.  
  1209.  
  1210.  
  1211. 5.4  TO Variables (VALUE's)
  1212.  
  1213. TO variables use a system variable called  %TO  to determine if they should
  1214. return their value, or store or add into the variable.  If %TO is zero, the
  1215. variables return their value.  If %TO is >0, the number on top of the stack
  1216. is stored into the variable.   If %TO is <0, the number on top of the stack
  1217. is added to the variable.  The following words, defined in assembly for
  1218. speed but reproduced here, show how this works.
  1219.  
  1220.     VARIABLE %TO
  1221.     : TO    1 %TO ! ;
  1222.     : +TO  -1 %TO ! ;
  1223.     : <TODOES> ( addr -- ? )  %TO @ 0 = IF  @  ELSE
  1224.                               %TO @ 0 > IF  !  ELSE  +!  THEN THEN
  1225.                               0 %TO ! ;
  1226.  
  1227.     : INTEGER ( -- )  CREATE  0 ,   DOES>  <TODOES> ;
  1228.  
  1229. This can be augmented to accept initial values when the INTEGER is created.
  1230.  
  1231.     : INTEGER ( -- )  CREATE  HERE  0 ,
  1232.                               %TO @ IF  <TODOES>  ELSE  DROP  THEN
  1233.                       DOES>   <TODOES> ;
  1234.  
  1235. To store an initial value into the first version of INTEGER, you must do:
  1236.  
  1237.     INTEGER X  100 TO X
  1238.  
  1239. whereas with the second version you can combine these as:
  1240.  
  1241.     100 TO INTEGER X
  1242.  
  1243.  
  1244.  
  1245. 5.5  VOCABULARIES
  1246.  
  1247. Vocabulary structures are made up of three words:
  1248.  
  1249.     1   0          Unused
  1250.     2   VocPtr     Pointer to the last Forth word created in this vocabulary
  1251.     3   Voc-Link   Link to most recently created vocabulary
  1252.  
  1253. The word  VOC-LINK  is the head of a linked-list of vocabularies in the
  1254. order in which they were created.  VOC-LINK is needed in order to
  1255. FORGET words across multiple vocabularies.
  1256.  
  1257. When created, each vocabulary VocPtr is set to zero.  That way, all
  1258. vocabularies chain back to 0, not any other vocabularies.  To search
  1259. multiple vocabularies, each vocabulary name must be executed to
  1260. have it insert itself into the list of vocabularies in CONTEXT.
  1261.  
  1262.  
  1263.  
  1264. 5.6  Specifications and Limits
  1265.  
  1266. The following limits are present in the current Forth/2 system.  Since this
  1267. is a 32-bit Forth using a flat, non-segmented address space, most of these
  1268. limits are arbitrary and are simply controlled by constants in the compiler.
  1269.  
  1270. Word size:                                          4 Bytes  (32 bits)
  1271. Word name length maximum size:                     31 Bytes
  1272. Base code (.EXE) size:                           35 K Bytes  (So far)
  1273. FORTH.INI code size:                             14 K Bytes  (So far)
  1274.  
  1275. Dictionary size limit (incl. FORTH.INI):         64 K Bytes
  1276. User stack size limit:                            4 K Bytes  (1024 elements)
  1277. User stack underflow size limit:                  4 K Bytes  (1024 elements)
  1278. Return stack size limit:                          8 K Bytes* (2048 elements)
  1279. Return stack underflow size limit:                0 K Bytes
  1280. USER variable area size limit:                    4 K Bytes
  1281. File Buffer Size limit:                          16 K Bytes  (for FORTH.INI)
  1282. Terminal Input Buffer (TIB) Size limit:           256 Bytes
  1283.  
  1284. Terminal I/O:                                    ANSI compatibility
  1285. Alphabetic case sensitivity:                     Case insensitive (Dup==DUP)
  1286.  
  1287.  
  1288. * Note:  The return stack is handled by OS/2 using a guard-page technique.
  1289.          If the stack grows past 4K, a new 4K Byte page is allocated.
  1290.          Forth/2 will allow up to 1 one more page to be allocated.
  1291.  
  1292.  
  1293.  
  1294.  
  1295. 6.  COMPATIBILITY
  1296.  
  1297. There are some differences in the way this Forth works compared to most
  1298. other Forths.  Some of these may be changed in a future version.
  1299.  
  1300.  
  1301. 6.1  Compatibility with Forth-83
  1302.  
  1303. Since this Forth is still in development, not all words are supported
  1304. yet.  The following words from the Forth-83 Standard have not been
  1305. created yet in Forth/2:
  1306.  
  1307.   >BODY  CONVERT
  1308.   D+  D<  DNEGATE  UM*  UM/MOD
  1309.  
  1310. In the file BLOCKS.4TH which accompanies Forth/2 are some preliminary
  1311. words which can read and load block files.  However, multiple buffers
  1312. and the ability to save those blocks back to disk has not been imp-
  1313. lemented.  It is recommended that you use the conversion utility to
  1314. convert your block files into sequential files.
  1315.  
  1316. The following words are therefore only partially supported:
  1317.  
  1318.   BLK  BLOCK  BUFFER  FLUSH  LOAD  SAVE-BUFFERS  UPDATE
  1319.  
  1320.  
  1321.  
  1322.  
  1323. 6.2  Compatibility issues with specific words and functions
  1324.  
  1325.  
  1326. File Loading
  1327.  
  1328. Currently, files are loaded into a 16K buffer and compiled in one
  1329. pass.  This will be changed in future releases to support line-by-line
  1330. compilation.  So, the file size limit for FORTH.INI is currently 16K.
  1331.  
  1332. Block files are not directly supported.  A preliminary block file handler
  1333. has been implemented using the OS/2 functions SYS$READ, SYS$SEEK, and
  1334. SYS$WRITE in the file BLOCKS.4TH.
  1335.  
  1336.  
  1337.  
  1338. WORD and Strings
  1339.  
  1340. All string lengths are fully 32-bits long (no 255-character limits on
  1341. strings.)  This will certainly cause problems if you are using
  1342. COUNT.  If so, replace it with @+ which does the same thing except for
  1343. using a 32-bit count.  Remember, though, that doing a C@ on the string
  1344. will return the correct length if it is less than 256 characters long
  1345. because the 80386 stores the least significant byte in lower memory.
  1346. And, using it the normal way will usually do no harm.  You will simply
  1347. be typing out extra zeros in the front and chopping off the last three
  1348. characters.
  1349.  
  1350. Feel free to redefine COUNT if necessary, but people often use COUNT
  1351. for purposes other than with strings, so it was left alone.
  1352.  
  1353. Or, redefine WORD like this:
  1354.  
  1355.     : WORD ( char string"-- addr ) WORD  DUP C@  OVER 3 + C!  3 + ;
  1356.  
  1357. which stores an extra copy of the count immediately before the first
  1358. character, and returns that address instead.  Be careful, however, to
  1359. redefine some of the system functions such as ". because these fetch
  1360. the full 32-bit length.
  1361.  
  1362. WORD will not work accross lines while loading a file.
  1363.  
  1364.  
  1365.  
  1366. " (Quotes)
  1367.  
  1368. " string" returns the address of 32-bit count of a counted string.
  1369.  
  1370.  
  1371.  
  1372. Dictionary Headers and ' (tick)
  1373.  
  1374. The dictionary structure reflects the fully 32-bit theme of this
  1375. Forth.  All fields, including the length of the word, are 32 bits long.
  1376. A separate 32-bit flag field replaces the use of bits 6 and 7
  1377. of the length byte of typical Forths.  The word IMMEDIATE works in
  1378. the usual way, however.  It sets bit 1 (of 0-31) of the flag field.
  1379.  
  1380. The name field is always set to 32 bytes.  With 4GB of virtual memory to
  1381. play with, code size was not a major concern.
  1382.  
  1383. The order of the dictionary fields is non-standard.  The dictionary
  1384. header is structured like this:
  1385.  
  1386. Field    Length
  1387. Name    in bytes   Contents
  1388. -----   --------   --------------------------------------------------------
  1389. LFA         4      Link Field Address, link to previous definition
  1390. FFA         4      Flag Field Address, flags immediate definitions
  1391. CFA         4      Code Field Address, pointer to executable code
  1392. NFA         4      Name Field Address, length of the word followed by
  1393. SFA        32      String Field Address, address of first character
  1394. PFA         ?      Parameter Field Address, start of code and/or parameters
  1395.  
  1396. The string field is initialized to zeros.
  1397.  
  1398. ' (tick) returns the address of the link field address of the word, the
  1399. start of the definition.  To get to the other fields, use the following
  1400. words:
  1401.  
  1402.   ' <word>  ==>  LFA of word, then use:
  1403.  
  1404. DECIMAL
  1405.   : FFA  04 + ;  ( converts  LFA  to  FFA  or  Flag Field Address )
  1406.   : CFA  08 + ;  ( converts  LFA  to  CFA  or  Code Field Address )
  1407.   : NFA  12 + ;  ( converts  LFA  to  NFA  or  Name Field Address )
  1408.   : SFA  16 + ;  ( converts  LFA  to  SFA  or  String Field Address )
  1409.   : PFA  32 + ;  ( converts  LFA  to  PFA  or  Parameter Field Address )
  1410.  
  1411.   : LFA  32 - ;  ( converts  PFA  to  LFA )
  1412.  
  1413. If you ' a constant or a word created with DOES> you will have to add 5
  1414. to the address to get the real parameters.  The 5 skips the jump opcode
  1415. and the four byte offset.
  1416.  
  1417.  
  1418.  
  1419. TIB
  1420.  
  1421. The word TIB returns the address of a variable which holds the location
  1422. of the terminal input buffer.  To make it compatible, redefine
  1423.    :  TIB TIB @ ;
  1424. (It seems to be more flexible as a pointer anyway.)
  1425.  
  1426.  
  1427.  
  1428. Dictionary Pointer
  1429.  
  1430. Currently the dictionary pointer cannot be externally accessed with a
  1431. variable address.  Instead, use HERE to get the current dictionary
  1432. pointer and use DP!  to store into the dictionary pointer (instead of
  1433. DP !).
  1434.  
  1435.  
  1436.  
  1437. CASE
  1438.  
  1439. An implementation of Chuck Eaker's CASE words is included in the
  1440. FORTH.INI file.  There is one major difference.  You must do a DROP or
  1441. equivalent before the ENDOF statement at the end.  This was done because
  1442. you should not have to DUP the value which fell through in order to
  1443. handle it (as in 0 DAY in section 3.1).  It does not make sense that
  1444. ENDCASE requires a parameter.  It DOES make sense that you should always
  1445. deal with an exception, either by ignoring it with DROP or by using some
  1446. type of error handling.
  1447.  
  1448.  
  1449.  
  1450.  
  1451. 7.  WHERE TO SEND COMMENTS AND SUGGESTIONS
  1452.  
  1453. Mike Warot (ka9dgx) created Forth/2 and welcomes any comments,
  1454. or suggestions about improving this product.  You may contact him
  1455. via email over the Internet at:
  1456.  
  1457.      ka9dgx@chinet.com             OR  ka9dgx@aol.com
  1458.  
  1459. or via USMail at:
  1460.  
  1461.      Mike Warot
  1462.      PO BOX 4043
  1463.      Hammond, Indiana 46324
  1464.  
  1465. Also contact Mike about licensing this product and obtaining the source
  1466. code for Forth/2.
  1467.  
  1468.  
  1469. Brian Mathewson has helped Mike develop this Forth and the documentation.
  1470. Please send any special requests, ideas, or suggestions to:
  1471.  
  1472.      bbm@r2d2.eeap.cwru.edu
  1473.  
  1474. or via USMail at:
  1475.  
  1476.      Brian Mathewson
  1477.      21576 Kenwood Avenue
  1478.      Rocky River, OH  44116-1232
  1479.  
  1480. <<< End of Forth/2 Documentation  23 March 1993 >>>
  1481.