我有一个宏来为程序定义初始化变量。该宏是...
(defmacro defparm (var value &key (frequency nil) (date nil date-supplied-p))
"Macro to define starting parameters."
`(let ((new-value (set-value ,value ,frequency)))
(cond ((eq ,date-supplied-p t)
(set-variation ',var new-value (make-date ,date)))
(t (setf (slot-value *my-parms* ',var) new-value)))))
该宏依赖于宏 set-value 和 set-variation,以及函数 is-date-p 和 is-percent-p。
(defun is-percent-p (value)
(cond ((and (symbolp value) (char= (char (symbol-name value) (1- (length (symbol-name value)))) #\%)))
((and (stringp value) (char= (char value (1- (length value))) #\%)))
(t nil)))
(defmacro set-value (value &optional frequency)
`(cond ((and (typep ',value 'symbol) (is-percent-p ',value))
(let ((new-value (string-right-trim "%" (symbol-name ',value))))
(/ (if (find #\. new-value)
(parse-float:parse-float new-value)
(parse-integer new-value :junk-allowed nil)) 100.0)))
(t ,value)))
我没有包括 is-date-p,因为它与这种情况无关,并且 set-variation 可以简单地被虚拟出来......
(defun set-variation (&rest x)
(declare (ignorable x)))
当我评估...
(defparm interest-rate 5%)
我明白了......
(defparm interest-rate 5%); 在:DEFPARM INTEREST-RATE;(SET-VALUE 5% NIL);--> IF IF AND IF TYPEP;==>;1;;捕获警告:;未定义变量:COMMON-LISP-USER::5%;;编译单元完成;未定义变量:;5%;捕获 1 警告条件 0.05 0.05
结果是正确的,0.05,但我不明白为什么会收到警告。
我已经输入(打印 nn)语句以尝试确定出现警告的位置,即评估 '5% 符号的位置,但我找不到它。
我的代码中的“警告”的实际点在哪里?!
如果我们充分扩展你的表达(“行走”),那么我们会得到如下结果:
您可以看到,在第一个子句中
cond
有一个子句(t 5%)
。这就是5%
变量的位置。通常我会通过宏扩展相应的代码片段来调试这些内容(并且编译器可能会给我未定义的变量位置等):
set-value
需要在宏扩展时调用is-percent-p
,而不是在扩展中调用。