以前為了開發KFP,特別學習了一下lambda calculus(也就是我的博客的標題啦)。lanbda calculus是一門神奇的語言,在計算機出現之前就已經被搞出來了。這門語言只有三種語法,然后可以用這個語法來構造整數(?。。。?、布爾型和很多遞歸數據結構等。
首先介紹一下語法。
1、func arg代表一個函數調用,func是函數表達式,arg是參數。
2、\param.value代表一個函數定義,參數是param,返回結果value。
3、(expr)代表expr的優先級較高。
上面就是所有的語法了。乍一看好像什么都沒有,其實不然。我們現在先看一個東西:函數定義。
為一個函數定義一個名稱是很簡單的:
let double = \num.inc (inc num)) in ...
代碼“...”可以訪問到函數double,但是函數定義的內部卻不行。不過這并不會帶來什么問題(其實是可以遞歸的,有辦法)。當然let-in不是一個合法的lambda calculus程序,不過可以被翻譯為:
(\double. ...) (\num.inc (inc num))
根據語法規則1,可以將后面的整個函數當作實參傳入形參,將所有的double都替換成后面的那個東西,于是double的名稱就被定下來了。
遞歸怎么辦呢?譬如說要寫個函數sum n來計算1+2+...+n的值:
let sum n = if (n==0) 0 (n+(sum (n-1))) in ...
這里為了方便,我們假設所有的運算符都是存在的。其實a op b可以看成函數調用op a b,如果我們給每一個運算符都分配一個名字,實際上就可以用正確的lambda calculus語法來說明了。所以這里為了方便先這么干。
sum內部是看不見sum的,因為翻譯了之后變成:
(\sum. ...) (if (n==0) 0 (n+(sum (n-1))))
那怎么辦呢?既然看不見自己,我可以讓調用者再外部把它自己傳進去當參數總可以吧:
let sum n = \SELF. if (n==0) 0 (n + (SELF (n-1))) in ...
但是我們不能用(sum sum)的方法來調用,因為到了最后(SELF (n-1))變成(sum (n-1)),下一步就錯了。所以我們造了個Y函數:
let Y = \f.(\t.f (t t)) (\t.f (t t)) in
let sum = Y (\SELF. if (n==0) 0 (n + (SELF (n-1)))) in ...
這樣函數\SELF. if (n==0) 0 (n+(SELF (n-1))))就被Y變成了一個真正的遞歸函數了。不過在這里我不想花很大篇幅解釋Y是怎么來的,有興趣的讀者看
這里。
于是我們可以這么定義數字:
zero = \s.\z.z
one = \s.\z.s z
two = \s.\z.s (s z)
three = \s.\z.s (s (s z))
four = \s.\z.s (s (s (s z)))
數字n是一個函數,這個函數接受兩個參數s和z,返回結果是拿s在z上應用n次的結果。所以我們可以很方便的實現乘法:拿“加法”函數當成第一個參數傳進a,然后去應用b,就變成乘法了。我們首先創造一個加1函數:
inc = \a.\s.\z.a s (s z)
然后是加法和乘法:
add = \a.\b.\s.\z.a s (b s z)
mul = \a.\b.\s.\z.a (b s) z
所以對代碼mul (add (one two)) (add (three four))進行求值的時候,我們得到(1+2)*(3+4)=21:\s.\z.(s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s z)))))))))))))))))))))。
布爾值也是一樣的。我們讓true接受兩個參數返回第一個,false接受兩個參數返回第二個:
true = \a.\b.a
false = \a.\b.b
那么and or xor not可以分別寫成:
and = \a.\b.a b false
or = \a.\b.a true b
not = \a.a false true
xor = \a.\b.a (not b) b
函數if cond t f跟cond t f等價,所以我們不需要if函數。
接下來怎么實現數據結構呢?假設我們實現一個pair,讓pair 1 2將數字保存起來,讓first(pair 1 2)返回1,second(pair 1 2)返回2:
pair = \a.\b.\c.c a b
first = \p.p true
second = \p.p false
我們舉一個例子,讓p=pair 1 (pair 2 3),然后求first (second p):
first (second p) =
first (second (pair 1 (pair 2 3))) =
first ((pair 1(pair 2 3)) false) =
first (false 1 (pair 2 3)) =
first (pair 2 3) =
(pair 2 3) true =
true 2 3 =
2
是不是很神奇捏,lambda calculus僅需那么幾條語法就可以實現所有東西了。將pair嵌套在一起可以構成一個列表。下面我們來寫一個完整的程序,構造列表[1,2,3,4,5],然后對每一個元素求平方后相加:1*1 + 2*2 + 3*3 + 4*4 + 5*5 = 55:
下面是完整的程序:
1 let Y = \f.(\t.f (t t)) (\t.f (t t)) in
2
3 let true = \a.\b.a in
4 let false = \a.\b.b in
5 let and = \a.\b.a b false in
6 let or = \a.\b.a true b in
7 let not = \a.a false true in
8 let xor = \a.\b.a (not b) b in
9
10 let zero = \s.\z.z in
11 let inc = \a.\s.\z.a s (s z) in
12 let one = inc zero in
13 let two = inc one in
14 let three = inc two in
15 let four = inc three in
16 let five = inc four in
17 let six = inc five in
18 let seven = inc six in
19 let eight = inc seven in
20 let nine = inc eight in
21 let ten = inc nine in
22 let add = \a.\b.\s.\z.a s (b s z) in
23 let mul = \a.\b.\s.\z.a (b s) z in
24 let sqr = \a.mul a a in
25
26 let pair = \a.\b.\c.c a b in
27 let first = \p.p true in
28 let second = \p.p false in
29 let empty = pair false false in
30 let list = \a.\b.pair true (pair a b) in
31 let head = \xs.(first xs) (first (second xs)) ERROR in
32 let tail = \xs.(first xs) (second (second xs)) ERROR in
33 let join = Y \SELF.\xs.\ys.(first xs) (list (head xs) (SELF (tail xs) ys)) ys in
34 let trans = Y \SELF.\f.\xs.(first xs) (list (f (head xs)) (SELF f (tail xs))) empty in
35
36 let foldl = Y \SELF.\op.\init.\xs.(first xs) (SELF op (op init (head xs)) (tail xs)) init in
37 let foldr = Y \SELF.\op.\init.\xs.(first xs) (op (head xs) (SELF op init (tail xs))) init in
38 let length = foldl (\a.\b.inc a) zero in
39 let sum = foldl add zero in
40
41 let long_list = list one (list two (list three (list four (list five empty)))) in
42
43 sum (trans sqr long_list)
然后是結果。首先我的lambda calculus虛擬機把let-in按照上面的方法重新轉換為標準的lambda calculus程序,最后求值:
數一數吧,上面有55個"(s",所以結果就是55了。
我們添加一個計算a的b次方的函數:pow = \a.\b.b (mul a) one,將最后幾行改成:
let one_to_five = list one (list two (list three (list four (list five empty)))) in
let one_to_ten = join one_to_five (trans (add five) one_to_five) in
let long_list = trans (pow two) one_to_ten in
sum long_list
這計算2^1 + 2^2 + ... + 2^9 + 2^10。結果太長,不截屏幕了,直接復制出來:
1 (\Y.(\true.(\false.(\and.(\or.(\not.(\xor.(\zero.(\one.(\two.(\three.(\four.(\fi
2 ve.(\six.(\seven.(\eight.(\nine.(\ten.(\inc.(\add.(\mul.(\pow.(\sqr.(\pair.(\fir
3 st.(\second.(\empty.(\list.(\head.(\tail.(\join.(\trans.(\foldl.(\foldr.(\length
4 .(\sum.(\one_to_five.(\one_to_ten.(\long_list.(sum long_list) ((trans (pow two))
5 one_to_ten)) ((join one_to_five) ((trans (add five)) one_to_five))) ((list one)
6 ((list two) ((list three) ((list four) ((list five) empty)))))) ((foldl add) ze
7 ro)) ((foldl \a.\b.(inc a)) zero)) (Y \SELF.\op.\init.\xs.(((first xs) ((op (hea
8 d xs)) (((SELF op) init) (tail xs)))) init))) (Y \SELF.\op.\init.\xs.(((first xs
9 ) (((SELF op) ((op init) (head xs))) (tail xs))) init))) (Y \SELF.\f.\xs.(((firs
10 t xs) ((list (f (head xs))) ((SELF f) (tail xs)))) empty))) (Y \SELF.\xs.\ys.(((
11 first xs) ((list (head xs)) ((SELF (tail xs)) ys))) ys))) \xs.(((first xs) (seco
12 nd (second xs))) ERROR)) \xs.(((first xs) (first (second xs))) ERROR)) \a.\b.((p
13 air true) ((pair a) b))) ((pair false) false)) \p.(p false)) \p.(p true)) \a.\b.
14 \c.((c a) b)) \a.((mul a) a)) \a.\b.((b (mul a)) one)) \a.\b.((b (add a)) zero))
15 \a.\b.((b inc) a)) \a.\s.\z.((a s) (s z))) \s.\z.(s (s (s (s (s (s (s (s (s (s
16 z))))))))))) \s.\z.(s (s (s (s (s (s (s (s (s z)))))))))) \s.\z.(s (s (s (s (s (
17 s (s (s z))))))))) \s.\z.(s (s (s (s (s (s (s z)))))))) \s.\z.(s (s (s (s (s (s
18 z))))))) \s.\z.(s (s (s (s (s z)))))) \s.\z.(s (s (s (s z))))) \s.\z.(s (s (s z)
19 ))) \s.\z.(s (s z))) \s.\z.(s z)) \s.\z.z) \a.\b.((a (not b)) b)) \a.((a false)
20 true)) \a.\b.((a true) b)) \a.\b.((a b) false)) \a.\b.b) \a.\b.a) \f.(\t.(f (t t
21 )) \t.(f (t t))))
22 最終結果:
23 \s.\z.(s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
24 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
25 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
26 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
27 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
28 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
29 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
30 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
31 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
32 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
33 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
34 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
35 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
36 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
37 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
38 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
39 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
40 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
41 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
42 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
43 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
44 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
45 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
46 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
47 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
48 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
49 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
50 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
51 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
52 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
53 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
54 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
55 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
56 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
57 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
58 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
59 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
60 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
61 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
62 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
63 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
64 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
65 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
66 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
67 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
68 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
69 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
70 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
71 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
72 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
73 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
74 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
75 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
76 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
77 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
78 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
79 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
80 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
81 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
82 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
83 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
84 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
85 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
86 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
87 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
88 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
89 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
90 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
91 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
92 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
93 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
94 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
95 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
96 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (
97 s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
98 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s
99 (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s (s z)))))))))))))))
100 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
101 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
102 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
103 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
104 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
105 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
106 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
107 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
108 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
109 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
110 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
111 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
112 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
113 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
114 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
115 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
116 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
117 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
118 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
119 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
120 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
121 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
122 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
123 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
124 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
125 )))))))))))))))))))))))))))))))
下面是lambda calculus虛擬機的C++代碼。代碼使用了Vczh Combinator Parser組裝編譯器,然后用一個池來存放運行時需要的東西,速度很快:
1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
2 #include "..\..\..\..\VL++\Library\Data\Data\VL_Data_Map.h"
3 #include "..\..\..\..\VL++\Library\Data\Data\VL_Data_Pool.h"
4 #include "..\..\..\..\VL++\Library\Data\VL_Stream.h"
5 #include "..\..\..\..\VL++\Library\Data\VL_System.h"
6 #include "..\..\..\..\VL++\Library\Data\Grammar2\Combinator\VL_CpKernel.h"
7 #include "..\..\..\..\VL++\Library\Data\Grammar2\Combinator\VL_CpLexer.h"
8
9 using namespace vl;
10 using namespace vl::platform;
11 using namespace vl::stream;
12 using namespace vl::system;
13 using namespace vl::pool;
14 using namespace vl::grammar;
15
16 /*********************************************************************************************************
17 運行時表達式
18 *********************************************************************************************************/
19
20 enum LambdaRuntimeKind
21 {
22 lrkPrimitive,
23 lrkClosure,
24 lrkInvoke
25 };
26 class LambdaRuntime
27 {
28 public:
29 typedef VL_Pool<LambdaRuntime> RuntimePool;
30
31 RuntimePool* Pool;
32 LambdaRuntimeKind Kind;
33 VInt ID;
34 LambdaRuntime* Closure;
35 LambdaRuntime* Expression;
36
37 void SetPrimitive(RuntimePool* aPool , VInt aID)
38 {
39 Pool=aPool;
40 Kind=lrkPrimitive;
41 ID=aID;
42 Closure=0;
43 Expression=0;
44 }
45
46 void SetClosure(RuntimePool* aPool , VInt aID , LambdaRuntime* aExpression)
47 {
48 Pool=aPool;
49 Kind=lrkClosure;
50 ID=aID;
51 Closure=0;
52 Expression=aExpression;
53 }
54
55 void SetInvoke(RuntimePool* aPool , LambdaRuntime* aClosure , LambdaRuntime* aExpression)
56 {
57 Pool=aPool;
58 Kind=lrkInvoke;
59 ID=-1;
60 Closure=aClosure;
61 Expression=aExpression;
62 }
63
64 LambdaRuntime* Alpha(VInt ExpID , LambdaRuntime* Code)
65 {
66 switch(Kind)
67 {
68 case lrkPrimitive:
69 return (ID==ExpID)?Code:this;
70 case lrkClosure:
71 if(ID==ExpID)
72 {
73 return this;
74 }
75 else
76 {
77 LambdaRuntime* NewExpression=Expression->Alpha(ExpID,Code);
78 if(Expression==NewExpression)
79 {
80 return this;
81 }
82 else
83 {
84 LambdaRuntime* AlphaTransformed=Pool->Alloc();
85 AlphaTransformed->SetClosure(Pool,ID,NewExpression);
86 return AlphaTransformed;
87 }
88 }
89 case lrkInvoke:
90 {
91 LambdaRuntime* NewClosure=Closure->Alpha(ExpID,Code);
92 LambdaRuntime* NewExpression=Expression->Alpha(ExpID,Code);
93 if(Closure==NewClosure && Expression==NewExpression)
94 {
95 return this;
96 }
97 else
98 {
99 LambdaRuntime* AlphaTransformed=Pool->Alloc();
100 AlphaTransformed->SetInvoke(Pool,NewClosure,NewExpression);
101 return AlphaTransformed;
102 }
103 }
104 default:
105 return 0;
106 }
107 }
108
109 LambdaRuntime* Evaluate(VBool EvaluatingRoot)
110 {
111 switch(Kind)
112 {
113 case lrkPrimitive:
114 return this;
115 case lrkClosure:
116 if(EvaluatingRoot)
117 {
118 Expression=Expression->Evaluate(true);
119 return this;
120 }
121 else
122 {
123 return this;
124 }
125 case lrkInvoke:
126 {
127 Closure=Closure->Evaluate(false);
128 if(Closure->Kind==lrkClosure)
129 {
130 *this=*Closure->Expression->Alpha(Closure->ID,Expression)->Evaluate(EvaluatingRoot);
131 return this;
132 }
133 else
134 {
135 Expression=Expression->Evaluate(EvaluatingRoot);
136 return this;
137 }
138 }
139 default:
140 return 0;
141 }
142 }
143 };
144
145 class LambdaEnvironment
146 {
147 public:
148 LambdaRuntime::RuntimePool Pool;
149
150 LambdaEnvironment():Pool(65536)
151 {
152 }
153 };
154
155 /*********************************************************************************************************
156 語法樹
157 *********************************************************************************************************/
158
159 class LambdaError
160 {
161 public:
162 VUnicodeString Message;
163
164 LambdaError(VUnicodeString aMessage)
165 {
166 Message=aMessage;
167 }
168 };
169
170 class LambdaIdentifier
171 {
172 public:
173 typedef VL_ListedMap<VUnicodeString , VInt> TokenMap;
174 typedef VL_ListedMap<VInt , VUnicodeString> TokenMapRev;
175
176 VUnicodeString Token;
177 VInt ID;
178
179 LambdaIdentifier()
180 {
181 ID=-1;
182 }
183
184 VBool operator==(const LambdaIdentifier& Identifier)
185 {
186 return ID==Identifier.ID;
187 }
188
189 VBool operator!=(const LambdaIdentifier& Identifier)
190 {
191 return ID!=Identifier.ID;
192 }
193
194 void Initialize(TokenMap& Tokens)
195 {
196 VInt Index=Tokens.IndexOfKey(Token);
197 if(Index==-1)
198 {
199 ID=Tokens.KeyCount();
200 Tokens.Add(Token,ID);
201 }
202 else
203 {
204 ID=Tokens.ValueOfIndex(Index);
205 }
206 }
207
208 void Initialize(TokenMapRev& Tokens)
209 {
210 Token=Tokens[ID];
211 }
212
213 void Collect(TokenMapRev& Tokens)
214 {
215 Tokens.Add(ID,Token);
216 }
217 };
218
219 class LambdaCode : public VL_Base
220 {
221 public:
222 typedef VL_AutoPtr<LambdaCode> Ptr;
223
224 friend LambdaCode::Ptr CreateCode(LambdaRuntime* Runtime);
225
226 virtual void Initialize(LambdaIdentifier::TokenMap& Tokens)=0;
227 virtual void Initialize(LambdaIdentifier::TokenMapRev& Tokens)=0;
228 virtual void Collect(LambdaIdentifier::TokenMapRev& Tokens)=0;
229 virtual VUnicodeString ToString()=0;
230 virtual LambdaRuntime* CreateRuntime(LambdaEnvironment* Environment)=0;
231
232 LambdaCode::Ptr Evaluate()
233 {
234 LambdaEnvironment Environment;
235 LambdaRuntime* Runtime=CreateRuntime(&Environment);
236 LambdaRuntime* Evaluated=Runtime->Evaluate(true);
237 LambdaCode::Ptr Code=CreateCode(Evaluated);
238 LambdaIdentifier::TokenMapRev Tokens;
239 Collect(Tokens);
240 Code->Initialize(Tokens);
241 return Code;
242 }
243 };
244
245 class LambdaCodePrimitive : public LambdaCode
246 {
247 public:
248 LambdaIdentifier Name;
249
250 void Initialize(LambdaIdentifier::TokenMap& Tokens)
251 {
252 Name.Initialize(Tokens);
253 }
254
255 void Initialize(LambdaIdentifier::TokenMapRev& Tokens)
256 {
257 Name.Initialize(Tokens);
258 }
259
260 void Collect(LambdaIdentifier::TokenMapRev& Tokens)
261 {
262 Name.Collect(Tokens);
263 }
264
265 VUnicodeString ToString()
266 {
267 return Name.Token;
268 }
269
270 LambdaRuntime* CreateRuntime(LambdaEnvironment* Environment)
271 {
272 LambdaRuntime* Runtime=Environment->Pool.Alloc();
273 Runtime->SetPrimitive(&Environment->Pool,Name.ID);
274 return Runtime;
275 }
276 };
277
278 class LambdaCodeClosure : public LambdaCode
279 {
280 public:
281 LambdaIdentifier Parameter;
282 LambdaCode::Ptr Expression;
283
284 void Initialize(LambdaIdentifier::TokenMap& Tokens)
285 {
286 Parameter.Initialize(Tokens);
287 Expression->Initialize(Tokens);
288 }
289
290 void Initialize(LambdaIdentifier::TokenMapRev& Tokens)
291 {
292 Parameter.Initialize(Tokens);
293 Expression->Initialize(Tokens);
294 }
295
296 void Collect(LambdaIdentifier::TokenMapRev& Tokens)
297 {
298 Parameter.Collect(Tokens);
299 Expression->Collect(Tokens);
300 }
301
302 VUnicodeString ToString()
303 {
304 return L"\\"+Parameter.Token+L"."+Expression->ToString();
305 }
306
307 LambdaRuntime* CreateRuntime(LambdaEnvironment* Environment)
308 {
309 LambdaRuntime* Runtime=Environment->Pool.Alloc();
310 Runtime->SetClosure(&Environment->Pool,Parameter.ID,Expression->CreateRuntime(Environment));
311 return Runtime;
312 }
313 };
314
315 class LambdaCodeInvoke : public LambdaCode
316 {
317 public:
318 LambdaCode::Ptr Function;
319 LambdaCode::Ptr Argument;
320
321 void Initialize(LambdaIdentifier::TokenMap& Tokens)
322 {
323 Function->Initialize(Tokens);
324 Argument->Initialize(Tokens);
325 }
326
327 void Initialize(LambdaIdentifier::TokenMapRev& Tokens)
328 {
329 Function->Initialize(Tokens);
330 Argument->Initialize(Tokens);
331 }
332
333 void Collect(LambdaIdentifier::TokenMapRev& Tokens)
334 {
335 Function->Collect(Tokens);
336 Argument->Collect(Tokens);
337 }
338
339 VUnicodeString ToString()
340 {
341 return L"("+Function->ToString()+L" "+Argument->ToString()+L")";
342 }
343
344 LambdaRuntime* CreateRuntime(LambdaEnvironment* Environment)
345 {
346 LambdaRuntime* Runtime=Environment->Pool.Alloc();
347 Runtime->SetInvoke(&Environment->Pool,Function->CreateRuntime(Environment),Argument->CreateRuntime(Environment));
348 return Runtime;
349 }
350 };
351
352 LambdaCode::Ptr CreateCode(LambdaRuntime* Runtime)
353 {
354 switch(Runtime->Kind)
355 {
356 case lrkPrimitive:
357 {
358 LambdaCodePrimitive* Primitive=new LambdaCodePrimitive;
359 Primitive->Name.ID=Runtime->ID;
360 return Primitive;
361 }
362 case lrkClosure:
363 {
364 LambdaCodeClosure* Closure=new LambdaCodeClosure;
365 Closure->Parameter.ID=Runtime->ID;
366 Closure->Expression=CreateCode(Runtime->Expression);
367 return Closure;
368 }
369 case lrkInvoke:
370 {
371 LambdaCodeInvoke* Invoke=new LambdaCodeInvoke;
372 Invoke->Function=CreateCode(Runtime->Closure);
373 Invoke->Argument=CreateCode(Runtime->Expression);
374 return Invoke;
375 }
376 default:
377 return 0;
378 }
379 }
380
381 /*********************************************************************************************************
382 語法分析器
383 *********************************************************************************************************/
384
385 enum LambdaTokenID
386 {
387 ltiLet,
388 ltiIn,
389 ltiClosure,
390 ltiName,
391 ltiLeft,
392 ltiRight,
393 ltiDot,
394 ltiEqual,
395 };
396
397 LambdaCode::Ptr ToPrimitive(VL_CpToken Token)
398 {
399 LambdaCodePrimitive* Primitive=new LambdaCodePrimitive;
400 Primitive->Name.Token=VUnicodeString(Token.Start,Token.Length);
401 return Primitive;
402 }
403
404 LambdaCode::Ptr ToInvoke(const VL_CpList<LambdaCode::Ptr>& Input)
405 {
406 LambdaCode::Ptr Code=Input.Head->Data;
407 VL_CpList<LambdaCode::Ptr>::Node::Ptr Current=Input.Head->Next;
408 while(Current)
409 {
410 LambdaCodeInvoke* Invoke=new LambdaCodeInvoke;
411 Invoke->Function=Code;
412 Invoke->Argument=Current->Data;
413 Code=Invoke;
414 Current=Current->Next;
415 }
416 return Code;
417 }
418
419 LambdaCode::Ptr ToClosure(const VL_CpPair<VL_CpToken , LambdaCode::Ptr>& Input)
420 {
421 LambdaCodeClosure* Closure=new LambdaCodeClosure;
422 Closure->Parameter.Token=VUnicodeString(Input.First.Start,Input.First.Length);
423 Closure->Expression=Input.Second;
424 return Closure;
425 }
426
427 LambdaCode::Ptr ToLetIn(const VL_CpPair<VL_CpPair<VL_CpToken , LambdaCode::Ptr> , LambdaCode::Ptr>& Input)
428 {
429 LambdaCodeInvoke* Invoke=new LambdaCodeInvoke;
430 Invoke->Function=ToClosure(VL_CpPair<VL_CpToken , LambdaCode::Ptr>(Input.First.First,Input.Second));
431 Invoke->Argument=Input.First.Second;
432 return Invoke;
433 }
434
435 LambdaCode::Ptr Parse(VUnicodeString Code)
436 {
437 VL_CpLexer Lexer;
438 Lexer
439 <<Token(false,L"let",ltiLet)
440 <<Token(false,L"in",ltiIn)
441 <<Token(false,L"\\",ltiClosure)
442 <<Token(false,L"(",ltiLeft)
443 <<Token(false,L")",ltiRight)
444 <<Token(false,L".",ltiDot)
445 <<Token(false,L"=",ltiEqual)
446 <<Token(false,_Name,ltiName)
447 <<Token(true,_Blank,-1)
448 <<Token(true,_CComment,-1)
449 <<Token(true,_CppComment,-1)
450 ;
451
452 typedef _Wrapper<VL_CpTokenNodePtr , LambdaCode::Ptr> CodeRule;
453 typedef _Terminal<VL_CpTokenNodePtr , LambdaCode::Ptr> CodeTerminal;
454
455 CodeRule Unit,Expr;
456
457 CodeTerminal Primitive =
458 (ToPrimitive <<= Token(ltiName));
459
460 CodeTerminal Closure =
461 (ToClosure <<= ((Toks(L"\\") > Token(ltiName) < Toks(L".")) + Expr));
462
463 CodeTerminal Bracket =
464 (Toks(L"(") > Expr < Toks(L")"));
465
466 CodeTerminal InExpr =
467 Toks(L"in") > Expr;
468
469 Unit=
470 Primitive || Closure || Bracket;
471
472 CodeTerminal Invoke=
473 (ToInvoke <<= ++Unit);
474
475 CodeTerminal LetIn=
476 (ToLetIn <<=((Toks(L"let") > Token(ltiName) < Toks(L"=")) + Expr + InExpr));
477
478 Expr=
479 Invoke || LetIn;
480
481 VL_CpParser<VL_CpTokenNodePtr , LambdaCode::Ptr> Parser=Expr;
482
483 LambdaCode::Ptr Lambda=Parser.Parse(Lexer.Parse(Code.Buffer()).First.Head).Head->Data.First;
484
485 LambdaIdentifier::TokenMap Tokens;
486 Lambda->Initialize(Tokens);
487 return Lambda;
488 }
489
490 /*********************************************************************************************************
491 主程序
492 *********************************************************************************************************/
493
494 void vlmain()
495 {
496 GetConsole()->SetTitle(L"Vczh Lambda Evaluator");
497 GetConsole()->SetTestMemoryLeaks(true);
498 GetConsole()->SetPauseOnExit(true);
499
500 VUnicodeString WorkSpace=VFileName(GetConsole()->GetAppPath()).MakeAbsolute(L"..\\TestData\\").GetStrW();
501 VUnicodeString Code;
502 {
503 VL_FileStream Stream(WorkSpace+L"Program_01.txt",VL_FileStream::vomRead);
504 Code=ReadText(&Stream);
505 }
506
507 try
508 {
509 LambdaCode::Ptr Lambda=Parse(Code);
510 GetConsole()->WriteLine(Lambda->ToString());
511 try
512 {
513 LambdaCode::Ptr Evaluated=Lambda->Evaluate();
514 GetConsole()->WriteLine(L"最終結果:");
515 GetConsole()->WriteLine(Evaluated->ToString());
516 }
517 catch(const LambdaError& Error)
518 {
519 GetConsole()->WriteLine(Error.Message);
520 }
521 }
522 catch(const VL_CpException<VL_CpTokenNodePtr>& e)
523 {
524 if(e.Input)
525 {
526 GetConsole()->WriteLine(L"第"+VUnicodeString(e.Input->Data.Line+1)+L"行,記號\""+VUnicodeString(e.Input->Data.Start,e.Input->Data.Length)+L"\"附近有語法錯誤。");
527 }
528 else
529 {
530 GetConsole()->WriteLine(L"程序末尾附近出現語法錯誤。");
531 }
532 }
533 }
posted on 2009-05-11 04:30
陳梓瀚(vczh) 閱讀(5405)
評論(7) 編輯 收藏 引用 所屬分類:
啟示