;;; -*- mode: lisp -*-
;;; $Id: wc.cmucl,v 1.3 2001/06/05 13:19:24 doug Exp $
;;; http://www.bagley.org/~doug/shootout/
;;; from Bulent Murtezaoglu (with some code from Andrew McDowell)

(declaim (optimize (speed 3) (debug 0) (safety 0) (space 0) (compilation-speed 0)))
     
  (let* ((start 0)
     (current #\X)            ;junk char save me the locally
     (end 0)
     (nc 0)
     (buffer (make-string 4096)))
    (declare (type (simple-base-string 4096) buffer) (fixnum start end nc)
         (base-char current))
    (labels
    ((get-char ()
           (when (= start end)
             (setf start 0)
             (setf end (read-sequence buffer *standard-input*))
             (incf nc end)
             (when (zerop end)
               (return-from get-char nil)))
           (setf current (schar buffer start))
           (incf start)))
      (let ((nl 0)
        (nw 0)
        (inword nil))
    (declare (fixnum nl nw))
    (loop while (get-char) do
      (cond ((char= current #\newline)
         (incf nl)
         (setq inword nil))
        ((or (char= current #\space) (char= current #\tab))
         (setq inword nil))
        ((not inword) ;; only tested if we have a word constituent
         (incf nw) (setq inword t))))
    (format t "~A ~A ~A~%" nl nw nc))))