最近在讀《The Little Schemer》,一到七章都還好卖丸,到第八章就開始云里霧里了。書讀不透盏道,那么看代碼吧稍浆。好在已經(jīng)有了把示例都整理好了。那么開始吧。
我們期望能寫出一個能對任意表達式求值的函數(shù)衅枫,一般叫它eval
嫁艇。不過,這里為了強調(diào)是我們自己的求值函數(shù)弦撩,叫它 value 步咪。
我們先來看兩個求值過程:
(value 6)
(value '(add1 6)) ; 7
我們不禁要問,這么多函數(shù)是必要的嗎益楼?它們起什么作用猾漫?
顯然,value
是個入口函數(shù)偏形,因為它只用到了一次静袖。
meaning
需要一個表達式和一張記錄變量名和其值的對照表(上下文環(huán)境)。這就引出一個問題俊扭,什么時候改寫對照表队橙?(*application)
接著,由expression-to-action
判斷表達式是否為原子( atom )萨惑,是的話交給atom-to-action
(如果是數(shù)字捐康、真假、cons
, car
, cdr
, null?
, eq?
, atom?
, zero?
, add1
, sub1
, number?
庸蔼,就交給*const
解总;其他交給*identifier
);否則交給list-to-action
姐仅。
函數(shù)分為內(nèi)置函數(shù)( primitive )和自定義函數(shù)( non-primitive )兩類花枫。語言規(guī)定了內(nèi)置函數(shù)的行為,但對于自定義函數(shù)掏膏,我們只能在運行時確定劳翰,所以需要在定義時把它們的相關信息(如:參數(shù)、函數(shù)體)寫進對照表馒疹。
它們分別是這么存儲的:
(primitive primitive-name)
(non-primitive (table formals body)) (上下文 形參 函數(shù)體)
如佳簸,
(lambda (x) (cons x y))
對照表的內(nèi)容是
((( y z)
((8) 9)))
那么,解釋器內(nèi)部是這么存儲的:
其中颖变,list (table formals body)
叫做 closure record .
list-to-action
將quote
, lambda
, cond
之外函數(shù)交由*application
處理生均。*application
對函數(shù)和參數(shù)列表分別進行處理,按函數(shù)類型將primitive
交給apply-primitive
腥刹,而將non-primitive
交給apply-closure
處理马胧。
evlis
對 list 中的各個元素依次求值,把結(jié)果合成一個 list 返回衔峰。
evcon
用于對cond
求值漓雅。
剩下的各位還是看書吧??