* Primitive principali
** def_class
*** Definizione
-
-
+Nel predicato def-class si definisce una classe dato: il nome, una lista di genitori ed eventuali fields e metodi,
+che definiscono il comportamento della classe e le caratteristiche,
+in seguito si inserisce la nuova classe dentro una tabella hash table in forma di chiave e valore.
+Come chiave abbiamo il nome della classe e come valore la lista che rappresenta la classe.
+Il predicato restituisce: il nome della classe messo in realazione alla lista della classe, di conseguenza per l'interprete Lisp il nome rappresenza la classe.
*** Implementazione
#+begin_src lisp :tangle ool.lisp
;;;; <Cognome> <Nome> <Matricola>
** make
*** Definizione
-
+Il predicato controlla se esiste /classname/, qualora sia presente si procede con l'operazione,
+trovando la lista che rappresenta la classe nell'hast-table, chiamiamo *create-istance* che resituisce l'istanza.
*** Implementazione
#+begin_src lisp :tangle ool.lisp
** field
*** Definizione
-
+Data un'istanza e il nome di un field, cerca nei campi dell'instanza se è prensete il valore del field ricevuto in ingresso.
*** Implementazione
#+begin_src lisp :tangle ool.lisp
(defun field (instance field-name)
- (unless (listp instance)
+ (unless (is-instance instance)
(error "~A non è un instanza" instance))
(field-helper (getf instance :fields) field-name))
** field*
*** Definizione
-
-
+boh ci penso sta sera, mentre farmo su star rail.
*** Implementazione
#+begin_src lisp :tangle ool.lisp
(defun field* (instance &rest fields)
* Predicati helper
+Definisce un semplice sistema per la gestione di specifiche di classi,
+mantenendo un hash-table in cui associare nomi di classi a specifiche di classe.
+
+Diachiariamo e inizializziamo una variabile globale come un hash-table vuoto, che verrà utilizzato per memorizzare le specifiche delle classi.
#+begin_src lisp :tangle ool.lisp
(defparameter *classes-specs* (make-hash-table))
-
+#+end_src
+La funzione aggiunge una nuova associazione all'hash-table, utilizzando il nome della classe come chiave e la specifica della classe come valore.
+#+begin_src lisp :tangle ool.lisp
(defun add-class-spec (name class-spec)
(setf (gethash name *classes-specs*) class-spec))
-
+#+end_src
+Restituiamo la specifica della classe associata a quel nome dall'hash-table.
+#+begin_src lisp :tangle ool.lisp
(defun class-spec (name)
(gethash name *classes-specs*))
#+end_src
+
** Creazione della classe in formato lista
+Creiamo la classe, se abbiamo una lista di fields *non vuota* il primo elemento deve essere l'atomo /fiedls/.
+In egual modo, in una lista di metodi il primo elemento deve essere l'atomo /methods/.
+
+Dopodichè creiamo i metodi come funzioni, si controlla che i fields siano del tipo corretto.
+Infine si prendono i fields del genitore e li aggiungiamo alla lista di fields alla classe creata.
#+begin_src lisp :tangle ool.lisp
(defun make-class (classname parents fields methods)
(unless (null fields)
#+end_src
*** Ereditazione dai genitori
+Controlliamo se esiste una classe genitore, qualora ci sia si unisce il genitore alla classe figlio.
+Ripetendo ricorsivamente il predicato, si forma una classe formata: dall'unione dei genitori, dei fields e dei metodi.
#+begin_src lisp :tangle ool.lisp
(defun inherit (class parents)
(if (null parents)
#+end_src
**** Merge dei genitori delle superclassi con quelli della classe figlio
+In questa merge controlliamo che la classe genitore è nella lista dei genitori, se *non* è prensete nella lista lo aggiungiamo.
#+begin_src lisp :tangle ool.lisp
(defun merge-parents (super-parents child-parent)
(if (null super-parents)
#+end_src
**** Merge field/method dei genitori con quelli della classe figlio
+Si aggiungono i fields e i metodi del genitore alla classe figlio,
+controllado che il field (o metodo) del genitore non sia presente nella lista del figlio.
#+begin_src lisp :tangle ool.lisp
(defun merge-parts (parent-fields class-fields)
(if (null parent-fields)
#+end_src
*** Creazione di metodi
+Per ogni lista dei metodi, creiamo una funzione che in ingresso 'this' e gli argomenti.
+Il corpo controlla che /this/ sia un istanza, verificando che dentro l'istanza è definito il metodo.
+Recuperiamo il corpo del metodo e lo richiamiamo con gli argomenti della funzione creata.
#+begin_src lisp :tangle ool.lisp
(defun define-methods (methods)
;; Per ogni metodi
#+end_src
** Creazione di un'istanza
+Data una lista, creiamo i field dell'istanza, che possono essere composti da: nome e valore oppure da nome, valore e tipo.
+Se ci sono field da modicare, cerco il field e ne modifico il valore successivamente richiamo ricorsivamente il predicato.
#+begin_src lisp :tangle ool.lisp
(defun create-instance (listclass new-fields)
;; Se c'è almeno un field da cambiare
(first new-fields) ;; nome del field
(second new-fields)) ;; nuovo valore
(cdr (cdr new-fields)))))
+#+end_src
+*** Impostare i campi dell'istanza
+Si definiscono i nuovi fields dell'istanza, cerchiamo il field con lo stesso nome
+(nel caso il field ha un tipo, viene controllato che il nuovo valore sia del tipo corretto) e ne si sostituisce il valore,
+dopodichè si restituisce l'istanza.
+#+begin_src lisp :tangle ool.lisp
(defun set-instance-field (instance name value)
;; `setf` modifica in-place
(setf (getf instance :fields)
#+end_src
** Stabilire se un simbolo è una classe
+Se il valore associato al nome della classe ha l'attributo ':type' con valore 'class,
+viene restituita la lista che rappresenta la classe.
#+begin_src lisp :tangle ool.lisp
(defun is-class (name)
(if (equal (getf (class-spec name) :type) 'class)
nil))
#+end_src
-** Controlla se il simbolo passato è un'instance della class
+** Controlla se il simbolo passato è un'instance della classe
+Per controllare che il simbolo è instanza della classe si controlla se esiste la classe.
+Se <class-name> esiste:
+ -controlliamo che l'istanza ha un attributo ':type' uguale a 'object.
+Se <class-name> non esiste:
+ -controlliamo se l'istanza è una lista o è la classe stessa o fa parte della lista dei genitori.
+Se nessuno di questi controlli va a buon fine il simbolo non è un'istanza della classe.
#+begin_src lisp :tangle ool.lisp
(defun is-instance (instance &optional (class-name t))
(if (eq class-name t)
#+end_src
** Controllo tipo valore
+Predicati dedicati al controlli dei tipi.
+Nello specifico:
+ -possiamo controllare che tutti i campi della lista abbiamo il tipo corretto.
+ -possaimo controllare se il campo è una terna o una coppia valida (?).
+ -dato un campo e un valore possiamo verificare che il valore sia del tipo corretto in base al campo.
+ -dato un tipo e un valore possiamo controllare se il valore è del tipo specificato.
#+begin_src lisp :tangle ool.lisp
(defun validate-fields-type (fields)
(cond ((null fields) nil)