Skip to content

Instantly share code, notes, and snippets.

@nbkolchin
Created October 24, 2021 10:42
Show Gist options
  • Save nbkolchin/ce1efb3e40651d477f101f3a6ad9af79 to your computer and use it in GitHub Desktop.
Save nbkolchin/ce1efb3e40651d477f101f3a6ad9af79 to your computer and use it in GitHub Desktop.
Naive buffered read-line
[UNDEFINED] RDROP [IF]
: RDROP POSTPONE R> POSTPONE DROP ; IMMEDIATE
[THEN]
[UNDEFINED] BUFFER: [IF]
: BUFFER: CREATE ALLOT ;
[THEN]
BEGIN-STRUCTURE (bufio-struct)
FIELD: (bufio-file) \ file handle
FIELD: (bufio-total) \ total buffer size
FIELD: (bufio-pos) \ position in buffer
FIELD: (bufio-size) \ actual size of data in buffer
FIELD: (bufio-is-eof) \ EOF flag
END-STRUCTURE
: (bufio-data) (bufio-struct) + ;
: (bufio-data-at-pos) ( addr -- addr )
DUP (bufio-pos) @ SWAP (bufio-data) +
;
\ amount of unprocessed chars
: (bufio-left) ( addr -- n )
\ ." (bufio-left)" DUP dump-bufio
DUP (bufio-size) @ SWAP (bufio-pos) @ -
\ DUP ." (bufio-left return)" . CR
;
\ create IO buffer with size n
: bufio ( n -- )
CREATE
HERE DUP (bufio-struct) DUP ALLOT ERASE
(bufio-total) OVER SWAP !
ALLOT
;
\ Read data from file to buffer
\ move data if necessary
\ read from bufio-file data block size bufio-total - bufio-size
: (bufio-refill) ( addr -- )
>R
R@ (bufio-pos) @ ?DUP 0<> IF
R@ (bufio-data-at-pos) SWAP R@ (bufio-data) SWAP CMOVE
R@ (bufio-size) @ R@ (bufio-pos) @ - R@ (bufio-size) !
0 R@ (bufio-pos) ! \ zero buffer position
THEN
R@ (bufio-data) R@ (bufio-size) @ +
R@ (bufio-total) @ R@ (bufio-size) @ -
R@ (bufio-file) @ READ-FILE
?DUP 0<> IF
R@ (bufio-is-eof) !
ELSE
DUP 0= IF TRUE R@ (bufio-is-eof) ! THEN
THEN
R> (bufio-size) +!
;
: bufio-init ( fileid addr -- )
(bufio-file) !
;
: bufio-close ( addr -- )
(bufio-file) @ CLOSE-FILE ABORT" Failure closing file"
;
: bufio-readline ( c-addr n addr -- n )
>R
R@ (bufio-left) 0= R@ (bufio-is-eof) @ 0<> AND IF
RDROP 2DROP -1 EXIT
THEN
\ do we have enough data to fill n
DUP R@ (bufio-left) > R@ (bufio-is-eof) @ 0= AND IF
R@ (bufio-refill)
THEN
\ check if are at end
R@ (bufio-left) 0= R@ (bufio-is-eof) @ 0<> AND IF
RDROP 2DROP -1 EXIT
THEN
DUP R@ (bufio-data-at-pos) SWAP R@ (bufio-left) MIN DUP >R 10
SCAN
?DUP 0= IF
2DROP
R>
DUP R@ (bufio-pos) +! \ update position
R> (bufio-data-at-pos)
ELSE
RDROP DROP R@ (bufio-data-at-pos) - NIP
R@ (bufio-data-at-pos) SWAP
DUP 1+ R> (bufio-pos) +! \ update position
SWAP
THEN
-ROT
DUP >R CMOVE R> \ copy data
;
1024 128 * bufio f
128 CONSTANT MAXBUF
MAXBUF BUFFER: buf
: main
S" test.txt" R/O OPEN-FILE ABORT" Failure opening file"
f bufio-init
BEGIN
buf MAXBUF f bufio-readline
0<
UNTIL
;
main bye
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment