snix/fun/wcl/wc.lisp
Vincent Ambo b0b52255bd fix(fun/wcl): Use 'eql' for byte comparisons
The fact that this works is just an implementation-specific detail. In
theory, 'eq' will only compare object instance equality and not value.

Thanks to /u/patrec from HN for pointing this out.
2020-01-29 00:03:50 +00:00

34 lines
1.1 KiB
Common Lisp

(defpackage wc
(:use #:cl #:iterate)
(:export :main))
(in-package :wc)
(declaim (optimize (speed 3) (safety 0)))
(defun main ()
(let ((filename (cadr sb-ext:*posix-argv*))
(space (char-code #\Space))
(newline (char-code #\Newline)))
(with-open-file (file-stream filename :element-type '(unsigned-byte 8))
(iter
(for byte in-stream file-stream using #'read-byte)
(for previous-byte previous byte)
(for is-newline = (eql newline byte))
;; Count each byte
(sum 1 into bytes)
;; Count every newline
(counting is-newline into newlines)
;; Count every "word", unless the preceding character already
;; was a space or we are at the beginning of the file.
(when (or (eql space previous-byte)
(eql newline previous-byte)
(not previous-byte))
(next-iteration))
(counting (or is-newline (eql space byte))
into words)
(declare (fixnum bytes newlines words))
(finally (format t " ~A ~A ~A ~A~%" newlines words bytes filename))))))