感谢 2024 级的王浩宸同学
使用Vscode的Debug功能解析
怎么使用Debug
-
直接按照助教的提示修改
.vscode/launch.json
文件即可。其中"args"
是一个数组,记录了将会传入给python scheme
指令的参数。例如下面的例子等价于调用python scheme -i tests.scm
,即对tests.scm
文件执行我们的 scheme 解释器。 -
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "scheme.py",
"args":[
"-i",
"tests.scm"
],
"console": "integratedTerminal",
"justMyCode": true,
}
]
}
- 你可以修改
tests.scm
里面的测试用例来测试,下面是我的例子
(define (factor n acc)
(if (= n 0)
acc
(factor (- n 1) (* acc n))))
(factor 10 1)
-
当然别忘打断点了
-
Debug,启动!
-
点击
Start Debugging
-
-
然后你会发现左边出来这些东西,分别是你的
VARIABLES
、WATCH
、CALL_STACK
VARIABLES
是当前的变量WATCH
可以添加自己想看的表达式或者变量的值CALL_STACK
看调用的堆栈
我们发现他停到了if这个语句停下来了
现在解释器在干啥?
- 我们发现左上角的
expr
的第一个sym
是define
,说明他正在进行do_define_form
怎么让解释器往下走?
在最上面有几个按钮,分别是下面几个
Step Into
如果当前语句是一个call expression
,他就会进入函数体让你看函数体内部是怎么执行的;否则和Step Over
一样。Step Over
:不管是否是call expression
直接当一条普通语句运行过去。Step Out
:跳出当前Frame
(比如A
里面调用了B
函数,我现在通过Step Into
进入了B
所在的Frame
,Step Out
就直接回到A
里面)
所以我们按Step Into
,你会发现他跳过了上面的if
语句;这是因为我们现在是在do_define_form
,并不是尾递归操作,所以就调用原始的eval_call
.
- 我们再次选择
Step Into
,发现:
这个部分就比较好理解了,他就是在做define
的内容,我就不解释了。
做完define form
之后
- 按照解释器解释的规则,我们把
factor
绑定到对应的lambda
函数之后,就会执行(factor 10 1)
那么他的的执行顺序就是(请你注意看左下角的CALL_STACK
)
eval factor
eval 10
eval 1
图略,类似上面apply lambda 10 1