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:
parent
176b3458b0
commit
1ba3d1cf97
2 changed files with 46 additions and 0 deletions
13
fun/wcl/default.nix
Normal file
13
fun/wcl/default.nix
Normal 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
33
fun/wcl/wc.lisp
Normal 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))))))
|
Loading…
Reference in a new issue