Common Lisp - 構造体の配列

Common Lispでは構造体の配列が使える。下のプログラムはその一例である。
(add-data)でデータを一つ入力し、(display)で全データを表示する。
名簿プログラムである。

; structs.lsp

(defparameter *n* 1000)

(defparameter *data-base* (make-array *n*))

(defstruct person
    name
    age
    sex
)

(defun find-name (name)
    (let ((i 0))
        (loop
            (if (eql i *n*) (return nil))
            (if (and (not (null (aref *data-base* i)))
                     (eql name (person-name (aref *data-base* i))) ) (return i))
            (setq i (1+ i)) ) ) )

(defun find-it (name)
    (let ((d) (k))
        (cond
            ((null (setq d (find-name name)))
             (cond
                 ((null (setq k (find-null))) (print '(not enouph memory)) nil)
                 (t k) ) )
            (t d) ) ) )

(defun find-null ()
    (let ((i 0))
        (loop
            (if (eql i *n*) (return nil))
            (if (null (aref *data-base* i)) (return i))
            (setq i (1+ i)) ) ) )

(defun add-data () ; Use this command.
    (let ((name) (age) (sex) (k))
        (princ 'name=) (setq name (read))
        (princ 'age=) (setq age (read))
        (princ 'sex=) (setq sex (read))
        (if (null (setq k (find-it name))) nil
            (progn
                (setf (aref *data-base* k) (make-person))
                (setf (person-name (aref *data-base* k)) name)
                (setf (person-age (aref *data-base* k)) age)
                (setf (person-sex (aref *data-base* k)) sex)
                t ) ) ) )

(defun display () ; Use this command.
    (let ((i 0))
        (loop
            (if (eql i *n*) (return t))
            (if (not (null (aref *data-base* i)))
                (progn
                    (terpri)
                    (princ (1+ i)) (terpri)
                    (princ 'name=) (princ (person-name (aref *data-base* i))) (terpri)
                    (princ 'age=) (princ (person-age (aref *data-base* i))) (terpri)
                    (princ 'sex=) (princ (person-sex (aref *data-base* i))) (terpri) ) )
            (setq i (1+ i)) ) ) )

トップページへ