1 Star 1 Fork 0

onepisYa/sicp-lisp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
test.sch 4.92 KB
一键复制 编辑 原始数据 按行查看 历史
onepisYa 提交于 4年前 . 4.1 元循环求值器
; 第四章
; --------------------------------
(define eval
; eval 返回一个匿名函数
; 该函数 有两个参数
; exp 是表达式
; env 是环境,或者是是上下文
(
(lambda (exp env)
(cond ((number? exp) exp)
; number 3 => 3
((symbol? exp) (lookup exp env))
; 变量 x => 3
; 从 env 环境 上下文中 查找 变量 x
; 环境是一个字典
((eq? (car exp)) 'quote (car (cdr exp)))
; 'foo => (quote foo) --> foo
; 这个 表达式的意思是 这类表达式 的求值 为它自己
((eq? (car exp)) 'lambda (list 'closure (cdr exp) env))
; (lambda(x)(+ x y)) --> (closure((x)(+ x y)) <env>)
((eq? (car exp)) 'cond (evcond (cdr exp) env))
; (cond (p1 e1) (p2 e2)...)
; p 是谓词, 谓词总是返回 true 或者 false
; e 是表达式
; evcond 是 evaluation the cond 的简写
; 如果我想要 更专业一点, 我会把它设计成 数据导向的
; 那样的话就不会有 这些条件判断, 而是根据一些 bit 位 来做分派
; 这样设计会来的更加专业, 也就是模式匹配。
; ---------------- 以上都是 特殊情况 ----------------
; ---------------- 以下是 默认情况 ----------------
(else (apply(eval (car exp) env)
(evlist (cdr exp) env)))
; (+ x 3) 表达式 应用
)
)
))
; 在这里我们未定义的部分
; evcond
; apply
; evlist
; lookup
; 下面开始实现
; apply 是 把还是符号 状态的求值运算符 和 运算对象, 求值为相应的过程 以及参数值
; 然后把得到的过程应用在参数上。
(define apply
(lambda (proc args)
; procedure
(cond ((primitive? proc )
; primitive 原始的 基本的
(apply-primop proc args))
((eq? (car proc) 'closure)
; 可能有错
(eval (cdr (cdr proc)) (bind (car (cdr proc) args
)))
; 取过程对象的 第二个元素的 第二个元素
)
)
)
)
; --------------------- 书上的代码 --------------------------
; eval
(define (eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp) (lookup-variable-value exp env))
((quoted? exp) (text-of-quotation exp))
((assignment? exp) (eval-assignment exp env))
((definition? exp) (eval-definition exp env))
((if? exp) (eval-if exp env))
((lambda? exp) (make-procedure (lambda-parameters exp)
(lambda-body exp)
env))
((begin? exp)
(eval-sequence (begin-actions exp) env))
((cond? exp) (eval (cond->if exp) env))
((application? exp)
(apply (eval (operator exp) env)
(list-of-values (operator exp) env)))
(else
(error "Unknown expression type -- EVAL" exp))))
; apply
(define (apply procedure arguments)
(cond ((primitive-procedure? procedure)
(apply-primitive-procedure procedure arguments))
((compound-procedure? procedure)
(eval-sequence
(procedure-body procedure)
(extend-environment
(procedure-parameters procedure)
arguments
(procedure-environment procedure))
))
(else
(error
"Unknown procedure type -- APPLY" procedure))))
; list-of-values 过程参数
(define (list-of-values exps env)
(if (no-operands? exps)
'()
(cons (eval (first-operand exps) env)
(list-of-values (rest-operands exps) env)
)
)
)
; eval-if 条件
(define (eval-if exp env)
(if (true? (eval (if-predicate exp) env))
(eval (if-consequent exp) env)
(eval (if-alternative exp) env)
))
;
; eval-sequence 序列
(define (eval-sequence exps env)
(cond ((last-exp? exps) (eval (first-exp exps) env))
(else (eval (first-exp exps) env)
(eval-sequence (rest-exps exps) env)
)
)
)
; eval-assignment 赋值
(define (eval-assignment exp env)
(set-variable-value! (assignment-variable exp)
(eval (assignment-value exp) env)
env
)
'ok
)
; eval-definition 定义
(define (eval-definition exp env)
(define-variable! (definition-variable exp)
(eval (definition-value exp) env)
env
)
'ok
)
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/onepisYa/sicp-lisp.git
git@gitee.com:onepisYa/sicp-lisp.git
onepisYa
sicp-lisp
sicp-lisp
master

搜索帮助