feat(fun/wcl): Add a simple 'wc' clone in Lisp

Prompted by this thread:
https://lobste.rs/s/zntyeq/wc_d_712_characters_without_single_branch
This commit is contained in:
Vincent Ambo 2020-01-28 21:06:35 +00:00
parent 176b3458b0
commit 1ba3d1cf97
2 changed files with 46 additions and 0 deletions

13
fun/wcl/default.nix Normal file
View file

@ -0,0 +1,13 @@
{ pkgs, ... }:
pkgs.nix.buildLisp.program {
name = "wc";
srcs = [
./wc.lisp
];
deps = with pkgs.third_party.lisp; [
iterate
];
}

33
fun/wcl/wc.lisp Normal file
View file

@ -0,0 +1,33 @@
(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 = (eq 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.
(when (or (eq space previous-byte)
(eq newline previous-byte))
(next-iteration))
(counting (or is-newline (eq space byte))
into words)
(declare (fixnum bytes newlines words))
(finally (format t " ~A ~A ~A ~A~%" newlines words bytes filename))))))