'(methods
(foo ()
(format "Favourite number is ~D~%" field(this 'bar)))))
+
+(def-class 'p-complex nil
+ '(fields
+ (:phi 0.0 real)
+ (:rho 1.0 real))
+ '(methods
+ (sum (pcn)
+ (let ((r1 (field this :rho))
+ (phi1 (field this :phi))
+ (r2 (field pcn :rho))
+ (phi2 (field pcn :phi)))
+ (make 'p-complex :rho (+ r1 r2)
+ :phi (+ phi1 phi2))))
+ (mult (pcn)
+ (let ((r1 (field this :rho))
+ (phi1 (field this :phi))
+ (r2 (field pcn :rho))
+ (phi2 (field pcn :phi)))
+ (make 'p-complex
+ :rho (- (* r1 r2) (* phi1 phi2))
+ :phi (+ (* r1 phi2) (* r2 phi1)))))
+ (div (pcn)
+ (let ((r1 (field this :rho))
+ (phi1 (field this :phi))
+ (r2 (field pcn :rho))
+ (phi2 (field pcn :phi))
+ (denominator (+ (* r2 r2) (* phi2 phi2))))
+ (make 'p-complex
+ :rho (/ (+ (* r1 r2) (* phi1 phi2)) denominator)
+ :phi (/ (- (* r1 phi2) (* r2 phi1)) denominator))))
+ (as-complex ()
+ (complex (field this :rho) (field this :phi)))))
#+end_src
** make
(field-helper (getf instance :fields) field-name))
(defun field-helper (fields field-name)
- (cond ((null fields) nil)
+ (cond ((null fields) (error "'~A' non è un field valido" field-name))
;; Se sono uguali il primo elemento della prima lista di `fields`
;; ed il nome del field restituisci il secondo
;; elemento della prima lista di `fields`
#+begin_src lisp :tangle ool.lisp
(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 'fields'")))
-
- (unless (null methods)
- (unless (equal (car methods) 'methods)
- (error "Il primo argomento della lista di methods ~S"
- "deve essere il simbolo 'methods'")))
-
- (define-methods (cdr methods))
- (validate-fields-type (cdr fields))
- (inherit
- (list :classname classname
- :type 'class
- :parents parents
- :fields (cdr fields)
- :methods (cdr methods))
- parents))
+ (cond ((and (null fields) (null methods))
+ (inherit
+ (list :classname classname
+ :type 'class
+ :parents parents
+ :fields nil
+ :methods nil)
+ parents))
+ ((and (null methods)
+ (eq 'methods (car fields)))
+ (make-class classname parents nil fields))
+ ((and (eq 'methods (car fields))
+ (eq 'fields (car methods)))
+ (make-class classname parents methods fields))
+ ((and (or (null fields) (eq 'fields (car fields)))
+ (or (null methods) (eq 'methods (car methods))))
+ (define-methods (cdr methods))
+ (validate-fields-type (cdr fields))
+ (inherit
+ (list :classname classname
+ :type 'class
+ :parents parents
+ :fields (cdr fields)
+ :methods (cdr methods))
+ parents))
+ (t (error "Definizione di fields o methods invalida"))))
#+end_src
*** Ereditarietà dei genitori
(field-helper (getf instance :fields) field-name))
(defun field-helper (fields field-name)
- (cond ((null fields) nil)
+ (cond ((null fields) (error "'~A' non è un field valido" field-name))
;; Se sono uguali il primo elemento della prima lista di `fields`
;; ed il nome del field restituisci il secondo
;; elemento della prima lista di `fields`
(gethash name *classes-specs*))
(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 'fields'")))
-
- (unless (null methods)
- (unless (equal (car methods) 'methods)
- (error "Il primo argomento della lista di methods ~S"
- "deve essere il simbolo 'methods'")))
-
- (define-methods (cdr methods))
- (validate-fields-type (cdr fields))
- (inherit
- (list :classname classname
- :type 'class
- :parents parents
- :fields (cdr fields)
- :methods (cdr methods))
- parents))
+ (cond ((and (null fields) (null methods))
+ (inherit
+ (list :classname classname
+ :type 'class
+ :parents parents
+ :fields nil
+ :methods nil)
+ parents))
+ ((and (null methods)
+ (eq 'methods (car fields)))
+ (make-class classname parents nil fields))
+ ((and (eq 'methods (car fields))
+ (eq 'fields (car methods)))
+ (make-class classname parents methods fields))
+ ((and (or (null fields) (eq 'fields (car fields)))
+ (or (null methods) (eq 'methods (car methods))))
+ (define-methods (cdr methods))
+ (validate-fields-type (cdr fields))
+ (inherit
+ (list :classname classname
+ :type 'class
+ :parents parents
+ :fields (cdr fields)
+ :methods (cdr methods))
+ parents))
+ (t (error "Definizione di fields o methods invalida"))))
(defun inherit (class parents)
(if (null parents)