欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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解析为闭包+参数的值
;用参数的值扩展闭包中的环境
;用新环境对闭包进行求值




相关标签: scheme scheme