the little scheme interpreter
程序员文章站
2024-02-10 23:32:52
...
#lang sicp
;entry是一个pair,(list1 list2),list1为一个set,list1和list2数量相等
(define build
(lambda (s1 s2)
(cond
(else (cons s1
(cons s2 (quote ())))))))
;s1和s2为两个s表达式
(define new-entry build)
;table是entry的list,(entry1 entry2 entry3 ...)
;extend-table为往table添加新的entry
;解释器:找出表达式的类型,然后使用相关的action
;不同的类型,进行不同的解释(计算)
;一个application,第一个元素为一个function
;如果e为(car (a b c)),那么(function-of e)就为car
;(meaning car table),需要先求出car的action,结果为*const
;使用*const进行解释,结果为(primitive car)
;然后再apply
;(car (quote ()))
;============================
;解释器
;解释器:找出表达式的类型,然后使用相关的类型进行解释
;将表达式传递给解释器
;第一步,找出表达式的类型
;大的方面,有两种:表达式为一个原子,表达式为一个list
;原子的有*const,*identifier
;list的有*quote,*lambda,*cond,*application
;第二步,根据不同的类型,进行不同的解释,计算出结果
;原子类型的解释,包括*const和*identifier的解释
;*const的解释
;包括数字,bool和内置函数
;*identifier的解释
;从table中查找标识符的值
;list的解释,包括*quote,*lambda,*cond,*application
;*quote的解释
;取出pair中的第二个元素
;*lambda的解释
;代表一个非内置函数,需要记住形参和函数体
;将lambda解释为一个pair,该pair为(non-primitive 闭包)
;其中闭包用于记住:形参、函数体以及环境(也就是table)
;表现为(table 形参 函数体)
;*cond的解释
;cond本身为(question answer)的一个list
;解释为:依次求question的值,如果为true,则求对应的answer的值
;如果为else,则else这个question为true,求对应的answer的值
;(meaning '(car l) '(((l) ((a b c)))))
;注意,书中例子无法直接从value求值,只能从meaning求值
;*application的解释
;application由两部分组成,函数和实参
;重点:函数部分使用(primitive xxx)或者是(non-primitive closure)来进行表示
;例如e为(car l) table为(((l) ((a b c)))) 非内置函数e为(add1 n) table为(((n) (5)))
;car为内置函数,或者叫原始函数
;add1为非内置函数
;先求出函数部分
;先说内置函数
;(function-of e)为car,然后求值(meaning car table)
;先判断car的类型为*const,然后使用*const进行解释,结果为(primitive car),即函数部分使用(primitive car)来进行表示
;然后求出参数值,l为(a b c),使用evlis函数
;然后调用apply-primitive,找到对应的类型,求出值
;值为a
;再说非内置函数non-primitive
;首先为函数部分
;(function-of e)为add1,然后求值(meaning add1 table),得出add1的类型为*identifier
;然后使用*identifier来解释add1,也就是从table中查找add1,table中add1为一个lambda
;然后使用*lambda来解释,得到一个包含闭包的pair,值为(non-primitive closure),其中closure为(table n (+ n 1)),table为(),此table为闭包的table(重点)
;即函数部分使用(non-primitive closure)来进行表示
;然后求参数n的值,即为5
;然后调用apply-closure,即:(meaning 函数体 扩展后的环境)
;首先需要扩展环境,将((n) (5)),扩展到闭包中的环境table中,也就是(cons '((n) (5)) '()),结果为(((n) (5)))
;然后得到(+ n 1)的类型为*application,再次递归,得到内置函数+,从扩展table中取出n的值为5,然后调用函数,得到结果6
;倒推
;传入的e
;(meaning '(car l) '(((l) ((a b c))))),而不是'(car (a b c)),倒着推也可以推出来
;闭包中扩展table部分为:
;(extend-table (new-entry 'n 5) '())
;(((n) (5)))
;然后进行evlis得到5
;闭包总结:
;函数+环境(环境中包含函数中*变量以及它的值)
;闭包总结2:
;将application解析为闭包+参数的值
;用参数的值扩展闭包中的环境
;用新环境对闭包进行求值
推荐阅读
-
the little scheme interpreter
-
[Scheme]循环读入并计算数字之和
-
Scheme宏的二三事
-
HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂)
-
phpstrom--------config php interpreter
-
常用的URL Scheme
-
CentOS 安装软件出现错误:/lib/ld-linux.so.2: bad ELF interpreter 解决
-
解决Pycharm下面出现No R interpreter defined的问题
-
<转>使用JIRA搭建企业问题跟踪系统(三) 项目管理Scheme配置管理MySQLWorkflow
-
过程和数据的演化 数据结构Scheme编程Unix