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))))))
 |