\ -*- mode: forth -*-
\ $Id: reversefile.gforth,v 1.1 2001/05/25 02:08:19 doug Exp $
\ http://www.bagley.org/~doug/shootout/

\ TBD - we still need to start the size at 4096 and grow only
\ when necessary.

variable size    2000000                  size !
variable sbuf    size @ allocate throw    sbuf !

10   constant  nl_ch
4096 constant  MAXREAD

: add_terminal_newline 
    dup c@ nl_ch <>
    if
    dup nl_ch swap c!
    1 +
    endif ;

: reversefile 
     nl_ch sbuf @ c!
    sbuf @ 1 +
    dup dup
    begin
        MAXREAD stdin read-file throw dup
    while
    \ add number of bytes read to current buffer position
    + dup
    \ now stack has start-of-buffer end-of-buffer addresses
    repeat
    drop
    \ stack: start-of-buffer end-of-buffer

    \ if input didn't end in a newline, then add one
    add_terminal_newline

    \ adjust end pointer
    2 -

    \ adjust start pointer
    swap 2 - swap

    \ now scan the buffer backwards, printing out the lines
    tuck
    -do
    \ stack: pointer to end of buffer
    i c@ nl_ch =
    if
        dup i 1 + swap i -
        stdout write-file throw
        drop
        i
    endif
    1 -loop
    ;

reversefile

bye \ th-th-that's all folks!