
本文是王垠一篇年代久远的文章的笔记,我仿照其中的说明做了一个简单的lisp“解释器”并记录了下来.
准确的来说并不算一个解释器,而更像是一个DSL:在宿主语言中以多位数组(或列表)的形式存在,没有分词和解析的过程,也没有创建AST,而是直接解释运行。
如何用数组表示代码
在lisp中大量使用的S-表达式具有'(+ 1 3)的形式,在python中以列表表示,即["+", 1, 3],操作符放在最前面。
这个S-表达式就是我们解释器的输入
解析一个表达式
有了一个输入后要解析表达式,方便起见所有表达式都只有最多三个参数,而且除if外最多两个。实际上一个就行,在Haskell,F#等语言中只有一元函数,多元函数是通过Currying实现的。
所以只需要判断第一个元素,然后进行运算即可。
以["+", 1, 3]为例,我们发现第一个元素是"+",”+”需要两个参数(这里忽略了一元+和错误处理)分别为1和3,所以进行运算1+3,得到结果4
变量和环境
完成了以上步骤的解释器只是一个普通的计算器,下面我们给它加上”变”量。由于我们对环境的操作,这里的”变”量实际上是不可变的,但我们可以重复绑定。
“环境”由一个单向列表实现,每个表达式都有自己的环境,这使得我们自然的使用了静态作用域。新的变量绑定被添加到源环境的后边形成新环境。由于每个表达式都会先从最内层的作用域开始查找变量,自然的实现了变量的遮蔽。
另外由于实现了变量,而函数也是变量(lambda表达式),所以函数也是可用的了。
条件
但是我们的语言只能顺序执行,下面添加一个条件判断。
加入条件判断其实很简单,在解析的基础上加上判断表达式if即可。
结束
原文没有条件判断,if是我诌的……不要加上if以后大概就是图灵完备的了233
原文的效果为
|
|
我做出来是
|
|
嗯,自我感觉还算可以😂
本博的原创作品作品采用知识共享署名 2.5 中国大陆许可协议 进行许可,欢迎转载,但转载请注明出处,并保持转载后文章内容的完整。
本文链接:http://fallenwood.github.io/2017/02/04/writing-a-simple-lisp/




近期评论