muforth/lib/sieve.mu4

( This file is part of muFORTH: http://pages.nimblemachines.com/muforth

  Copyright 2002-2008 David Frech. All rights reserved, and all wrongs
  reversed. (See the file COPYRIGHT for details.)

( Sieve of Eratosthenes)

( line by line printing)
variable .width.  80 .width. !
variable .col.  .width. @ .col. !

: type_
   dup 1+ dup .col. @ +  .width. @ u< not if  cr .col. off then
   .col. +!  type space ;


1 k k constant nprimes
nprimes 31 + 5 >> cells buffer seen-bits  seen-bits  nprimes 7 + 3 >> erase

: i>bit  ( i - byte bit)  dup 3 >> swap 7 and ;
: 'seen  ( i)  i>bit  1 swap << ( mask)  swap  seen-bits +  ( mask a) ;
: seen   'seen  dup c@  rot or  swap c! ;
: seen?  'seen  c@  and ;
: 1mark  ( prime i - prime i')  dup seen  over + ;
: sieve  ( i prime)  swap  begin  dup nprimes <  while  1mark  repeat  2drop ;
: i>prime  ( map index to prime #)  2* 3 + ;
: print   dup  (.) type_ ;
: prime?   ( found i - found' i+1)
   dup seen? not if  dup  dup i>prime  print  sieve  1 u+  then  1+ ;
: erat   0  0  nprimes for  prime?  next drop  cr ." (" . ." primes)" ;

erat bye