NANDゲートから加算器作ってみた(common lisp)

NANDゲートから加算器作ってみました。
これでマインクラフトで計算機が作れるようになるのでは無いか??

(defmacro let1 ((k v) &body body)
  `(let ((,k ,v))
     ,@body))

(defun end (lst)
  (first (rest lst)))

;; nand gate
(defun nand-g (in1 in2)
  (if (>= (+ in1 in2) 2) 0 1))

;; not gate
(defun not-g (in)
  (nand-g in in))

;; and gate
(defun and-g (in1 in2)
  (nand-g (nand-g in1 in2) (nand-g in1 in2)))

;; or gate
(defun or-g (in1 in2)
  (nand-g (nand-g in1 in1) (nand-g in2 in2)))

;; nor gate
(defun nor-g (in1 in2)
  (not-g (or-g in1 in2)))

;; xor gate
(defun xor-g (in1 in2)
  (or-g (and-g (not-g in1) in2) (and-g in1 (not-g in2))))

;; マルチプレクサ
(defun mux (in1 in2 sel)
  (or-g (and-g in2 (not-g sel)) (and-g in1 sel)))

;; デマルチプレクサ
(defun dmux (in sel)
  (if (= sel 1)
    (list 0 in)
    (list in 0)))

;; 16bit用のゲート
(defun in1-gate16 (gate in1)
  (let1 (lst '())
        (dotimes (i 16)
          (push (funcall gate (nth i in1)) lst))
        (reverse lst)))

;; 16bit用入力二つ用のゲート
(defun in2-gate16 (gate in1 in2)
  (let1 (lst nil)
        (dotimes (i 16)
          (push (funcall gate (nth i in1) (nth i in2)) lst))
        (reverse lst)))

;; 半加算器
(defun ha (in1 in2)
  (let ((s (and-g in1 in2))
        (c (xor-g in1 in2)))
    (list s c)))

;; 全加算器
(defun fa (in1 in2 up)
  (let* ((lst1 (ha in1 in2))
         (lst2 (ha (end lst1) up))
         (c (or-g (first lst1) (first lst2))))
    (list c (end lst2))))

;; 加算
(defun sum (in1 in2)
  (let ((carry 0)
        (rst '())
        (in1 (reverse in1))
        (in2 (reverse in2)))
        (dotimes (i 16)
          (let1 (fa-lst (fa (nth i in1) (nth i in2) carry))
                (push (end fa-lst) rst)
                (setf carry (first fa-lst))))
        rst))

;; 2の補数
(defun 2comp (in)
  (dotimes (i 16)
    (setf (nth i in) (not-g (nth i in))))
  (sum in '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)))

(defvar *lst1* '(0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1)) ; 2017
(defvar *lst2* '(0 0 0 1 0 1 0 0 1 0 1 1 0 1 0 0)) ; 5300

; 2017 + 5300
(print (sum *lst1* *lst2*)) ;-> (0 0 0 1 1 1 0 0 1 0 0 1 0 1 0 1) = 7317

; 2017 - 5300
(print (sum *lst1* (2comp *lst2*))) ; -> (1 1 1 1 0 0 1 1 0 0 1 0 1 1 0 1)  = -3283

lisp楽しいですね。
ちょっとしたスクリプトlispで書けるようになりたいな。
なんだかんだまだpythonとか書いちゃいますね。。。