我正在通过l99来学习lisp。如何构建这个lisp宏?
这是从here,我希望应用宏只是为了练习,写一个宏的所有((x) (x (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
s。
(defun evaluate-boolean (expression bindings)
"Evaluates the boolean expression. Returns t or nil
expression := variable
| constant
| '(' operator expression expression ')'
| '(' not expression ')'
.
constant := 'true' | 'fail' .
variable := symbol .
operator := 'and' | 'or' | 'nand' | 'nor' | 'xor' | 'impl' | 'equ' .
bindings is a list of pairs (variable . constant)
"
(cond ((eq expression 'true) t)
((eq expression 'fail) nil)
((symbolp expression)
(let ((pair (assoc expression bindings)))
(if pair
(progn
(assert (member (cdr pair) '(true fail)))
(eql 'true (cdr pair)))
(error "No variable named ~A in the bindings." expression))))
((atom expression) (error "Invalid atom ~A in the expression." expression))
(t (case (length expression)
((2) (destructuring-bind (op subexpression) expression
(case op
((not) (not (evaluate-boolean subexpression bindings)))
(otherwise (error "Invalid operator ~A in ~A" op expression)))))
((3) (destructuring-bind (op left right) expression
(case op
((and) (and (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((or) (or (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((nand) (nand (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((nor) (nor (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((xor) (xor (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((impl) (impl (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((equ) (equ (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
(otherwise (error "Invalid operator ~A" op)))))
(otherwise (error "Invalid expression ~A" expression))))))
我已经尝试了一些东西,但他们似乎都给出错误报告失踪的变量。
我将如何实现宏
- 作为
defmacro
,或 - 使用
macrolet
,在evaluate-boolean
函数内?
我通常测试出来的东西与defun
或defmacro
第一,然后替换用flet
。对此有何建议?
感谢您解释内部/外部的宏观事物! – ackerleytng