• 求值环境模拟


    环境 构建和操作

    SICP 的环境构建思路

    frame 相关操作

    SICP 是将环境实现为框架的表,每个框架包含一个variable的链表和一个value的链表
    比如:

    variable  'a  'b 'c 'd
    value:     1   2  3   4
    

    frame提供操作 :(make-frame variables values) ;;cons variables values
    (frame-variables frame) ;;car frame
    (frame-values frame) ;;cdr frame
    (add-binding-to-frame var val frame)

    解释一下: 分别是
    根据一个variables和values的链表构造一个frame
    取出variables链表
    取出values 链表
    添加新的var-value在frame中

    env 定义

    empty-env
    (outer-env env) ;;cdr env
    (first-frame env) ;;cdr env

    (lookup var env)
    (set-var! var new-value env)
    (def-var! var new-value env)

    解释一下:

    • env 的定义就是frame的链表
    • empty-env就是空环境,直接定义为nil( '() )
    • outer-env 就是除了当前框架外的外部环境
      +first-frame就是当前环境

    后面的三个操作十分重要,首先是从环境中找到variable对应的value

    • 第二个是改变环境中var的值
    • 在当前环境中定义变量var

    个人的构造方式

    source code

    #lang planet neil/sicp
    
    (define (make-env variable value)
         (if (=(length variable)(length value) )
             (map cons variable value)
             (error "the numbers of variable and value doesn't match!") ))
    
    (define (env-variable env)
         (map car env))
    (define (env-value env)
         (map cdr env))
    
    (define (add-binding-to-env! var val env)
        (cons (cons var val) env))
    
    (define (lookup-var var env)
       (cond ((null? env) '())
             ((eq? var (car (env-variable env))) (car (env-value env)))
             (else (lookup-var var (cdr env))
             )))
    
    (define (set-var! var new-value env)
       (cond ((null? env) '())
            ( (eq? var (car (env-variable env)))
             (set-car! env (cons var new-value)))
             (else (set-var! var new-value (cdr env)))))
    
    (define (def-var! var new-value env)
       (cond ((null? env) (add-binding-to-env! var new-value env))
              ((eq? var (car (env-variable env)))  (set-car! env (cons var new-value)) )
              (else (set-car! env (cons (cons var new-value) (car env) )   ))))
    
    

    介绍

    大致的思路是,将env表示成 pair 变量的链表,每个pair是var-val键对

    1. make-env:
      首先检查variables和values元素个数是否相等,若相等则利用map进行cons:
      举例: variables: ('a 'b 'c' d)
      values: (1 2 3 4)
      map之后: (('a 1) ('b 2) ('c 3) ('d 4))
    2. empty-env 空环境仍然定义为nil
    3. 提取variables和values的操作仍然由map来完成
    4. 接下来由4个操作:添加新的var-val在env的开头、lookup、set-var!、def-var!
    5. 另外,在racekt中set-car! 没有定义,因此这里第一行说明语言为mit-scheme;
    6. set-car! 等赋值操作只对已经定义的变量有效,而对(set-car! (some-op data) new-value)无效

    分析

    • 其实环境的实现方式不重要,引用第二章的界面约定和抽象屏障的思想,我们只要提供满足约定的界面或者说是接口即可;
    • S型表达式使得我们解析语法结构变得很容易,当然配合scheme本身也是这样的语法结构就更简单了,但是用其它语言来做也大同小异,需要补写一个词法分析
    • 我们的ICS 课程的实验任务是在给定的框架下实现一个完整的模拟器:需要对IA32的绝大多数指令给出模拟,并且需要实现常见的如断点、打印栈帧链、单步执行等功能,也包括程序的加载等等。当然这是用C语言做的啦。 做起来还是很爽的,收获也很大。不过扫了一下第五章用scheme做一个简单的寄存器模拟(貌似只有3条简单的指令),用scheme来写的话,模拟器的速度就更加不忍直视了。。哈哈
    • 但是我个人感觉scheme 的好处就在于抽象层次很高,完全不用担心任何硬件细节,实际程序的效率可能不高,但是用scheme实现同样功能之后收获往往会更大,对这一问题的理解往往到达更加抽象的层次。
    • 最后,其实相对于纯C,个人更喜欢C++,毕竟提供给了更多的可能,对个人写程序而言,更容易符合自己的胃口,C的话不免用很多宏来抽象,不太符合个人对语言的审美。
    • 实验使用的环境是Drracket
  • 相关阅读:
    小小小康
    GC日志补充
    一次GC问题定位
    mycat1.5~1.6的一个bug
    [转] java Statement和PreparedStatement批量更新
    java 中的instanceof 运算符
    Java学习篇之数组方法
    iOS7适配的一点小技巧
    iOS 中正确切换摄像头&正确实现设置帧率的方式
    iOS 音量键事件监控响应
  • 原文地址:https://www.cnblogs.com/gaoduan/p/4066056.html
Copyright © 2020-2023  润新知