1 ;;-----------------------------------------------------------------------------------
3 ;;; description: all the macros needed for netclos
5 ;;; contact : me (Michael Trowe)
9 ;;;-----------------------------------------------------------------------------------
13 (defstruct request message-id
)
15 (defun fetch-names (args)
17 collect
(if (listp arg
)
21 (defmacro defmessage
(name args
&key receive-action request-p process-p
)
23 (create-request name
(fetch-names args
) args receive-action process-p
)
24 (create-operation name
(fetch-names args
) args receive-action process-p
)))
26 (defun create-request (name arg-names args body process-p
)
27 (let* ((sym (gensym "message-id"))
28 (body `(kernel-send *calling-os
*
29 (reply-message :content
,body
32 ,(create-struct name arg-names
:super
'request
)
33 ,(create-defun name (cons sym arg-names
) body process-p
)
34 ,(create-pack name
(cons 'message-id arg-names
) (cons 'message-id args
)))))
36 (defun create-operation (name arg-names args body process-p
)
38 ,(create-struct name arg-names
)
39 ,(create-defun name arg-names body process-p
)
40 ,(create-pack name arg-names args
)))
43 (defun create-struct (name args
&key super
)
46 (:constructor
,(intern (format nil
"~a-MESSAGE" name
)))
50 (:constructor
,(intern (format nil
"~a-MESSAGE" name
))))
53 (defun create-defun (name arg-names body process-p
)
54 `(defun ,name
,arg-names
,(if process-p
55 `(acl-compat-mp:process-run-function
,(format nil
"receiving ~a" name
)
56 #'(lambda (*calling-os
*)
61 (defvar *pack-forms
* ())
63 (defun create-pack (name arg-names args
)
64 `(defmethod pack ((message ,name
) &optional stream
)
66 (write-string ,(concatenate 'string
"(" (write-to-string name
) " ") stream
)
67 ,@(loop for arg in args
68 for arg-name in arg-names
69 for packfunc
= (if (and (listp arg
)
70 (eq (second arg
) :packing
))
73 collect
`(,packfunc
(,(intern
74 (format nil
"~a-~a" name arg-name
))
77 (write-char #\
) stream
))))
79 ;;; mit *thee-agg zum testen von env
81 (defun create-pack (name arg-names args
)
82 `(defmethod pack ((message ,name
) &optional stream
)
85 "(let ((mks::*the-aggregate* 'pol) (declare (special mks::*the-aggregate*))")
86 (write-string ,(concatenate 'string
"(" (write-to-string name
) " ") stream
)
87 ,@(loop for arg in args
88 for arg-name in arg-names
89 for packfunc
= (if (and (listp arg
)
90 (eq (second arg
) :packing
))
93 collect
`(,packfunc
(,(intern
94 (format nil
"~a-~a" name arg-name
))
97 (write-char #\
) stream
)
98 (write-char #\
) stream
)
104 (defmacro defgeneric
(name second
&rest rest
)
105 (if (member second
'(:past
:now
:future
))
106 `(defpargeneric ,name
,second
,@rest
)
107 `(common-lisp:defgeneric
,name
,second
,@rest
)))
111 (defmacro defpargeneric
(name send-func lambda-list
&rest options
)
112 ;; I wanted to use defgeneric, but you can't add your own keyword arguments then.
113 ;; So now there is no source-file-recording and fewer compile-time error-checking.
114 `(progn (when (and *manager
* *defremote-p
*)
115 (loop for space in
(spaces *manager
*)
116 do
(remote-eval space
117 '(let ((*defremote-p
* nil
))
118 (defpargeneric ,name
,send-func
,lambda-list
,@options
)))))
119 (ensure-generic-function
121 :lambda-list
',lambda-list
122 :generic-function-class
(find-class ',(compute-gf-class
124 (second (assoc :generic-function-class
126 :send-func
,(compute-send-func send-func
)
127 ,@(compute-options options
))))
129 (defun make-args (lambda-list)
130 (loop for arg in lambda-list
131 unless
(member arg lambda-list-keywords
)
134 (defun compute-send-func (name)
135 (if (member name
'(:past
:now
:future
))
136 (list 'function
(intern (format nil
"SEND-~a" name
) :nc
))))
138 (defun compute-options (optionlist)
139 (loop for opt in optionlist
140 unless
(eq (first opt
) :generic-function-class
)
143 (defun compute-gf-class (name class
)
144 (if (and (listp name
) (eq (first name
) 'setf
))
145 (cond ((not class
) 'ncl-setf
)
146 ((and (subtypep class
'sending-gf
) (subtypep class
'setf-gf
)) class
)
147 (t (error "a generic-function-class used in defpargeneric for a setf form must be a subclass of sending-gf and setf-gf")))
148 (cond ((not class
) 'ncl-gf
)
149 ((subtypep class
'sending-gf
) class
)
150 (t (error "a generic-function-class used in defpargeneric must be a subclass of sending-gf")))))
153 I want to supply automatic creation of packing methods for structures here
157 (defmacro defstruct
(name &rest rest
)
158 (let ((class-name (cond ((listp name
) (first name
))