G'day,

I have a library that requires the ability to create methods programatically. 
To do this I have been using the CLOSER-MOP system to try and achieve 
portability across lisp implementations. Using the AMOP book [1] and the 
additional information provided in [2], I think I have managed to produce the 
correct code (attached) to programmatically create methods. 

When LOADing the code attached and invoking the function CLOSER-MOP-TESTS:MAIN, 
the code works as expected. i.e. it returns non-NIL. If I compile the code and 
load the resulting fasl, the code signals the following error:

Condition of type: SIMPLE-TYPE-ERROR
In function CAR, the value of the first argument is
  #<frame 2>
which is not of the expected type LIST

Backtrace:
  > CAR
  > #:g24
  > closer-mop-tests:main
  > si:bytecodes [Evaluation of: (closer-mop-tests:main)]
  > si:bytecodes [Evaluation of: (load "quick")]
  > si:bytecodes [Evaluation of: (si:top-level t)]

I am not sure what the cause of this error is. The code works as expected if I 
specify CLOSER-MOP:STANDARD-GENERIC-FUNCTION as the generic function class for 
PERFORM-OPERATION.

The code attached simply defines a macro DEFINE-OPERATION which adds a method 
to the PERFORM-OPERATION generic function. 

The version of ECL I am using is:
ECL (Embeddable Common-Lisp) 13.5.1 
(git:914ce253d1d9e52df684dfacc554167b3f100ce7)

Thanks
Mark

[1] The Art of the Metaobject Protocol by Gregor Kiczales, Jim des Rivieres and 
Daniel G. Bobrow.
[2] 
http://www.franz.com/support/documentation/8.2/doc/mop/concepts.html#processing-method-bodies

;; closer-mop-tests.lisp
(defpackage "CLOSER-MOP-TESTS"
  (:use "COMMON-LISP")
  (:export #:main))
(in-package "CLOSER-MOP-TESTS")

(eval-when (:compile-toplevel :load-toplevel :execute)
  (closer-mop:defgeneric perform-operation (task chain))

  (defun make-perform-operation-method-lambda (task-var chain-var body 
environment)
    (let ((gf #'perform-operation))
      (closer-mop:make-method-lambda gf
                                     (closer-mop:class-prototype
                                      (closer-mop:generic-function-method-class 
gf))
                                     `(lambda (,task-var ,chain-var)
                                        ,@body)
                                     environment)))

  (defun make-perform-operation-method (task-var chain-var task-class 
chain-class method-lambda initialisation-arguments)
    (assert (listp initialisation-arguments))
    (assert (closer-mop:classp task-class))
    (assert (closer-mop:classp chain-class))
    (let ((gf #'perform-operation))
      (apply #'make-instance (closer-mop:generic-function-method-class gf)
             :specializers (list task-class chain-class)
             :lambda-list (list task-var chain-var)
             :function method-lambda     
             initialisation-arguments)))

  (defmacro define-operation ((task-var task-class) (chain-var chain-class) 
&body body &environment environment)
    (multiple-value-bind (method-lambda initialisation-arguments)
        (make-perform-operation-method-lambda task-var chain-var body 
environment)
      `(let ((m (make-perform-operation-method ',task-var ',chain-var
                                               (find-class ',task-class) 
(find-class ',chain-class)
                                               (function ,method-lambda)
                                               ',initialisation-arguments)))
         (add-method #'perform-operation m)))))

(defclass my-task ()
  ())

(let ((object 2))
  (define-operation (task my-task) (chain t)
    (list task chain object)))

(defun main ()
  (let ((task (make-instance 'my-task)))
    (equal (list task 1 2)
           (perform-operation task 1))))


;;; quick.lisp
(asdf:load-system "closer-mop")
(proclaim '(optimize (speed 0) (safety 3) (debug 3) (space 0)))
(load (compile-file "closer-mop-tests.lisp"))
(print (closer-mop-tests:main))


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ecls-list mailing list
Ecls-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ecls-list

Reply via email to