This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainland License.

下面是 the little schemer 中的 简单interpreter实现以及在DrRacket中的一步步的调试观察。

这里注意运行下面的代码需要设置一下

另外,使用DrRacket的调试来step by step 观察 Scheme 程序运行非常不错。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;a simple scheme interpreter run on scheme (DrRacket 5.3)
;date:2012-9-3

;some trivil functions
(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define first
  (lambda (p)
    (car p)))

(define second
  (lambda (p)
    (car (cdr p))))

(define third
  (lambda (p)
    (car (cdr (cdr p)))))

(define build
  (lambda (s1 s2)
    (cons s1 (cons s2 (quote ())))))

(define new-entry build)

;entry and table
(define lookup-in-entry-help
  (lambda (name names values entry-f)
    (cond
      ((null? names) (entry-f name))
      ((eq? (car names) name) (car values))
      (else (lookup-in-entry-help name (cdr names) (cdr values) entry-f)))))

(define lookup-in-entry
  (lambda (name entry entry-f)
    (lookup-in-entry-help name
                          (first entry)
                          (second entry)
                          entry-f)))

(define extend-table cons)

(define lookup-in-table
  (lambda (name table table-f)
    (cond
      ((null? table) (table-f name))
      (else (lookup-in-entry name
                             (car table)
                             (lambda (name)
                               (lookup-in-table name (cdr table) table-f)))))))

;;;;;;;;;;;actions
(define atom-to-action
  (lambda (e)
    (cond
      ((number? e) *const)
      ((eq? e #t) *const)
      ((eq? e (quote cons)) *const)
      ((eq? e (quote car)) *const)
      ((eq? e (quote cdr)) *const)
      ((eq? e (quote null?)) *const)
      ((eq? e (quote eq?)) *const)
      ((eq? e (quote atom?)) *const)
      ((eq? e (quote zero?)) *const)
      ((eq? e (quote add1)) *const)
      ((eq? e (quote sub1)) *const)
      ((eq? e (quote number?)) *const)
      (else *identifier))))

(define list-to-action
  (lambda (e)
    (cond
      ((atom? (car e))
       (cond
         ((eq? (car e) (quote quote)) *quote)
         ((eq? (car e) (quote lambda)) *lambda)
         ((eq? (car e) (quote cond)) *cond)
         (else *application)))
      (else *application))))

(define expression-to-action
  (lambda (e)
    (cond
      ((atom? e) (atom-to-action e))
      (else (list-to-action e)))))

;*const action
(define *const
  (lambda (e table)
    (cond
      ((number? e) e)
      ((eq? e #t) #t)
      ((eq? e #f) #f)
      (else (build (quote primitive) e)))))

;*quote action
(define text-of second)

(define *quote
  (lambda (e table)
    (text-of e)))

;identifier action
(define initial-table
  (lambda (name)
    (car (quote ()))))

(define *identifier
  (lambda (e table)
    (lookup-in-table e table initial-table)))

;*lambda action
(define *lambda
  (lambda (e table)
    (build (quote non-primitive)
           (cons table (cdr e)))))

;*cond action
(define table-of first)

(define formals-of second)

(define body-of third)

(define else?
  (lambda (x)
    (cond
      ((atom? x) (eq? x (quote else)))
      (else #f))))

(define question-of first)

(define answer-of second)

(define evcon
  (lambda (lines table)
    (cond
      ((else? (question-of (car lines)))
       (meaning (answer-of (car lines)) table))
      ((meaning (question-of (car lines)) table)
       (meaning (answer-of (car lines)) table))
      (else (evcon (cdr lines) table)))))

(define cond-lines-of cdr)

(define *cond
  (lambda (e table)
    (evcon (cond-lines-of e) table)))

;*application action
(define evlis
  (lambda (args table)
    (cond
      ((null? args) (quote ()))
      (else
       (cons (meaning (car args) table)
             (evlis (cdr args) table))))))

(define function-of car)

(define arguments-of cdr)

(define primitive?
  (lambda (l)
    (eq? (first l) (quote primitive))))

(define non-primitive?
  (lambda (l)
    (eq? (first l) (quote non-primitive))))

(define :atom?
  (lambda (x)
    (cond
      ((atom? x) #t)
      ((null? x) #t)
      ((eq? (car x) (quote primitive)) #t)
      (else #f))))

(define apply-primitive
  (lambda (name vals)
    (cond
      ((eq? name (quote cons))
       (cons (first vals) (second vals)))
      ((eq? name (quote car))
       (car (first vals)))
      ((eq? name (quote vals))
       (cdr (first vals)))
      ((eq? name (quote null?))
       (null? (first vals)))
      ((eq? name (quote eq?))
       (eq? (first (second vals))))
      ((eq? name (quote atom?))
       (:atom? (first vals)))
      ((eq? name (quote zero?))
       (zero? (first vals)))
      ((eq? name (quote add1))
       (add1 (first vals)))
      ((eq? name (quote sub1))
       (sub1 (first vals)))
      ((eq? name (quote number?))
       (number? (first vals))))))

(define apply-closure
  (lambda (closure vals)
    (meaning (body-of closure)
             (extend-table
              (new-entry (formals-of closure) vals) (table-of closure)))))

(define apply
  (lambda (fun vals)
    (cond
      ((primitive? fun)
       (apply-primitive (second fun) vals))
      ((non-primitive? fun) (apply-closure (second fun) vals)))))

(define *application
  (lambda (e table)
    (apply
     (meaning (function-of e) table)
     (evlis (arguments-of e) table))))

;;;;;;;;;value--the interpreter entrance
(define meaning
  (lambda (e table)
    ((expression-to-action e) e table)))

(define value
  (lambda (e)
    (meaning e (quote ()))))

;;;;test examples;;;
;;DrRacket中注释代码COMMENT in DrRacket:    select codes and press ctrl + alt + ";"
;;DrRacket中取消注释UNCOMMENT in DrRacket:  select codes and press ctrl + alt + "="

;example1.(meaning e table)是什么,其中e是(lambda (x) (cons x y)),table 是(((y z) ((8) 9)))。

;(define e '(lambda (x) (cons x y)))
;(define table '(((y z) ((8) 9))))
;(meaning e table)

;example2.(*cond e table), 其中e是(cond (coffee klastsch) (else party)), table 是 (((coffee) (#t)) ((klastsch party) (5 (6))))

;(define e '(cond (coffee klastsch) (else party)))
;(define table '(((coffee) (#t)) ((klastsch party) (5 (6)))))
;(*cond e table)

;example3.
(define e '((lambda (nothing)
              (cond
                (nothing (quote something))
                (else (quote nothing))))
            #t))
(value e)

the little schemer 笔记(10.1)的更多相关文章

  1. the little schemer 笔记(10)

    第十章 What Is  the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...

  2. 操作系统概念学习笔记 10 CPU调度

    操作系统概念学习笔记 10 CPU调度 多道程序操作系统的基础.通过在进程之间切换CPU.操作系统能够提高计算机的吞吐率. 对于单处理器系统.每次仅仅同意一个进程执行:不论什么其它进程必须等待,直到C ...

  3. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  4. 《C++ Primer Plus》学习笔记10

    <C++ Primer Plus>学习笔记10 <<<<<<<<<<<<<<<<<&l ...

  5. SQL反模式学习笔记10 取整错误

    目标:使用小数取代整数 反模式:使用Float类型 根据IEEE754标识,float类型使用二进制格式编码实数数据. 缺点:(1)舍入的必要性: 并不是所有的十进制中描述的信息都能使用二进制存储,处 ...

  6. JAVA自学笔记10

    JAVA自学笔记10 1.形式参数与返回值 1)类名作为形式参数(基本类型.引用类型) 作形参必须是类的对象 2)抽象类名作形参 需要该抽象类的子类对象,通过多态实现 3)接口名为形参 需要的是该接口 ...

  7. golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息

    golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...

  8. Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息

    </pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...

  9. Python标准库笔记(10) — itertools模块

    itertools 用于更高效地创建迭代器的函数工具. itertools 提供的功能受Clojure,Haskell,APL和SML等函数式编程语言的类似功能的启发.它们的目的是快速有效地使用内存, ...

随机推荐

  1. Java 兔子问题(斐波那契数列)扩展篇

    Java兔子问题(斐波那契数列)扩展篇 斐波那契数列指的是这样一个数列 0, 1, 1, 2,3, 5, 8, 13, 21, 34, 55, 89, 144, ...对于这个数列仅仅能说将兔子生产周 ...

  2. 李洪强iOS开发之-实现点击单行View显示和隐藏Cell

    李洪强iOS开发之-实现点击单行View显示和隐藏Cell 实现的效果:  .... ....

  3. 小程序多级下拉菜单demo

    小程序多级下拉菜单demo - CSDN博客 https://blog.csdn.net/github_39371177/article/details/80251211

  4. QT下QThread学习(二)

    学习QThread主要是为了仿照VC下的FTP服务器写个QT版本.不多说,上图. FTP服务器的软件结构在上面的分析中就已经解释了,今天要解决的就是让每一个客户端的处理过程都可以按一个线程来单独跑.先 ...

  5. XMU C语言程序设计实践(5)

    •       使用动态链表完成一个简单的商品库存信息管理系统. •       商品信息包括如下字段:商品号.商品名称.商品库存 •       函数 create:接收用户输入的商品号和商品名称的 ...

  6. 基于MATLAB的滤波算法

    目前比较经典的图像去噪算法主要有以下三种: 均值滤波:也称线性滤波,主要思想为邻域平均法,即用几个像素灰度  的平均值来代替每个像素的灰度.有效抑制加性噪声,但容易引起图像模糊,  可以对其进行改进, ...

  7. vue-router-h5-history

    vue-router的HTML5 History 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面. const router = new V ...

  8. 执行sql语句异常...需要的参数与提供的值个数不匹配

    执行mysql语句时,出现以下错误时. 看错误提示,提示说你的sql语句只需要5个参数,而你提供了8个值value,你确定你确实需要8个参数,而你的sql语句却提示说只需要5个参数 这时,请仔细检查一 ...

  9. [Selenium] 配置 Internet Explorer Driver 的注意事项

    1)请确保 IEDriverServer 的可执行文件在系统环境变量PATH 中 2)在IE7 和以上版本的 Internet Explorer 上,必须确保保护模式的正确配置.设置方式为 Tools ...

  10. 「NOIP2012」「LuoguP1083」 借教室

    Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的 ...