diff options
author | Vincent Ambo <tazjin@google.com> | 2020-01-28T21·06+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-01-28T21·07+0000 |
commit | 1ba3d1cf97b9f671c7e0572fad7c57d691e69444 (patch) | |
tree | 64f7e8d1a482c5c37ef2b664dc2e9ec8f75b872a | |
parent | 176b3458b0352975dfa1af7eac5cb90a5394a4ba (diff) |
feat(fun/wcl): Add a simple 'wc' clone in Lisp r/469
Prompted by this thread: https://lobste.rs/s/zntyeq/wc_d_712_characters_without_single_branch
-rw-r--r-- | fun/wcl/default.nix | 13 | ||||
-rw-r--r-- | fun/wcl/wc.lisp | 33 |
2 files changed, 46 insertions, 0 deletions
diff --git a/fun/wcl/default.nix b/fun/wcl/default.nix new file mode 100644 index 000000000000..17367f3d8072 --- /dev/null +++ b/fun/wcl/default.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: + +pkgs.nix.buildLisp.program { + name = "wc"; + + srcs = [ + ./wc.lisp + ]; + + deps = with pkgs.third_party.lisp; [ + iterate + ]; +} diff --git a/fun/wcl/wc.lisp b/fun/wcl/wc.lisp new file mode 100644 index 000000000000..f443125a85b4 --- /dev/null +++ b/fun/wcl/wc.lisp @@ -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)))))) |