我正在尝试仅使用Lisp基本函数编写Lisp解释器。我正在写评估,但不确定如何检测到',因此我不评估该符号。我知道'x在内部转换为(quote x),我启动了一个Lisp解释器并尝试了以下操作:
(defun my-car (x) (car x))
(my-car (quote x)) -> QUOTE
(my-car '(x)) -> QUOTE
(my-car 'x) -> Error: Attempt to take the car of A which is not listp.
我看到在前两个示例中,汽车将引号检测为第一个元素并将其返回,但我不确定在最后一个示例中为什么不这样做,因为实际上'x应该转换为(quote x)然后作为参数传递给my-car。我需要针对my-eval的一种基本情况进行检查,以便如果引用在原子之前,则不会返回其值。有没有办法只使用原始函数呢?
谢谢!
答案 0 :(得分:2)
Lisp评估是分阶段进行的。
第一阶段是阅读器,它将文本(字符序列)转换为 forms ,即i。 e。列表,符号和文字形式(字符,字符串,数字,数组等)。
阅读器还将'
转换为以下形式的包装引号形式(可能是列表,符号等)。 'a
被读为(quote a)
,被读为'(a)
。
(quote (a))
然后只需要一个规则就如何将Eval
作为运算符来处理。它永远不会看到任何quote
。
答案 1 :(得分:1)
您的Lisp解释器的行为不像Common Lisp。您应该得到:
(defun my-car (x) (car x))
(my-car (quote x)) -> Error: Attempt to take the car of A which is not listp.
(my-car '(x)) -> X
(my-car 'x) -> Error: Attempt to take the car of A which is not listp.
(my-car (list 'QUOTE 'X)) -> QUOTE
(my-car ''x) -> QUOTE
(my-car (quote 'x)) -> QUOTE
(my-car '(quote x)) -> QUOTE
逐步:
源代码:
(my-car ''x)
解析:
(my-car (quote (quote x)))
评估参数
(#<Function MY-CAR> (quote x))
通话功能:
X
这是我的原因,因为符号QUOTE
和符号X
的列表的汽车是QUOTE
。