人人都能学会程序设计7解释器原理

来源:互联网 发布:太平洋软件站官方网站 编辑:程序博客网 时间:2024/04/28 22:25


 

文字解码完后,你可以想象有一条纸带,上面写着代码。从左侧向左拉动纸带,用剪刀将程序

纸带剪成纸片,在内存中依次摆放这些纸片,然后才可以执行内存中的这些纸片。

 

 

执行内存中代码的时侯,会用到一种名为堆栈(stack)的数据结构(也就是数据的组织处理

方式)。堆栈像个容器,放东西与取东西都在同一端,越晚放进去的东西,越早被取出来(后

进先出)。用通俗一点的比喻:堆栈就像是停车场,越早停进去的车,会停在越里面的位置,

要等到比它晚进的车都开走之后,才能开走。

为什么需要堆栈?因为程序在执行的过程中,有时候需要把某些事暂时保留不做(因为条件不

成熟),等到后面的事做完才能回头去做之前保留的事,这时候用堆栈是最适合的。

从下一页开始连续有好几个范例,你会看到这些范例在执行的过程中堆栈如何变化,而且屏幕

上的输出如何变化。通过这些范例,你应该可以理解解释器的运行原理。

 

 

对于abs -1 这段代码来说,会被剪成两个值:abs -1,然后开始执行。

在状态A,堆栈与屏幕都是空的。然后把abs 放进堆栈中,abs 是求绝对值的函数,它后面

需要跟着一个数字,但堆栈中目前只有abs 自己,所以执行不了,这是状态B

到了状态C,-1 也被放进堆栈。有了这一个参数,abs 终于可以计算了,计算方式是把这两

个值都从堆栈中取出,计算之后得到的值是1,再把放回堆栈,现在是状态D

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行,这表示程序要结束了。

结束时,堆栈中剩下的就是返回值。所以在状态E 中,我们看到堆栈被清空,但屏幕上出

== 1

 

 

 

对于power 2 6 这段代码来说,会被剪成power2这三个值,然后开始执行。

在状态A,堆栈与屏幕都是空的。然后把power 放进堆栈中,成为状态B。power 是求幂的

函数,它后面需要跟着两个数字,分别是底数与指数,所以目前计算不了。状态C,把2 放进

堆栈,依然无法执行。

状态D,把6 放进堆栈,现在power 的两个参数都到齐了,可以计算了。方式是把三个值都

取出来计算,结果得到64,再把结果放回堆栈,进入状态E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中剩下的64 就是返回值。所以在状态F 中,我们看到堆栈被清空,但屏幕上出

== 64

 

 

对于print add 3 -4 这段代码来说,会被剪成printadd3-4 这四个值,然后

解释其原理

 

开始执行。

先把print 放进堆栈,进入状态A。print 需要一个参数,所以此时无法计算。再把add 

进堆栈,进入状态B。add 现在无法当做print 的参数,因为add 自己就是一个函数,必须

add 计算完毕的值才能当print 参数。add 需要两个参数。

-4 被依次放进堆栈,进入状态C。这个时候,add 的两个参数已经到齐,可以计算了。

把这三个值取出来,计算之后得到结果-1,把-1 放回堆栈,现在是状态D

这个时候,print 需要的参数(-1)已经出现了,取出这两个值,计算(执行)的结果是屏

幕上出现-1print 是没有返回值的。没有返回值也就是说返回值是一个特殊值unset(未

设)。unset 放进堆栈中。现在状态是E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中剩下的特殊值unset 就是返回值,返回值为特殊值unset 相当于没有返回值。

所以在状态F 中,我们看到堆栈被清空,屏幕中没有出现==

 

 

对于power 2 6 abs add 3 -4 这段代码来说,会被剪成power26absadd3

-4 这7 个值,然后开始执行。

power2依次放进堆栈,进入状态A。终于可以计算了,计算之后进入状态B。堆栈

中已经没有任何进一步的计算要进行,但内存中还有后续的代码,所以尚未结束。

把内存中的absadd3-4 依次放进堆栈,进入状态C。终于可以计算了,取出最上面的

三个值,计算之后把结果-1 放回堆栈,进入状态D。状态D 也可以计算,取出两个值,计算

结果放回堆栈,进入状态E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中若有多个值,最上层的值就是返回值。所以在状态F 中,我们看到堆栈被清空,

屏幕中出现== 1,而64 直接被扔了。

 

 

这个例子其实有两个段落,所以最后堆栈会有两个值。段落之间彼此独立,因此写代码时,我

们喜欢让段落之间换行,可以帮助阅读理解。

每次发生计算,其实就是找到一个段落。堆栈最后的值分别由power abs 产生,所以它们

两个就是段落的起点。

既然每次发生计算就是一个段落,那么add 应该也是段落的起点。但因为add 只是abs 的一

部分(也就是说它是abs 段落的子段落),而且add 没有兄弟段落(power abs 在这里就

是兄弟关系,是平级的),再说abs 太简单,让abs add 摆一起比较好。把add 段落拆出

去没有太大必要。

最后一个例子。对于power 26 print add 3 -4 这段代码来说,这个例子和前一个例子

差不多,只是abs 换成了print。这导致状态E 的堆栈中有两个值,而最上面的值是特殊值

unset

尽管最后堆栈中存在一个有效值64,但只有最上面的值才是返回值。unset 表示没有返回值。

原创粉丝点击