lisp 表达式求值规则

lisp 表达式求值规则
一个要求值的 lisp 对象被称为lisp表达式(form)。
lisp 表达式分三种
    1. 自求值表达式。前面说过数字、字符串、向量都是自求值表达式。还有两个特殊的符号 t 和 nil 也可以看成是自求值表达式。
    2. 符号表达式。符号的求值结果就是符号的值。如果它没有值,就会出现 void-variable 的错误。
    3. 列表表达式。关键看第一个元素
        列表的第一个表达式如果是一个符号,解释器会查找这个符号的函数值。如果函数值是另一个符号,则会继续查找这个符号的函数值。
       这称为“symbol function indirection”。符号功能追踪
       最后直到某个符号的函数值是:
           1. lisp 函数(lambda 表达式)、byte-code 函数、原子函数( primitive function).
              这是正常的函数调用(function call),求值规则如下:
              先对列表中其它元素求值,求值的结果作为函数调用的真正参数。
              然后使用 apply 函数用这些参数调用函数。
              可以理解为把参数和变量绑定到函数后,对函数体顺序求值,返回最后一个 form 的值。

           2. 宏、
              将宏展开。如果扩展后还是一个宏调用,则会继续扩展下去,直到扩展的结果不再是一个宏调用为止。

           3. 特殊表达式或 autoload 对象。
              这些特殊表达式通常是用于控制结构或者变量绑定。例如IF语句,WHEN 语句等
       每个特殊表达式都有对应的求值规则
    
    4. 以上类型都不是,
    比如某个符号的函数值是前面出现的某个符号导致无限循环,
    或者某个符号函数值为空,
    都会导致一个错误 eval: Symbol’s function definition is void: ...


最后用这个elisp 伪代码来说明一下 elisp 中的求值规则:
(defun eval (exp)
  (cond
   ((numberp exp) exp)
   ((stringp exp) exp)
   ((arrayp exp) exp)
   ((symbolp exp) (symbol-value exp))
   ((special-form-p (car exp))
    (eval-special-form exp))
   ((fboundp (car exp))
    (apply (car exp) (cdr exp)))
   (t
    (error "eval: Symbol's function definition is void: %S" exp))))

参考1: elisp 手册
参考2: 网上资料

猜你喜欢

转载自blog.csdn.net/hejinjing_tom_com/article/details/129198964