CS61A Scheme


buffer可以看成一个栈,第一个元素是栈顶(current),每次弹出第一个元素(pop_first)
do_xx_form函数传进去的表达式的第一个元素都是xx,然后会在进入函数之前被删除掉,也就是最后进入do_xx_form函数的表达式都是已经删除第一个xx元素的表达式。

P1⭐⭐

scheme_read 读取完整表达式,如果是一个值直接返回,否则栈顶一定是’(',将栈顶删除之后,调用read_tail
read_tail 读取表达式的后部分,先调用scheme_read获得栈顶的值(可能是列表也可能是单值),因为调用scheme_read之后,表达式的栈顶就被pop掉了,因此继续调用read_tail读取除了栈顶元素的表达式后部分,然后将栈顶的值和除了栈顶的值用Pair连接起来。

可以如下图模拟一下比较容易理解
在这里插入图片描述

P2⭐

每个帧里有一个字典保存变量值,除了全局帧,每个帧都有个父亲帧,如果一个变量在当前帧找不到,就去它父亲找,最后都找不到就显示错误。
因此要找一个变量就看当前帧有没有,如果找不到就循环找父亲直到全局帧即可。

P3 ⭐

将scheme表示的Pair转换成python的list即可,然后将当前帧的环境也添加到list末尾

P4 ⭐⭐

给定Pair(其实就是列表)类型的表达式,当前的环境。要求计算出表达式的值。
铺垫:
给了一些可以用的函数:
Pair里面有一个map函数,向map函数传进一个单参数的函数fn,则可获得一个新的Pair, 新Pair的元素由将Pair中每个元素都通过fn进行变换获得
scheme_apply:传入一个操作和一个表达式,返回对表达式进行该操作后的值

因此直接递归调用,将scheme_eval函数作为fn传入Pair的map函数(因为scheme_eval是双参函数,因此可以用一个lambda表达式先将env传进去,将其转变为单参函数),获得Pair每个元素的取值。 然后调用scheme_apply,将Pair的第一个元素作为操作,其余的元素作为操作。

P5 define变量⭐

定义类似c语言的define语句,且只定义变量,不定义行为,因此是很简单的哟。
define函数传入的是一个表达式和环境,表达式是list,list第一个元素是要定义的变量名,第二个元素是要变量名要绑定的值。因此只需要调用一下 s c h e m e _ e v a l scheme\_eval scheme_eval计算一下第二个元素的值,再在环境中将变量名和值绑定即可。

P6 quote & ’ ⭐⭐

q u o t e quote quote就是用来保留它后面的表达式,即不对其进行任何运算直接输出。比如(quote 6),最后获得6。(quote 6 + 7),仍然获得6 + 7。因此在 d o _ q u o t e _ f o r m do\_quote\_form do_quote_form函数中直接返回表达式的第一个元素即可(因为表达式第一个元素 ′ q u o t e ′ 'quote' quote已经被处理掉了。而如果是 ′ ' ,则需要在 s c h e m e r e a d scheme_read schemeread函数中预先处理,将 ′ ' 变成 ′ q u o t e ′ 'quote' quote还需要将’后面的表达式再套进一个pair里,以便和 d o q u o t e f o r m do_quote_form doquoteform统一,因为在 d o q u o t e f o r m do_quote_form doquoteform中会仅提取第一个元素。

P7 eval_all(连续赋值)⭐

eval_all 传入很多个表达式,将所有表达式都赋值之后,eval_all返回最后一个表达式的值。除了第一个,前面的表达式可能会对环境变量产生影响,因此可能对最后一个表达式产生影响,因此需要按顺序赋值哟。

P8 λ \lambda λ

用Pair形式表示一个lambda表达式。但是它已经给了一个类LambdaProcedure来构造了。所以只需要把expressions拆开成【 λ \lambda λ参数formals】和【 λ \lambda λ表达式body】两个部分作为构造类LambdaProcedure的两个参数即可。

P9 define函数 ⭐

在P8的基础上给 λ \lambda λ表达式一个函数名。只需要把给定的expressions拆成【函数名fname】,【 λ \lambda λ参数formals】和【 λ \lambda λbody】三个部分,后面的两部分利用P8形成一个 λ \lambda λ表达式,再在env中将 f n a m e fname fname绑定形成的表达式。

P10 继承帧⭐

原来环境再增加一些变量的绑定。

P11 高阶函数的一小部分⭐

在一个函数a里定义另一个函数b,在函数a调用函数b。
在【调用】函数a会传入参数,因此需要将这些参数绑定到环境中,这题就是用P10进行环境绑定。

P12 ~14 水题

12 and or表达式
13 if-else表达式
14 局部赋值

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值