\ A simple immplementation of the blocks wordset.
\ This implementation uses only a single buffer and will therefore be a
\ little slow. An efficient implementation would use mmap on OSs that
\ provide it and many buffers on OSs that do not provide mmap.
\ I think I avoid the assumption 1 char = 1 here, but I have not tested this
1024 constant chars/block \ mandated by the standard
create block-buffer chars/block chars allot
variable buffer-block 0 buffer-block ! \ the block currently in the buffer
variable block-fid 0 block-fid ! \ the file id of the current block file
variable buffer-dirty buffer-dirty off
: get-block-fid ( -- fid )
block-fid @ 0=
if
s" blocks.fb" r/w open-file 0<>
if
s" blocks.fb" r/w create-file .s throw
then
block-fid !
then
block-fid @ ;
: block-position ( u -- )
\ positions the block file to the start of block u
1- chars/block chars um* get-block-fid reposition-file .s throw ;
: update ( -- )
buffer-dirty on ;
: save-buffers ( -- )
buffer-dirty @
if
buffer-block @ block-position
block-buffer chars/block get-block-fid write-file throw
buffer-dirty off
endif ;
: empty-buffers ( -- )
0 buffer-block ! ;
: flush ( -- )
save-buffers
empty-buffers ;
: block ( u -- a-addr )
dup 0= -35 and throw
dup buffer-block @ <>
if
save-buffers
dup block-position
block-buffer chars/block get-block-fid read-file .s throw
\ clear the rest of the buffer if the file is too short
block-buffer over chars + chars/block rot - blank
buffer-block !
else
drop
then
block-buffer ;
: buffer ( u -- a-addr )
\ reading in the block is unnecessary, but simpler
block ;
variable scr 0 scr ! \ !! this should be a user var
: list ( u -- )
\ calling block again and again looks inefficient but is necessary
\ in a multitasking environment
dup scr !
." Screen " u. cr
16 0
?do
scr @ block i 64 * chars + 64 type cr
loop ;
\ not yet implemented (with block semantics):
\ evaluate
\ load
\ refill
\ thru
\ \
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>