\ -*- mode: forth -*-
\ $Id: wordfreq.gforth,v 1.1 2001/05/30 17:49:08 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Anton Ertl:
wordlist constant word-counts
create word-pointers 10000 cells allot
variable endwp word-pointers endwp !
1024 constant max-line
create line max-line 2 + allot
struct
cell% field wf-count
cell% 2* field wf-name
end-struct wf%
: count-word
2dup word-counts search-wordlist if
1 swap >body +! 2drop
else
nextname get-current word-counts set-current create set-current
here endwp @ tuck ! cell+ endwp !
1 , last @ name>string 2,
endif ;
: no-letter?
dup 'a < swap 'z > or ;
: process-word
2dup u< if
over - count-word
else
2drop
endif ;
: process-line
bounds 2dup ?do
i c@ $20 or dup i c!
no-letter? if
i process-word i 1+
endif
loop
swap process-word ;
: process-file
>r begin
line max-line r@ read-line throw
while
line swap process-line
repeat
rdrop ;
: output
endwp @ word-pointers ?do
i @ dup wf-count @ 7 .r #tab emit wf-name 2@ type cr
cell +loop ;
: wf<
over wf-count @ over wf-count @ 2dup = if
2drop >r wf-name 2@ r> wf-name 2@ compare 0>
else
u> nip nip
endif ;
cell- -1 cells ,
: partition
\ partition array addr1 u1 into all elements less than pivot and all
\ others, addr1 u2 and addr3 u3 are the two partitions.
\ lessthan-xt ( elemptr1 elemptr2 -- f ) compares the two elements
{ lessthan-xt }
over @ { pivot }
begin
2dup u<
while
begin
pivot over @ lessthan-xt execute
while
cell-
repeat
swap over @ over !
begin
2dup u>
while
pivot over @ lessthan-xt execute 0=
while
cell+
repeat then
swap over @ over !
repeat
drop pivot over ! ;
: sort1 recursive
>r begin
2dup u<
while
2dup r@ partition
rot over cell- r@ sort1
cell+ swap
repeat
rdrop 2drop ;
stdin process-file word-pointers endwp @ cell- ' wf< sort1 output bye