|
To read a file, we need a file ID, a buffer where a record can be read, and the maximum number of characters to be read at one time.
We use VALUE to give us names for these.
Program Text 1 0 VALUE Input-File
0 VALUE Input-Line
0 VALUE Input-Length
The "values" for these VALUE names should be assigned when the file is opened.
Program Text 2 128 CONSTANT |Input-Length|
CREATE |Input-Line| |Input-Length| 2 + CHARS ALLOT
: OPEN-INPUT ( str len -- )
R/O OPEN-FILE ABORT" Can't Open File. " TO Input-File
|Input-Line| TO Input-Line
|Input-Length| TO Input-Length ;
str len is the file name, and is given in the form
S" filename"
or
CREATE <file> ," filename"
...
<file> COUNT
or is extracted from input or existing data.
Most contemporary applications process one file at a time, so OPEN-INPUTOPEN-INPUTOPEN-HTML-INPUTOPEN-GRAPHIC-INPUT
READ-INPUTInput-FileInput-LineInput-LengthREAD-INPUT
: READ-INPUT ( -- str len more )
Input-Line dup Input-Length Input-File READ-LINE
ABORT" Can't READ-LINE " ;
Let's also have a function to reposition a file at its beginning, and one to close a file when we are done with it.
Program Text 4 : REWIND-FILE ( file-id -- ior ) 0 0 ROT REPOSITION-FILE ;
: REWIND-INPUT ( -- )
Input-File REWIND-FILE ABORT" Can't REWIND-FILE " ;
: CLOSE-INPUT ( -- )
Input-File CLOSE-FILE ABORT" Can't CLOSE-FILE " ;
From this we get a simple pattern for processing files.
REWIND-INPUT ( )
BEGIN READ-INPUT WHILE ( str len)
process a record of the file ( )
REPEAT 2DROP
CLOSE-INPUT
This pattern occurs frequently enough to have an even simpler form:
TRAVERSE-INPUT ( str len)
process a record of the file ( )
REPEAT
CLOSE-INPUT
TRAVERSE-INPUTEVALUATE
: TRAVERSE-INPUT ( C: -- orig dest )( -- str len )
S" REWIND-INPUT BEGIN READ-INPUT ?dup AND ?dup AND WHILE "
EVALUATE ; IMMEDIATE
or POSTPONE
: TRAVERSE-INPUT ( C: -- orig dest )( -- str len )
POSTPONE REWIND-FILE
POSTPONE BEGIN POSTPONE READ-INPUT POSTPONE ?DUP
POSTPONE AND POSTPONE ?DUP POSTPONE AND POSTPONE WHILE
; IMMEDIATE
Here are some convenient little tools. #Chars/Line
72 VALUE #Chars/Line
: EMITS ( n char -- ) SWAP 0 ?DO dup EMIT LOOP DROP ;
: SHOW-INPUT ( -- )
TRAVERSE-INPUT TYPE CR REPEAT ;
: LISTING ( str len -- )
CR ." \ " #Chars/Line [char] # EMITS CR
CR ." \ " 8 SPACES 2dup TYPE CR
CR ." \ " #Chars/Line [char] # EMITS CR
OPEN-INPUT SHOW-INPUT CLOSE-INPUT ;
Input-File ( -- file-id )
Input-Line ( -- addr )
Input-Length ( -- n )
|Input-Length| ( -- n )
Input-Length|input-Line| ( -- addr )
Input-LineOPEN-INPUT ( str len -- )
Input-FileInput-LengthInput-LineREAD-INPUT ( -- str len more )
Input-FileInput-LineInput-LengthREAD-INPUTREWIND-FILE ( file-id -- ior )
REWIND-INPUT ( -- )
Input-FileTRAVERSE-INPUT ( C: -- orig dest )( -- str len )
Input-FileREPEAT<test> UNTIL <action> THENSHOW-INPUT ( -- )
Input-FileLISTING ( str len -- )
Input-File( -- Wil Baden Costa Mesa, California Per neilbawd@earthlink.net )