((not (listp methods)) (error "`methods` non è una lista"))
((or (null classname)
(not (symbolp classname))) (error "'~A' non è un simbolo"
- classname)))
+ classname))
+ ((is-class classname)
+ (error "'~A' è una classe già definita" classname)))
;; Aggiunge la coppia `classname` e classe in forma di lista
;; all'hash-table
(add-class-spec classname (setf (symbol-value classname)
- (make-class parents fields methods)))
+ (make-class classname parents fields methods)))
;; e restituisce il nome della classe
classname)
#+end_src
** Creazione della classe in formato lista
#+begin_src lisp :tangle ool.lisp
-(defun make-class (parents fields methods)
+(defun make-class (classname parents fields methods)
(unless (null fields)
(unless (equal (car fields) 'fields)
(error "Il primo argomento della lista di fields ~S"
"deve essere il simbolo 'methods'")))
(type-check-fields (cdr fields))
- (inherit (list :type 'class
+ (inherit (list :classname classname
+ :type 'class
:parents parents
:fields (cdr fields)
:methods (cdr methods)) parents))
(error "`~A` non è una classe" (car parents)))))
(defun merge-class (child super)
- (list :type 'class
+ (list :classname (getf child :classname)
+ :type 'class
:parents (merge-parents (getf super :parents)
(getf child :parents))
:fields (merge-parts (getf super :fields)
"o una coppia (name value)"))))
(defun type-check (value type)
- (unless (typep value type) (error "~A non è di tipo ~A" value type)))
+ (if (is-class type)
+ (if (is-class value) ;; probabilmente da cambiare in `is-instance`
+ (if (equal (getf (class-spec type) :classname)
+ (getf (class-spec value) :classname))
+ t
+ (unless (member type (getf (class-spec value) :parents))
+ (error "'~A' non è di tipo '~A'" value type)))
+ (unless (null value) (error "'~A' non è di tipo '~A'" value type)))
+ (unless (typep value type) (error "~A non è di tipo ~A" value type))))
#+end_src
((not (listp methods)) (error "`methods` non è una lista"))
((or (null classname)
(not (symbolp classname))) (error "'~A' non è un simbolo"
- classname)))
+ classname))
+ ((is-class classname)
+ (error "'~A' è una classe già definita" classname)))
;; Aggiunge la coppia `classname` e classe in forma di lista
;; all'hash-table
(add-class-spec classname (setf (symbol-value classname)
- (make-class parents fields methods)))
+ (make-class classname parents fields methods)))
;; e restituisce il nome della classe
classname)
(defun class-spec (name)
(gethash name *classes-specs*))
-(defun make-class (parents fields methods)
+(defun make-class (classname parents fields methods)
(unless (null fields)
(unless (equal (car fields) 'fields)
(error "Il primo argomento della lista di fields ~S"
"deve essere il simbolo 'methods'")))
(type-check-fields (cdr fields))
- (inherit (list :type 'class
+ (inherit (list :classname classname
+ :type 'class
:parents parents
:fields (cdr fields)
:methods (cdr methods)) parents))
(error "`~A` non è una classe" (car parents)))))
(defun merge-class (child super)
- (list :type 'class
+ (list :classname (getf child :classname)
+ :type 'class
:parents (merge-parents (getf super :parents)
(getf child :parents))
:fields (merge-parts (getf super :fields)
"o una coppia (name value)"))))
(defun type-check (value type)
- (unless (typep value type) (error "~A non è di tipo ~A" value type)))
+ (if (is-class type)
+ (if (is-class value) ;; probabilmente da cambiare in `is-instance`
+ (if (equal (getf (class-spec type) :classname)
+ (getf (class-spec value) :classname))
+ t
+ (unless (member type (getf (class-spec value) :parents))
+ (error "'~A' non è di tipo '~A'" value type)))
+ (unless (null value) (error "'~A' non è di tipo '~A'" value type)))
+ (unless (typep value type) (error "~A non è di tipo ~A" value type))))