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