From 403d2016c5ef82bcdcc87d5cb1abb3fd3a5c2007 Mon Sep 17 00:00:00 2001 From: MetMattone <115347319+MetMattone@users.noreply.github.com> Date: Tue, 9 Jan 2024 19:03:51 +0100 Subject: [PATCH] Update README.org fatta tutta la documentazione di lisp --- Lisp/README.org | 67 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/Lisp/README.org b/Lisp/README.org index bba2314..a0207a8 100644 --- a/Lisp/README.org +++ b/Lisp/README.org @@ -9,8 +9,11 @@ * 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 ;;;; @@ -54,7 +57,8 @@ ** 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 @@ -76,11 +80,11 @@ ** 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)) @@ -97,8 +101,7 @@ ** field* *** Definizione - - +boh ci penso sta sera, mentre farmo su star rail. *** Implementazione #+begin_src lisp :tangle ool.lisp (defun field* (instance &rest fields) @@ -111,17 +114,31 @@ * 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) @@ -146,6 +163,8 @@ #+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) @@ -167,6 +186,7 @@ #+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) @@ -184,6 +204,8 @@ #+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) @@ -205,6 +227,9 @@ #+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 @@ -242,6 +267,8 @@ #+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 @@ -260,7 +287,13 @@ (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) @@ -279,6 +312,8 @@ #+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) @@ -286,7 +321,13 @@ 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 esiste: + -controlliamo che l'istanza ha un attributo ':type' uguale a 'object. +Se 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) @@ -301,6 +342,12 @@ #+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) -- 2.52.0