home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1988 / 02 / tracy / tracy.lst
File List  |  1987-01-04  |  12KB  |  368 lines

  1.  
  2.  
  3. LISTINGS FOR TRACY Feb 1988 issue
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10. ( Stream data and text read and write )
  11. These utilities read and write streams of data and text from
  12. standard or BLOCKed files.
  13.  
  14. Text lines are read into the user buffer until either the buffer
  15. is full, or the file is empty, or an #EOF or #EOL is read.
  16. The terminating #EOF or #EOL , if present, is not read into the
  17. buffer.  #LF ( linefeeds) are read but ignored.
  18.  
  19. Output files are assumed to be extensible.
  20.  
  21. For your convenience, the Standard Prelude and DDJ Controlled
  22. Reference Word Set are duplicated in this file.
  23.  
  24.  
  25.  
  26. ( LOAD screen for DDJ Standard Prelude and String Extension)
  27. ( MJT  Nov 22 1987 for DDJ February 1987)
  28.  
  29. (     2 LOAD ( Standard prelude)
  30.       3 LOAD ( Augmented interpretation)
  31.    4  5 THRU ( Controlled words)
  32.    6  9 THRU ( Strings)
  33.   10 13 THRU ( General file support)
  34. \    14 LOAD ( Read and write data files)
  35.   15 16 THRU ( Read and write BLOCKed data files)
  36.      17 LOAD ( Read text file, no   #EOL)
  37. \    18 LOAD ( Read text file, with #EOL)
  38.      19 LOAD ( Write text file)
  39.   20 22 THRU ( Some examples)
  40.  
  41.  
  42. ( FORTH-83 functions-- typical definitions)
  43. ( Adjust these words for your Forth.    See DDJ Oct 1987.)
  44. ( Note: functions already provided need not be redefined.)
  45. : RECURSE   [COMPILE] MYSELF ;  IMMEDIATE
  46. : INTERPRET   INTERPRET ;
  47.  
  48. : I> ( - 'data)   COMPILE R> ;  IMMEDIATE
  49. : >I ( - 'data)   COMPILE >R ;  IMMEDIATE
  50.  
  51. ( Used for alignment: )
  52. : ALIGN    ( HERE 1 AND ALLOT) ;
  53. : REALIGN  ( a - a' )  ( DUP 1 AND +) ;
  54.  
  55. 2 CONSTANT CELL   : CELL+   2+ ;    : CELLS   2* ;
  56.  
  57. : UNDO   I> R> R> 2DROP >I ;  \ Undoes a DO-- LOOP.
  58. ( Required definitions - used to support further compilation)
  59.  
  60. : THRU ( n n2)   1+ SWAP DO  I LOAD  LOOP ;
  61. \ LOADS screens n through n2.
  62.  
  63. : \   >IN @ 64 + -64 AND >IN ! ;  IMMEDIATE
  64. \ comment to end of line.  For use in screens only.
  65.  
  66. : \\   1024 >IN ! ;  IMMEDIATE
  67. \ stops interpreting or compiling screen immediately.
  68.  
  69. : \IF ( f )   0= IF  [COMPILE] \  THEN ;  IMMEDIATE
  70. \ conditional interpretation or compilation.
  71.  
  72. : NEED ( - f)   32 ( ie blank) WORD FIND  SWAP DROP  0= ;
  73. \ true if the following word is in the search order.
  74. \ FORTH-83 Controlled Words
  75.  
  76. NEED  2* \IF  :  2*    DUP  + ;
  77. NEED D2* \IF  : D2*   2DUP D+ ;
  78.  
  79. NEED HEX \IF  : HEX   16 BASE ! ;
  80. NEED  C, \IF  : C, ( n )   HERE 1 ALLOT C! ;
  81.  
  82. NEED BL \IF  32 CONSTANT BL
  83.  
  84. NEED ERASE \IF  : ERASE ( a n)   00 FILL ;
  85. NEED BLANK \IF  : BLANK ( a n)   BL FILL ;
  86.  
  87. NEED .R \IF  : .R ( n width)   >R DUP 0< R> D.R ;
  88.  
  89.  
  90. \ DDJ Forth Column Controlled Words
  91. NEED 2>R
  92. \IF : 2>R   COMPILE SWAP COMPILE >R COMPILE >R ;  IMMEDIATE
  93. NEED 2R>
  94. \IF : 2R>   COMPILE R> COMPILE R> COMPILE SWAP ;  IMMEDIATE
  95. NEED @EXECUTE \IF  : @EXECUTE   @ EXECUTE ;
  96.  
  97. NEED AGAIN
  98. \IF  : AGAIN   0 [COMPILE] LITERAL [COMPILE] UNTIL ;  IMMEDIATE
  99. NEED DLITERAL
  100. DUP \IF  : DLITERAL  SWAP [COMPILE] LITERAL [COMPILE] LITERAL ;
  101.     \IF   IMMEDIATE
  102.  
  103. NEED S>D  \IF  : S>D  ( n - d)    DUP 0< ;
  104. NEED WITHIN   \IF  : WITHIN ( n n2 n3 - f)  OVER - >R - R> U< ;
  105. NEED TRUE \IF  -1 CONSTANT TRUE
  106. \ String operators    See  DDJ  December 1987
  107. \ Only  /STRING  and  EVAL  are used in this application.
  108.  
  109. : /STRING ( a n n2 - a+n2 n-n2)   ROT OVER +  ROT ROT - ;
  110. \ truncates leftmost n chars of string.  n may be negative.
  111.  
  112. : EVAL ( a n )
  113. \ evaluates ("text interprets") a string.
  114.    DUP >R  TIB SWAP CMOVE  R@ #TIB !
  115.    0 >IN ! 0 BLK !  INTERPRET  R> >IN ! ;
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122. \\ String operators from  STRINGS.ARC  are summarized here:
  123.  
  124. ASCII ( - c)       \ returns value of following character.
  125. CTO"" ( c - a 1)   \ converts character to string.
  126.  
  127. SKIP ( a l c - a2 l2)
  128. \ returns shorter string from first position unequal to byte.
  129. SCAN ( a l byte - a2 l2)
  130. \ returns shorter string from first position equal to byte.
  131.  
  132. " ( - a n)     \ STATE-smart string literal.
  133.  
  134.  
  135.  
  136.  
  137.  
  138. \\ String operators from  STRINGS.ARC  continue here:
  139. VAL? ( a n - d 2 , n2 1 , 0)
  140. \ string to number conversion primitive.  True if d is valid.
  141. \ Returns d if number contains ",-./:"  and sets DPL = 0
  142. \ Returns n if no punctuation present   and sets DPL = 0<
  143.  
  144. VAL ( a n - d f)
  145. \ converts string to double number.  True if number is valid.
  146. \ If number contains ",-./:" then sets DPL = 0
  147. \ If no punctuation present  then sets DPL = 0<
  148.  
  149. -TEXT ( a n a2 - -1 , 0 , 1)
  150. \ returns -1 if string a n < a2 n , 0 if equal, and 1 if >.
  151.  
  152. COMPARE  ( a n a2 n2 - -1 , 0 , 1)
  153. \ returns -1 if a n < a2 n2 , 0 if equal, and 1 if >.
  154. \ The corrected version of  MATCH
  155.  
  156. : MATCH ( a n a2 n2 - ???? 0 , offset -1)
  157. \ returns the position of string a2 n2 in (a n).
  158. \ Offset is zero if ( a n ) is found in first char position.
  159. \ Returns false with invalid offset if ( a n ) isn't in a2 n2.
  160.    DUP 0= IF  2DROP 2DROP   0 TRUE EXIT  THEN
  161.    2SWAP  2 PICK OVER SWAP -
  162.    DUP 0< IF  2DROP 2DROP   0 EXIT  THEN
  163.    0   ( index ) SWAP 1+ 0
  164.    DO  ( index ) >R
  165.      2OVER 2OVER DROP  -TEXT 0=  ( equal? )
  166.      IF  2DROP 2DROP  R> TRUE  UNDO EXIT  THEN
  167.      1 /STRING   R> 1+
  168.    LOOP  2DROP 2DROP  0 ;
  169.  
  170. \ Data stream general support
  171. 1024 CONSTANT 1K
  172.  
  173. : UMIN ( u u2 - u3)   2DUP U< 0= IF  SWAP  THEN  DROP ;
  174.  
  175. \ Adjust these constants for your system:
  176. 10 CONSTANT #LF    \ linefeed character.
  177. 13 CONSTANT #EOL   \ end-of-line character.
  178. 26 CONSTANT #EOF   \ end of file character (control-Z).
  179.  
  180. \ Adjust end-of-line and end-of-file sequence for your system:
  181. CREATE ENDLINE   2 ( count) C,  #EOL C, #LF C,
  182. CREATE ENDFILE   1 ( count) C,  #EOF C,
  183.  
  184.  
  185.  
  186. \ File size and position
  187. \ Example of some of the structure of a file control block:
  188.  
  189. \ VARIABLE FCB   HERE FCB !  5 CELLS ALLOT  ( Containing: )
  190. \    1 cell   current file handle-- ie selects current file.
  191. \    2 cells  current file size in bytes (double number).
  192. \    2 cells  current file position      (double number).
  193.  
  194. \\ You can implement CAPACITY and POSITION as 2VARIABLES.
  195. \\ You must initialize CAPACITY to the size of your file.
  196.  
  197. 2VARIABLE POSITION
  198. 2VARIABLE CAPACITY  ( eg  DSIZE CAPACITY 2! )
  199.  
  200.  
  201.  
  202. \ Set and reset file position
  203. \ Given POSITION you can control the position of file access:
  204.  
  205. : MARKDATA ( - d)   POSITION 2@ ;
  206. \ determines the position of the current file.
  207.  
  208. : SEEKDATA ( d )    POSITION 2! ;
  209. \ changes the position of the current file.
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218. \ Extend the file
  219. \ If your Forth or operating system requires explicit extension,
  220. \ supply an appropriate definition for  EXTEND .
  221. \ Otherwise, use  : EXTEND ( d ) COMPILE 2DROP ;  IMMEDIATE
  222.  
  223. : EXTEND ( d ) COMPILE 2DROP ;  IMMEDIATE
  224.  
  225. \\
  226. : EXTEND ( d )
  227. \ properly extends current file by  d  bytes.
  228. \ This example converts  d  to blocks and calls a MORE function.
  229.    1K UM/MOD  SWAP IF  1+  THEN ( # of blocks to extend ) MORE ;
  230.  
  231.  
  232.  
  233.  
  234. \ Read and write data files directly
  235.  
  236. : GETDATA ( a n - n2)   ;
  237. \ reads n bytes of data from input file into address, n < 64K
  238. \ Returns n2 bytes not read ( ie beyond end of file ).
  239. \ Implement as a system call using CAPACITY and POSITION
  240.  
  241. : PUTDATA ( a n)   ;
  242. \ writes n bytes of data to output file from address, n < 64K
  243. \ Implement as a system call using CAPACITY POSITION and EXTEND
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250. \ Read BLOCKed file as data file
  251.  
  252. : GETDATA ( a n - n2)
  253. \ reads n bytes of data from input file into address, n < 64K
  254. \ Returns n2 bytes not read ( ie beyond end of file ).
  255.    ( calculate # of bytes to move < 64K : )  POSITION 2@
  256.    BEGIN  2 PICK ( n ) DUP
  257.      IF ( n ) >R  2DUP 1K UM/MOD  SWAP DROP  1+  1K UM*
  258.         CAPACITY 2@ DMIN  2OVER D- 0= NOT OR  R> UMIN
  259.      THEN  ?DUP
  260.    WHILE  >R  2DUP 1K UM/MOD  BLOCK +  4 PICK R@ CMOVE
  261.      R@ 0 D+  2SWAP  R> /STRING  2SWAP
  262.    REPEAT  POSITION 2!  SWAP DROP ;
  263.  
  264.  
  265.  
  266. \ Write BLOCKed file as data file
  267.  
  268. : PUTDATA ( a n)
  269. \ writes n bytes of data to output file from address, n < 64K
  270.    ( extend the file as needed : )
  271.    DUP 0  POSITION 2@ D+  CAPACITY 2@  2SWAP D-  DUP 0<
  272.    IF  2DUP EXTEND  2OVER CAPACITY 2!  THEN  2DROP
  273.    ( calculate # of bytes to move < 64K : )  POSITION 2@
  274.    BEGIN  2 PICK ( n ) DUP
  275.      IF ( n ) >R  2DUP 1K UM/MOD  SWAP DROP  1+  1K UM*
  276.         CAPACITY 2@ DMIN  2OVER D- 0= NOT OR  R> UMIN
  277.      THEN  ?DUP
  278.    WHILE  >R  2DUP 1K UM/MOD  BLOCK +  4 PICK SWAP R@ CMOVE
  279.      R@ 0 D+  2SWAP  R> /STRING  2SWAP   UPDATE
  280.    REPEAT  POSITION 2!  2DROP ;
  281.  
  282. \ Read text file with #EOF
  283.  
  284. : GETTEXT ( a n - n2 f)
  285. \ reads n bytes of text from input file into address, n < 64K
  286. \ Returns n2 bytes not read ( ie end-of-line or beyond file)
  287. \ Returns true if #EOL terminates line; false otherwise.
  288.    POSITION 2@  CAPACITY 2@  2OVER D- 0= NOT OR ( limit to 64K)
  289.    3 PICK UMIN  ?DUP 0= IF  2DROP SWAP DROP  0 EXIT  THEN  0
  290.    DO  2DUP 1 0 D+  2SWAP 1K UM/MOD  BLOCK + C@ ( read a char )
  291.       DUP #EOL = OVER #EOF = OR
  292.       IF  >R  POSITION 2!  SWAP DROP  R> #EOL = UNDO EXIT  THEN
  293.       DUP #LF -  ( a n dpos ch f )
  294.       IF  >R  2SWAP  R@ 2 PICK C!  1 /STRING  2SWAP  R> THEN
  295.       DROP
  296.    LOOP  POSITION 2!  SWAP DROP  0 ;
  297.  
  298. \ Read text file without #EOF
  299.  
  300. : GETTEXT ( a n - n2 f)
  301. \ reads n bytes of text from input file into address, n < 64K
  302. \ Returns n2 bytes not read ( ie end-of-line or beyond file)
  303. \ Returns true if #EOL terminates line; false otherwise.
  304.    POSITION 2@  CAPACITY 2@  2OVER D- 0= NOT OR ( limit to 64K)
  305.    3 PICK UMIN  ?DUP 0= IF  2DROP SWAP DROP  0 EXIT  THEN  0
  306.    DO  2DUP 1 0 D+  2SWAP 1K UM/MOD  BLOCK + C@ ( read a char )
  307.       DUP #EOL =
  308.       IF  >R  POSITION 2!  SWAP DROP  R> #EOL = UNDO EXIT  THEN
  309.       DUP #LF -  ( a n dpos ch f )
  310.       IF  >R  2SWAP  R@ 2 PICK C!  1 /STRING  2SWAP  R> THEN
  311.       DROP
  312.    LOOP  POSITION 2!  SWAP DROP  0 ;
  313.  
  314. \ Read and write lines of text
  315.  
  316. : GETLINE ( a n - a n2 f)
  317. \ reads n bytes of text from input file into address, n < 64K
  318. \ n2 bytes are actually read; this is the opposite of GETTEXT
  319. \ Returns true if #EOL terminates line; false otherwise.
  320.    2DUP GETTEXT >R  -  DUP 0= 0=  R> OR ;
  321.  
  322. : PUTLINE ( a n )   PUTDATA  ENDLINE COUNT PUTDATA ;
  323. \ writes n bytes of data to output file from address, n < 64K
  324.  
  325.  
  326.  
  327.  
  328. \ Text stream examples
  329.  
  330. : TYPE-FILE   \ reads and prints the input text file.
  331. \ Assumes zero-length string TYPEs nothing.
  332.    SWITCH ( to input file saving currently active file)
  333.    BEGIN  PAD 80  GETLINE ( n2 f)
  334.    WHILE  CR TYPE  REPEAT  2DROP
  335.    SWITCH ( back to current file) ;
  336.  
  337. : COPY-FILE
  338. \ copies the input text file to the output text file.
  339. \ Save and restore current file as needed.
  340.    BEGIN  SWITCH ( to input  file)  PAD 80 GETLINE
  341.           SWITCH ( to output file)
  342.    WHILE  PUTLINE  REPEAT  2DROP  ENDFILE COUNT PUTDATA ;
  343.  
  344. \ Text stream examples
  345. : BLOCK-TO-TEXT
  346. \ copies the input BLOCK file to the output text file.
  347. \ Save and restore current file as needed.
  348.    BEGIN  SWITCH ( to input  file)  PAD 64 GETLINE
  349.           SWITCH ( to output file)
  350.    WHILE  -TRAILING  PUTLINE
  351.    REPEAT  2DROP  ENDFILE COUNT PUTDATA ;
  352.  
  353. : TEXT-TO-BLOCK   0 ( previous line length )
  354. \ copies the input text file to the output BLOCK file.
  355.    BEGIN  SWITCH ( to input  file)
  356.           PAD  64  2DUP BLANK  GETLINE  ROT ( a ) DROP
  357.           SWITCH ( to output file)
  358.    WHILE  DUP 0= ROT 64 = AND NOT IF  PAD 64 PUTDATA  THEN
  359.    REPEAT  2DROP ;
  360. \ Text stream examples
  361.  
  362. : EVAL-FILE   \ reads and interprets the input text file.
  363. \ Assumes zero-length interpreted string does nothing.
  364.    SWITCH ( to input file saving currently active file)
  365.    BEGIN  PAD 80  GETLINE ( n2 f)
  366.    WHILE  EVAL  REPEAT  2DROP
  367.    SWITCH ( back to current file) ;
  368.