10e2e56b67
unix-opts, imported into buildLisp.nix in the previous commit, provides an implementation independent way of parsing command line arguments.
34 lines
1.1 KiB
Common Lisp
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 (opts: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))))))
|