我试着构造一个函数模板,我可以在其他包中使用特定于包的参数。我试图实现这一目标的要点如下:
;;; FSM
(in-package #:fsm)
(defmacro %cas (flag old new)
#+sbcl `(sb-ext:compare-and-swap ,flag ,old ,new)
#+ecl `(mp:compare-and-swap ,flag ,old ,new)
)
(defmacro control! (fsm task flag)
`(let ((*task-category* (tag ,task)))
(unless (%cas ,flag nil t)
(lambda () (submit-task (channel (cqueue-prio-out ,fsm)) (fn ,task))))))
;;; REPL
(in-package #:repl)
(defparameter *controller-active* nil)
(control! fsm control-task *controller-active*)
;;; USB-SP
(in-package #:usb-sp)
(defparameter *controller-active* nil)
(control! fsm control-task *controller-active*)显然,这是行不通的:
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001640703}>:
Invalid place to CAS: CNC-HOST/FSM::FLAG -> CNC-HOST/FSM::FLAG这个构造是如何正确完成的?
发布于 2020-07-21 14:58:31
在收到有关freenode lisp通道的反馈后,我清楚地看到宏构造可以按预期工作:
(defpackage #:fsm (:use #:cl) (:export #:control!! #:%cas))
(defpackage #:repl (:use #:cl #:fsm) (:export #:test-in-repl))
(defpackage #:usb-sp (:use #:cl #:fsm) (:export #:test-in-usb-sp))
;;; FSM
(in-package #:fsm)
(defmacro %cas (flag old new)
#+sbcl `(sb-ext:compare-and-swap ,flag ,old ,new)
#+ecl `(mp:compare-and-swap ,flag ,old ,new))
(defmacro control!! (flag pkg)
`(lambda () (if (%cas ,flag nil t)
(format nil "~A : skip task" ,pkg)
(format nil "~A : task run" ,pkg))))
;;; REPL
(in-package #:repl)
(defparameter *controller-active* nil)
(defun test-in-repl (pkg) (funcall (control!! *controller-active* pkg)))
(assert (string= "repl : task run" (test-in-repl "repl")))
(assert *controller-active*)
;;; USB-SP
(in-package #:usb-sp)
(defparameter *controller-active* nil)
(defun test-in-usb-sp (pkg) (funcall (control!! usb-sp::*controller-active* pkg)))
(assert (string= "usb-sp : task run" (test-in-usb-sp "usb-sp")))
(assert *controller-active*)
(in-package #:cl-user)
(assert (string= "repl : skip task" (repl:test-in-repl "repl")))
(assert (string= "usb-sp : skip task" (usb-sp:test-in-usb-sp "usb-sp")))编译器消息让我认为我的宏中有错误-相反,我忽略了在我的用例中,control!!应该返回函数调用结果,而不是lambda。
https://stackoverflow.com/questions/63001750
复制相似问题