青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評論-2670  文章-0  trackbacks-0
    以前為了開發(fā)KFP,特別學(xué)習(xí)了一下lambda calculus(也就是我的博客的標(biāo)題啦)。lanbda calculus是一門神奇的語言,在計算機(jī)出現(xiàn)之前就已經(jīng)被搞出來了。這門語言只有三種語法,然后可以用這個語法來構(gòu)造整數(shù)(!!!)、布爾型和很多遞歸數(shù)據(jù)結(jié)構(gòu)等。

    首先介紹一下語法。
    1、func arg代表一個函數(shù)調(diào)用,func是函數(shù)表達(dá)式,arg是參數(shù)。
    2、\param.value代表一個函數(shù)定義,參數(shù)是param,返回結(jié)果value。
    3、(expr)代表expr的優(yōu)先級較高。

    上面就是所有的語法了。乍一看好像什么都沒有,其實不然。我們現(xiàn)在先看一個東西:函數(shù)定義。
    為一個函數(shù)定義一個名稱是很簡單的:
    let double = \num.inc (inc num)) in ...
    代碼“...”可以訪問到函數(shù)double,但是函數(shù)定義的內(nèi)部卻不行。不過這并不會帶來什么問題(其實是可以遞歸的,有辦法)。當(dāng)然let-in不是一個合法的lambda calculus程序,不過可以被翻譯為:
    (\double. ...) (\num.inc (inc num))
    根據(jù)語法規(guī)則1,可以將后面的整個函數(shù)當(dāng)作實參傳入形參,將所有的double都替換成后面的那個東西,于是double的名稱就被定下來了。

    遞歸怎么辦呢?譬如說要寫個函數(shù)sum n來計算1+2+...+n的值:
    let sum n = if (n==0) 0 (n+(sum (n-1))) in ...
    這里為了方便,我們假設(shè)所有的運(yùn)算符都是存在的。其實a op b可以看成函數(shù)調(diào)用op a b,如果我們給每一個運(yùn)算符都分配一個名字,實際上就可以用正確的lambda calculus語法來說明了。所以這里為了方便先這么干。

    sum內(nèi)部是看不見sum的,因為翻譯了之后變成:
    (\sum. ...) (if (n==0) 0 (n+(sum (n-1))))
    那怎么辦呢?既然看不見自己,我可以讓調(diào)用者再外部把它自己傳進(jìn)去當(dāng)參數(shù)總可以吧:
    let sum n = \SELF. if (n==0) 0 (n + (SELF (n-1))) in ...
    但是我們不能用(sum sum)的方法來調(diào)用,因為到了最后(SELF (n-1))變成(sum (n-1)),下一步就錯了。所以我們造了個Y函數(shù):
    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 ...
    這樣函數(shù)\SELF. if (n==0) 0 (n+(SELF (n-1))))就被Y變成了一個真正的遞歸函數(shù)了。不過在這里我不想花很大篇幅解釋Y是怎么來的,有興趣的讀者看這里

    于是我們可以這么定義數(shù)字:
    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)))
    數(shù)字n是一個函數(shù),這個函數(shù)接受兩個參數(shù)s和z,返回結(jié)果是拿s在z上應(yīng)用n次的結(jié)果。所以我們可以很方便的實現(xiàn)乘法:拿“加法”函數(shù)當(dāng)成第一個參數(shù)傳進(jìn)a,然后去應(yīng)用b,就變成乘法了。我們首先創(chuàng)造一個加1函數(shù):
    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))進(jìn)行求值的時候,我們得到(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接受兩個參數(shù)返回第一個,false接受兩個參數(shù)返回第二個:
    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
    函數(shù)if cond t f跟cond t f等價,所以我們不需要if函數(shù)。

    接下來怎么實現(xiàn)數(shù)據(jù)結(jié)構(gòu)呢?假設(shè)我們實現(xiàn)一個pair,讓pair 1 2將數(shù)字保存起來,讓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僅需那么幾條語法就可以實現(xiàn)所有東西了。將pair嵌套在一起可以構(gòu)成一個列表。下面我們來寫一個完整的程序,構(gòu)造列表[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)

    然后是結(jié)果。首先我的lambda calculus虛擬機(jī)把let-in按照上面的方法重新轉(zhuǎn)換為標(biāo)準(zhǔn)的lambda calculus程序,最后求值:


    數(shù)一數(shù)吧,上面有55個"(s",所以結(jié)果就是55了。

    我們添加一個計算a的b次方的函數(shù):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。結(jié)果太長,不截屏幕了,直接復(fù)制出來:

  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 falsefalse)) \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 最終結(jié)果:
 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虛擬機(jī)的C++代碼。代碼使用了Vczh Combinator Parser組裝編譯器,然后用一個池來存放運(yùn)行時需要的東西,速度很快:

  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 運(yùn)行時表達(dá)式
 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"最終結(jié)果:");
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"程序末尾附近出現(xiàn)語法錯誤。");
531         }
532     }
533 }

posted on 2009-05-11 04:30 陳梓瀚(vczh) 閱讀(5429) 評論(7)  編輯 收藏 引用 所屬分類: 啟示

評論:
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-11 05:54 | cy
500幾行就誕生了一門語言.......  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-11 06:32 | suxiaojack
牛!
這個語法太酷了。
to cy :加上頭文件不只500多行。
  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-11 08:21 | cy
那些頭文件屬于這個語言的“設(shè)計支持”部分,暫時不算進(jìn)去~~

感覺這樣的語言到達(dá)了電路設(shè)計級別  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-12 06:28 | yindf
127 行的Evaluate 參數(shù)是false,
236 行的Evaluate 參數(shù)是true,

可能會造成不一致吧?

236行的true表示應(yīng)用序求值(先求值,后代換),但是127行的false表示不對前面的閉包求值,所以這個閉包是正則序求值的(先代換,后求值)。于是就可能造成不一致。

不知道我理解的對不對,請指教。  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-13 00:53 | 陳梓瀚(vczh)
@yindf
不是這個意思,Evaluate=false指的是盡可能少求值,譬如對于一個函數(shù)表達(dá)式來說,(\x.(\y.y) x) 1和(\x.x) 1在對被調(diào)用函數(shù)的處理上是沒區(qū)別的,但是對于程序的結(jié)果來說,(\x.(\y.y) x)和(\x.x)是有區(qū)別的。所以Evaluate的意思其實是【正在求值的表達(dá)式是否根表達(dá)式】。如果\x.y是根表達(dá)式,那么y也是。如果\x.y z是跟表達(dá)式,那么y和z不算根表達(dá)式。  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-13 01:29 | yindf
@陳梓瀚(vczh)

其實問題是一樣的,主要是你對表達(dá)式怎么求值的問題,比如:

\x.x 1+2 這個式子,你是要
先算1+2=3呢, (1)
還是把\x.x 1+2直接替換成1+2? (2)

如果你想做(1)的話,那么在(\x.(\y.y) x) 1中,(\x.(\y.y) x)就應(yīng)該先被計算成 (\y.y),然后再\y.y 1

如果(2)的話,那么在(\x.(\y.y) x) 1中,先把x換成1,變成(\y.y) 1

(1)表示對所有函數(shù),先求出參數(shù)表達(dá)式,然后再帶入。
(2)表示先把參數(shù)直接帶入展開,展開到最底層,最后一起求值。

在函數(shù)式編程里面,比如一個函數(shù)接受另一個函數(shù)做參數(shù),那么你是要先計算參數(shù)的值呢,還是直接把參數(shù)帶進(jìn)去?

因為我感覺你在用(1)方法,所以我覺得函數(shù)在使用前應(yīng)該求值。

其實問題的本質(zhì)是函數(shù)在使用前應(yīng)不應(yīng)該被化簡,對于采用應(yīng)用序的語言來說,應(yīng)該。  回復(fù)  更多評論
  
# re: 丘奇數(shù)(Church Numerals)和lambda calculus 2009-05-13 07:00 | 陳梓瀚(vczh)
@yindf
函數(shù)使用前不簡化(只需要變成一個lambda表達(dá)式即可,lambda里面的內(nèi)容不理),不然你無法對那個傳說中的Y函數(shù)求值,會死循環(huán)的。你可以去學(xué)習(xí)一下惰性求值。  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产欧美一区二区三区同亚洲| 亚洲一级黄色| 久久一综合视频| 久久激情一区| 在线播放一区| 亚洲国产aⅴ天堂久久| 欧美国产视频在线观看| 亚洲色无码播放| 中文在线不卡视频| 国产人成一区二区三区影院| 久久精品国产99国产精品| 欧美中文字幕在线播放| 亚洲第一精品在线| 亚洲国产综合在线看不卡| 欧美日韩亚洲一区三区| 久久激情五月激情| 麻豆精品精华液| 亚洲一级在线| 久久国产直播| 99精品国产99久久久久久福利| 一区二区三区波多野结衣在线观看| 亚洲第一福利在线观看| 亚洲午夜一二三区视频| 国内在线观看一区二区三区 | 国产精品国产三级国产aⅴ浪潮| 午夜精彩国产免费不卡不顿大片| 久久爱另类一区二区小说| 亚洲精品一区二区三区蜜桃久| 亚洲少妇自拍| 亚洲激情视频在线播放| 亚洲一区国产| 亚洲人成网站999久久久综合| 日韩亚洲在线观看| 黄色精品一区| 亚洲综合色婷婷| 亚洲蜜桃精久久久久久久| 午夜影视日本亚洲欧洲精品| 亚洲精品国精品久久99热| 午夜国产一区| 亚洲深夜福利在线| 嫩草国产精品入口| 久久精品av麻豆的观看方式| 欧美日韩岛国| 亚洲高清av| 亚洲第一精品久久忘忧草社区| 亚洲一区精品视频| 亚洲午夜激情网页| 欧美国产国产综合| 欧美大片在线观看| 国模精品娜娜一二三区| 亚洲综合国产| 亚洲在线观看| 欧美日韩成人在线播放| 亚洲第一中文字幕在线观看| 精品二区视频| 久久久精品免费视频| 久久精品夜色噜噜亚洲aⅴ| 欧美小视频在线| 99视频一区二区三区| 一本不卡影院| 欧美日本亚洲韩国国产| 亚洲国产欧美在线人成| 亚洲精品视频免费| 欧美a级片网| 亚洲国产欧美一区二区三区同亚洲| 亚洲大片免费看| 久久综合九色九九| 蜜臀久久99精品久久久久久9| 黄色一区二区在线| 久久免费少妇高潮久久精品99| 乱中年女人伦av一区二区| 极品日韩av| 欧美a级片一区| 亚洲美女视频网| 亚洲欧洲av一区二区| 国产酒店精品激情| 久久国产精品亚洲va麻豆| 久久婷婷色综合| 亚洲欧洲一区| 欧美日韩亚洲免费| 亚洲在线第一页| 久久综合导航| 亚洲精品在线视频观看| 欧美色图天堂网| 午夜久久久久久久久久一区二区| 久久久久久一区二区三区| 伊人蜜桃色噜噜激情综合| 欧美精品午夜视频| 欧美激情女人20p| 一二美女精品欧洲| 久久成人资源| 亚洲日本无吗高清不卡| 欧美日韩在线视频首页| 欧美亚洲视频一区二区| 欧美激情中文字幕一区二区 | 国产精品毛片a∨一区二区三区|国| 午夜精品一区二区三区电影天堂| 美女图片一区二区| av成人黄色| 黄色小说综合网站| 欧美人交a欧美精品| 欧美伊人久久久久久午夜久久久久 | 亚洲精品视频二区| 国产欧美日韩视频一区二区| 免费欧美网站| 午夜精品一区二区三区电影天堂 | 亚洲男女自偷自拍| 亚洲成人资源| 久久精品亚洲热| 99视频精品免费观看| 国产色综合网| 欧美日韩午夜在线视频| 久久久青草青青国产亚洲免观| 99精品国产热久久91蜜凸| 另类尿喷潮videofree| 亚洲女同性videos| 亚洲伦理网站| 在线观看不卡av| 国产午夜精品一区理论片飘花| 欧美精品日韩www.p站| 久久久噜噜噜| 欧美一区二区三区的| 亚洲视频高清| 亚洲精品乱码视频| 免费观看成人www动漫视频| 欧美在线观看视频在线| 亚洲午夜小视频| 99riav国产精品| 亚洲精品视频在线观看网站 | 国产精品久久久一区麻豆最新章节| 美女图片一区二区| 久久精品99无色码中文字幕| 亚洲一区二区三区国产| 99re6热只有精品免费观看| 亚洲高清不卡一区| 蜜臀av一级做a爰片久久| 久久久久在线观看| 久久成人久久爱| 欧美一区二区三区免费看| 亚洲欧美一区在线| 亚洲一区区二区| 亚洲欧美日韩另类精品一区二区三区| 99视频精品全部免费在线| 99精品国产在热久久| 99国产一区二区三精品乱码| 一本色道久久| 中文在线资源观看网站视频免费不卡 | 亚洲精品日韩一| 亚洲麻豆一区| 欧美一级在线视频| 亚洲电影自拍| 欧美福利一区| 亚洲欧洲精品成人久久奇米网| 欧美成人一区二区在线| 亚洲成色777777女色窝| 最近看过的日韩成人| 亚洲日本电影| 亚洲午夜精品一区二区三区他趣| 亚洲婷婷综合色高清在线| 亚洲欧美综合v| 久久久久久一区| 欧美韩国在线| 国产精品呻吟| 激情欧美亚洲| 99riav1国产精品视频| 亚洲在线观看免费| 久久久久久69| 亚洲国产另类 国产精品国产免费| 日韩视频在线观看国产| 亚洲欧美区自拍先锋| 狼人天天伊人久久| 欧美日韩在线一区二区三区| 国产欧美日韩不卡免费| 亚洲第一毛片| 亚洲综合国产激情另类一区| 久久久久99| 亚洲免费成人av电影| 欧美制服丝袜| 欧美日本韩国| 国产一区二区三区网站| 亚洲作爱视频| 毛片基地黄久久久久久天堂| 亚洲精品一二三区| 久久精品人人| 国产精品99免视看9| 亚洲第一在线视频| 亚洲欧美中文在线视频| 欧美国产精品专区| 亚洲欧美日韩国产中文在线| 嫩草影视亚洲| 国模精品一区二区三区色天香| 一区二区三区欧美在线| 免费美女久久99| 亚洲自拍偷拍视频| 欧美无砖砖区免费| 亚洲精品欧洲| 欧美gay视频激情| 欧美在线网站| 国产日本精品| 香蕉久久精品日日躁夜夜躁|