;;; -*- Mode:LISP; Package:WORDS; Readtable:CL; Base:10 -*-

(defvar *slist* nil "List of sentence structures")
(defvar *wlist* nil "A-List of word symbol/structure pairs")

(defstruct sentence
  (text "")
  (words nil)
  (wordlist nil))

(defstruct word
  (text "")
  (symbol nil))

(defun word-p(word)
  (assoc word *wlist*))

(defun wordify(word)
  (intern (string word) 'words))

(defun add-word(word)
  (setq word (wordify word))
  (or (word-p word)
      (car(push (cons word (make-word :text (string word) :symbol word))
		*wlist*))))

(defun words-in-list(words)
  (if (listp words) (format nil "~{~s ~}" words)))

(defun words-in-string(words)
  (when (stringp words)
    (setq words (string-trim " " words))
    (when (greaterp (length words) 0)
      (multiple-value-bind (val index)
	  (read-from-string words nil :eof)
	(and (neq val :eof)
	     (cons val
		   (words-in-string
		     (substring words index))))))))

(defun add-words(words)
  (loop for word in words
	when (not(word-p word))
	collect (progn (setq word (wordify word))
		       (add-word word))))

(defun add-sentence(sentence &aux text words newone)
  (etypecase sentence
    (string
     (setq text sentence)
     (setq words (words-in-string sentence)))
    (list
     (setq text (words-in-list sentence))
     (setq words sentence))
    (sentence
     (setq text (sentence-text sentence))
     (setq words (sentence-words sentence))))
  (setq newone
	(make-sentence :text text
		       :words words
		       :wordlist (add-words words)))
  (push newone *slist*)
  newone)

(defun init()
  (setq *slist* nil)
  (setq *wlist* nil))

