我有以下功能(我是 Lisp 的初学者):
(defun my-fun (a b)
(my-commandsend-and-reply-macro (cmd)
(:reply (ok result)
(do-something a b result)))
)
其中 my-commandsend-and-reply-macro 是另一个程序员编写的宏。我无法修改它。
my-commandsend-and-reply-macro 将命令(在此示例中为 cmd)发送到服务器进程(它是用另一种编程语言编写的),然后等待它的回答。然后在宏中使用用户给定的“:reply part of the code”处理答案。列表(ok 结果)是一种模式,在宏中,destructuring-bind 解构并将答案的适当部分绑定到 ok 和 result(ok 只是一个标志)。在此之后,":reply part" 的其他用户给定的行被执行。(用于结果处理)
我想做以下事情:
1、向其他进程发送类似的命令(这样就可以了)
2,使用结果调用函数(如做某事)并使用其他一些参数,这些参数是 my-fun 的实际参数(这部分失败......)
我怎样才能做到这一点?我认为问题是在宏扩展之前没有评估 a 和 b,当宏扩展时 Lisp 搜索本地 a 和 b 但没有 a 或 b。有没有办法评估a和b?(因此宏可以将它们视为具体值)
这是宏定义:(由另一个程序员编写)
(defmacro* my-commandsend-and-reply-macro ((cmd &rest args) &body body)
`(progn
(with-request-id ()
(setf (gethash *request-id* *my-callbacks*)
(lambda (status &rest status-args)
(case status
,@(loop for (kind . clause) in body when (eql kind :reply)
collect
(destructuring-bind
((status-flag &rest lambda-form-pattern)
&body action-given-by-user) clause
`(,status-flag
(destructuring-bind ,lambda-form-pattern status-args
,@action-given-by-user))))
((error)
(message "Error: %s" (elt (elt status-args 0) 1))))))
(apply #'send-command-to-process *request-id* cmd args)))))
with-request-id 的定义:
(defmacro* with-request-id ((&rest vars) &body body)
"Send `getid' to the server, and call `body' once the response
with the new ID has arrived. By then, global variable `*request-id*'
is bound to the latest request ID."
`(progn
(when (not (server-is-running))
(error "Server isn't running!"))
(when *reqid-queue*
(error "Some internal error occured. Please, restart the program!"))
(lexical-let (,@(loop for var in vars
collect `(,var ,var)))
(setf *reqid-queue* (lambda ()
(unwind-protect
(progn ,@body)
(setf *reqid-queue* nil)))))
(get-id)))
并从其他进程获取 id:
(defun get-id ()
(send-command-to-process 'getid))