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

隨筆-341  評論-2670  文章-0  trackbacks-0
 
花了兩天時間,集成了以前開發(fā)的山寨Office2007的Ribbon框架,和之前開發(fā)的Intellisense算法和控件,打算做一個可以點擊Run之后出一只小烏龜畫圖的小demo哇哈哈。然后以此作為Vczh Library++ 3.0的第一個Release的Demo。

vle.exe大概已經(jīng)做完了,現(xiàn)在checkin了一個vlscript.dll的框架,但是還沒有實現(xiàn)里面的具體的函數(shù)。到時候這個用C#寫的demo就會調(diào)用C++寫的vlscript.dll,來實現(xiàn)烏龜畫圖功能。

這個破IDE的代碼在“Tools\Release\VleSource\VlTurtle\VlTurtle.csproj”,大家有興趣的話可以去下載。打開那個solution,然后用release編譯,然后再release目錄下執(zhí)行Deploy.bat之后,就可以F5看到效果了。

此時的心情簡直無以倫比。

posted @ 2011-02-24 08:54 陳梓瀚(vczh) 閱讀(25397) | 評論 (26)編輯 收藏
    Vczh Library++ 3.0這破東西也做了一年半了,因此打算給它制作第一個Release。這個Release將計劃包含下面的東西:

    1、vle.exe。這是一個編譯器和虛擬機的命令行程序。通過這個程序可以把NativeX程序編譯成assembly、可以執(zhí)行基于控制臺的assembly程序、以及運行我為這個平臺開發(fā)的一個單元測試工具。這些是已經(jīng)開發(fā)完成的了。接下來還要給vle.exe添加鏈接功能。所謂的鏈接功能是指將多個assembly合并成一個,并且預先展開所有模板函數(shù)、模板變量和concept mapping等等。雖然NativeX程序跟C語言很像(多了泛型和concept mapping),也需要頭文件,不過其機制并不像#include那樣把文件復制進去,而是類似pascal。為了調(diào)用另一個assembly而必須的頭文件可以讓編譯器在編譯的過程中產(chǎn)生,不需要人去維護。

    2、vlscript.dll。這是一個編譯器和虛擬機的函數(shù)庫。這個函數(shù)庫將會制作成C而不是C++的格式。我在盡可能讓vlscript.dll包含vle.exe所具有的全部功能以外,還要添加一些其他的譬如可以遍歷一個assembly里面各種聲明什么的的一些功能,以便二次開發(fā)的時候可以利用vlscript.dll完成很多有趣的事情。

    3、TurtleDotNet.exe。這暫時還是一個設想。還記得舊社會的LOGO語言吧?最近新出的Microsoft Small Basic也跟LOGO一樣可以使用烏龜畫圖。這是一個很好的教程式的函數(shù)庫,因此我也打算做一個。因為時間的關系,我并不會在第一個Release里面包含一個NativeX的IDE,而只是包含一個C#寫的窗口程序,可以讀取assembly并提供烏龜畫圖的功能。這也同時展示了C#如何跟C的dll進行互操作。

    4、各種NativeX的demo?,F(xiàn)在已經(jīng)開發(fā)好的demo包含一個四則運算分析器的程序。這個程序從字符串生成語法樹(NativeX也可以利用虛函數(shù)表來模擬多態(tài),雖然這需要人肉完成而不是語法完成),然后做各種事情。我還附帶一個四則運算分析庫的單元測試程序。另一個開發(fā)好的demo是一個猜數(shù)字游戲。程序隨機產(chǎn)生4個0-9范圍內(nèi)的數(shù)字,然后讓你也輸入4個,告訴你命中了多少,半命中(數(shù)字對位置不對)了多少,然后一直到你放棄或者猜中為止,程序結束。

    上面已經(jīng)開發(fā)好的東西已經(jīng)check in在codeplex里面了,感興趣的話可以自行下載。不過那個vle.exe是以源代碼的形式存放的(不像Release,都是編譯好的東西),因此如果想要看到效果的話,需要裝有Visual Studio 2010。編譯完之后,在Tools\Release\Vlpp\和Tools\Release\Vlpp\ScriptSample\CrossAssemblyInvoking\Binary\下面有Readme.txt,會告訴你在編譯完vle.exe之后如何部署他們,使得上述的兩個NativeX demo可以編譯和運行。

    拭目以待吧,哇哈哈。
posted @ 2011-02-19 23:29 陳梓瀚(vczh) 閱讀(3513) | 評論 (1)編輯 收藏

流水賬。

今年春節(jié)回家的時候帶了三本書。去年中秋節(jié)的時候外服發(fā)了200塊錢的卓越卡(啊,不是公司的,啊,說出來沒人信),我覺得自己還是個看書的人,因此買了8本書。不過我覺得自己大概不是個做文學的人,所以買的都是些什么數(shù)學啊物理的民科書。里面有本講時間的,原本以為是物理,結果是本哲學書,堅持到看完了才知道。之后8本只看了1/4本,于是到了春節(jié)。家里的電腦是02年買的,到現(xiàn)在就跟屎一樣,因此給家里添置了一臺。不過在這之前的三天,只能把上網(wǎng)的時間用來看書了,然后把這本書給解決掉了。接下來解決了那本哲學的,現(xiàn)在在看一本我也不知道他在說什么的。

我是懷著一種什么心情來看書的呢?覺得不看書就如同有負罪感一般,因此總是千方百計想把它們看完??赐甑臅r候是什么感覺呢?除了接收到了知識感到欣喜以外,還有一種神奇的感覺類似“如釋重負”的感覺。我覺得很不舒服。

對比起自己更加喜愛的編程,我突然想起在大學的時候,不寫程序也是有負罪感的,不過現(xiàn)在沒有了。當時其實我也很坦白,說不寫程序會有負罪感,并且引以為豪,以此證明自己是一個愛寫程序的人?,F(xiàn)在想起來是有點滑稽。人每天都說話,說話就是生活,但有一兩天你沒說話,你有沒有負罪感呢?想必是沒有的。沒有人會覺得一兩天不說話會對不起自己或者對不起別人。當然吃飯是不一樣的,不吃飯是會死的。寫程序?qū)τ诂F(xiàn)在的我來說就如同說話。寫程序就是生活,但是有一兩天你沒寫程序,其實也覺得沒什么,這種事常有。但是自己是不會因此就再也不寫程序的,就如同你自己不會因為一兩天不說話就永遠不說話一樣。當然如果你一兩天不吃飯,估計就永遠不吃飯了……

那寫程序?qū)τ谖沂鞘裁茨兀砍踔械臅r候,覺得寫程序很有意思,自己搞著搞著總能擺弄出一點事情來,沒有理過微軟的fellow們。高中的時候,覺得寫程序是一種追求,很有遠大理想,看到了微軟主頁上的那三十多個fellow,覺得自己將來就是想成為他們一樣的人。大學的時候,覺得寫程序是一種義務,雖然自己再也不拿fellow當終極目標了,覺得修煉自己就是一種快樂,覺得反正自己的目標大概是要成為一個厲害的人的,不管將來是不是fellow都無所謂。到了現(xiàn)在,寫程序儼然變成了生活的一部分。自己仍然對自己有嚴厲的要求,寫出來的代碼要高性能要好改還要富有藝術感,但已經(jīng)不覺得厲害不厲害是一件多么大不了的事情了。我就是寫程序,寫程序就是我,反正遲早是要厲害的,那只是時間問題,也就不執(zhí)著于那個了。

因此我現(xiàn)在沒有宣稱自己是喜歡寫程序的人了,而宣稱我自己就是寫程序的人。想必當年覺得“喜歡寫程序”就是自己身份的一個標簽,認為只要不寫程序,我也就不成為我,而且對不起貼在身上的標簽了。如今,程序還是在寫,但標簽已經(jīng)沒了。激情在,理想在,功夫也在,程序也一直在寫。只是寫程序已經(jīng)變成了自己想寫就寫,不想寫就不寫,隨心所欲的狀態(tài)了。

因此對比起看書,說不定自己仍然很在意“喜歡看民科書”的標簽。實際上我也是這么做的,對外宣稱自己是喜歡看民科書的人,而不是看民科書的人,跟寫程序相反。所以大概會有這種感覺罷。

想想以前也有過不少愛好,譬如4歲的時候開始的鋼琴,8歲的時候開始的看民科書。10歲的時候開始的糊變形金剛,14歲的時候開始的寫程序。堅持下來的也就是看民科書跟寫程序了。然后經(jīng)歷都是差不多的,一個事情自己做得好,然后就慢慢有了追求,然后就變成了標簽,如果順利的話那個事情也就成為了生活了。

什么時候看民科書能成為生活呢?我想能看的民科書的數(shù)量也是有限的,大概也只能當個標簽吧,說不定哪天自己寫程序?qū)懰?,也寫寫跟編程相關的民科書,然后就貼上了個“喜歡寫民科書”的標簽了。

posted @ 2011-02-08 09:09 陳梓瀚(vczh) 閱讀(4274) | 評論 (13)編輯 收藏
    今天做了一整天終于優(yōu)化了kd-tree和Ambient Occlusion。先上代碼,后上圖。

    首先是做了一個kd-tree,渲染一幅有一千三百多萬個三角形的圖僅需要0.4秒。


    其次是Ambient Occlusion


    第三幅是對比圖。上圖有Ambient Occlusion,下圖沒有。
 

    再加兩張(博客發(fā)布后才添加的)。算法沒變,只不過多了模型,就暫時不更新代碼了:


posted @ 2011-01-21 22:45 陳梓瀚(vczh) 閱讀(11510) | 評論 (11)編輯 收藏
    最近休了幾天假玩一玩所以進展比較慢。直到今天我做了高亮、4*4全屏幕消鋸齒、圓柱體和三角形模型。不過目前三角形我沒有用kd-tree,所以巨慢。在i7上做一個36096個面的Menger Sponge再加上全屏幕消鋸齒花掉了20分鐘……

    點擊這里下載當前進度的代碼。

    下面開始貼圖:

    Blinn Specular:


    全屏幕消鋸齒:


    傳說中三萬多個三角形的Menger Sponge


    無聊做的圓柱體求交函數(shù):
posted @ 2011-01-20 09:10 陳梓瀚(vczh) 閱讀(5211) | 評論 (9)編輯 收藏

    每年總有那么幾個星期不想寫編譯器,這個時候做做ray tracing就變成一件很美妙的事情了。因此這個星期重寫了當年那個超爛的光線追蹤,然后加上了貼圖的功能。當然圖是可以直接貼在物體上的,還支持了法線貼圖,譬如說下面做的地球在不同方向的光線的照射下顯得有立體效果:


    之所以FPS有16是因為我已經(jīng)不再當年那個破thinkpad上渲染,而在一個i7四核超線程三通道的CPU上做了。渲染的時候為了簡單,把屏幕等分成了八行,然后創(chuàng)建八個線程分別綁定到八個CPU上面去(SetThreadAffinityMask),最后渲染完出來。當然比起那些專業(yè)的還是顯得相當慢,現(xiàn)在很多光線追蹤軟件都用了GPU來做,不過我GPU也沒用,SSE指令也沒用,就純粹C++寫。如今也懶得用C++做GUI了,所以把核心用C++做成了之后,export幾個函數(shù)出來,用C#的P/Invoke直接調(diào)用。C++渲染完以后給一個HBITMAP,C#拿過來就往窗口上畫,還是十分方便的哈。多語言開發(fā)萬歲。

    重寫了光線追蹤之后仍然把折射和反射給做了,因此可以做出個類似凸透鏡一樣的東西:


    需要提一下的是,做貼圖的時候?qū)崿F(xiàn)了nearest、linear和bicubic三種插值方法。nearest基本上就是不插值,所以放大了之后會有馬賽克效果。linear是線性插值,如果放得太大還是能看出一點模糊的馬賽克。bicubic效果就好很多了,如果大家有興趣的話可以到這里去看。為了達到更好的效果,后面還有計劃做ray differential和各向異性過濾。ray differential之后就可以做photon mapping(一種比較高效的全局光照模型)了。做完photon mapping之后,無聊的心情大概就結束了,可以繼續(xù)寫編譯器了吧。

    嗯嗯,雖然ray differential和photon mapping還沒做,我就先把代碼丟上啦,不僅可以做備份,大家也能搞下來看一看。當然需要有Visual Studio 2010才能編譯的。選擇release編譯之后到release文件夾下去啟動,debug的話慢的不能忍。而且我的多線程模型是一個核(超線程的話算兩個)一個線程,那些古老的雙核CPU大概性能會很慘不忍賭吧……

 

posted @ 2011-01-08 23:54 陳梓瀚(vczh) 閱讀(7012) | 評論 (15)編輯 收藏
    根據(jù)之前的計劃,讓Vczh Library++3.0的編譯器變成語言的公共后端的同時,開放幾乎所有層的API讓人們可以從各種基礎上開發(fā)自己的DSL,所以在做完NativeX之后,接下來的事情就是寫必要程度的庫之后,做一些基礎設施讓托管語言可以被編譯到NativeX上面去。因此現(xiàn)在需要完成的東西有:
    1、內(nèi)存池,用來實現(xiàn)NativeX的new和delete。這個已經(jīng)做完了。下一篇文章將詳細描述這個內(nèi)存池的結構。
    2、線程和同步對象。這個很快就做完了。NativeX的線程不僅需要有基本的功能,還需要做一個內(nèi)置的消息循環(huán)。當一部分線程選擇使用消息循環(huán)作為它的結構的時候,其他線程就可以把一些代碼片段發(fā)送給這個線程執(zhí)行了。并且要做到跟C#一樣,當線程被外部強行中止的時候,線程內(nèi)部會拋出一個異常,然后讓線程自己去處理。
    3、基本的字符串和數(shù)學函數(shù)庫
    4、垃圾收集器。這個垃圾收集器是不屬于NativeX的語法的。這個垃圾收集器將被開發(fā)成一個NativeX的函數(shù)庫,用于支持更高層次語言的編譯。

    當然為了完成這個目標,我給NativeX加上了一些無關痛癢但是卻會帶來方便的語法:
    1、#public編譯選項。只要在structure、function或者variable上面標記了#public的話,這個特殊的標志就會被記錄在編譯后的二進制文件的元數(shù)據(jù)里面。NativeX現(xiàn)在的元數(shù)據(jù)分為兩種。第一種是運行時元數(shù)據(jù)。之前的文章提到NativeX的模板函數(shù)和其他模板的東西都是可以直接編譯進二進制文件的,因此模板函數(shù)的實例化實際上是在運行是的時候做的。不過現(xiàn)在我也實現(xiàn)了一個編譯選項(不屬于NativeX,需要用C++去控制),可以在編譯完所有二進制文件之后,將他們合并成一個大的二進制文件并且預先展開所有需要的模板函數(shù)。這一步可以用于加快運行速度,還可以為將來運行時編譯成x86或者x64做準備。當#public被記錄到元數(shù)據(jù)里面之后,編譯器就可以從編譯好的二進制文件里面重新還原出該二進制文件的頭文件。
    2、sizeof(type)、offsetof(type::member)、typeof(expression)和typeof(type::member)。這個純粹是為了配合內(nèi)存池和未來的垃圾收集器而做出來的。當你需要alloc一個東西的時候,你顯然需要知道一個類型的尺寸,而這個是會跟隨著不同的情況而變化的,所以就給出了這些東西,讓編譯器幫助你計算各種跟類型相關的數(shù)字。
    3、常量定義。這個還沒實現(xiàn),到時候的語法可能會是constant type name = value;。而且當他被標記上#public之后,就可以在生成頭文件的時候包含該常量了。

    為了讓C++可以給NativeX添加外部函數(shù),我做了一個輔助類用來簡化這個過程。舉個例子,我們需要實現(xiàn)一個叫做MemCreate的創(chuàng)建內(nèi)存池的函數(shù)。首先我們需要在NativeX里面聲明它:
1 structure __ForeignHandle
2 {
3 }
4 
5 foreign function __ForeignHandle* __MemCreate()
6     alias SystemCoreForeignFunctions.MemCreate;

    這里的alias后面的一大串是外部函數(shù)的名稱,而__MemCreate則是他對于NativeX的名稱。接下來我們就得在C++實現(xiàn)這個函數(shù)了:
  1 #include "ScriptingUtilityForeignFunctions.h"
  2 #include "..\Languages\LanguageRuntime.h"
  3 #include "..\..\Entity\GeneralObjectPoolEntity.h"
  4 #include "..\..\Threading.h"
  5 
  6 namespace vl
  7 {
  8     namespace scripting
  9     {
 10         namespace utility
 11         {
 12             using namespace basicil;
 13             using namespace entities;
 14             using namespace collections;
 15 
 16             class SystemCoreMemoryManagerPlugin : public LanguagePlugin
 17             {
 18             public:
 19                 struct PoolPackage
 20                 {
 21                     GeneralObjectPool                    pool;
 22                     CriticalSection                        cs;
 23 
 24                     PoolPackage(vint poolUnitSize, vint poolUnitCount)
 25                         :pool(poolUnitSize, poolUnitCount)
 26                     {
 27                     }
 28                 };
 29 
 30                 List<Ptr<PoolPackage>>                    pools;
 31                 CriticalSection                            pluginCs;
 32 
 33                 class MemCreate : public Object, public IBasicILForeignFunction
 34                 {
 35                 protected:
 36                     SystemCoreMemoryManagerPlugin*        plugin;
 37                 public:
 38                     MemCreate(SystemCoreMemoryManagerPlugin* _plugin)
 39                         :plugin(_plugin)
 40                     {
 41                     }
 42 
 43                     void Invoke(BasicILInterpretor* interpretor, BasicILStack* stack, void* result, void* arguments)
 44                     {
 45                         LanguageArgumentReader reader(result, arguments, stack);
 46                         Ptr<PoolPackage> pool=new PoolPackage(1048576256);
 47 
 48                         CriticalSection::Scope scope(plugin->pluginCs);
 49                         plugin->pools.Add(pool);
 50                         reader.Result<PoolPackage*>()=pool.Obj();
 51                     }
 52                 };
 53 
 54                 static vint MemAlloc(void* result, void* arguments)
 55                 {
 56                     LanguageArgumentReader reader(result, arguments);
 57                     PoolPackage* pool=reader.NextArgument<PoolPackage*>();
 58                     vint size=reader.NextArgument<vint>();
 59 
 60                     CriticalSection::Scope scope(pool->cs);
 61                     reader.Result<char*>()=pool->pool.Alloc(size);
 62                     return reader.BytesToPop();
 63                 }
 64 
 65                 static vint MemFree(void* result, void* arguments)
 66                 {
 67                     LanguageArgumentReader reader(result, arguments);
 68                     PoolPackage* pool=reader.NextArgument<PoolPackage*>();
 69                     char* pointer=reader.NextArgument<char*>();
 70                     
 71                     CriticalSection::Scope scope(pool->cs);
 72                     reader.Result<bool>()=pool->pool.Free(pointer);
 73                     return reader.BytesToPop();
 74                 }
 75 
 76                 static vint MemIsValidHandle(void* result, void* arguments)
 77                 {
 78                     LanguageArgumentReader reader(result, arguments);
 79                     PoolPackage* pool=reader.NextArgument<PoolPackage*>();
 80                     char* pointer=reader.NextArgument<char*>();
 81                     
 82                     CriticalSection::Scope scope(pool->cs);
 83                     reader.Result<bool>()=pool->pool.IsValid(pointer);
 84                     return reader.BytesToPop();
 85                 }
 86 
 87                 static vint MemGetHandleSize(void* result, void* arguments)
 88                 {
 89                     LanguageArgumentReader reader(result, arguments);
 90                     PoolPackage* pool=reader.NextArgument<PoolPackage*>();
 91                     char* pointer=reader.NextArgument<char*>();
 92                     
 93                     CriticalSection::Scope scope(pool->cs);
 94                     reader.Result<vint>()=pool->pool.GetSize(pointer);
 95                     return reader.BytesToPop();
 96                 }
 97 
 98                 static vint MemGetOwnerHandle(void* result, void* arguments)
 99                 {
100                     LanguageArgumentReader reader(result, arguments);
101                     PoolPackage* pool=reader.NextArgument<PoolPackage*>();
102                     char* pointer=reader.NextArgument<char*>();
103                     
104                     CriticalSection::Scope scope(pool->cs);
105                     reader.Result<char*>()=pool->pool.GetHandle(pointer);
106                     return reader.BytesToPop();
107                 }
108             protected:
109                 bool RegisterForeignFunctions(BasicILRuntimeSymbol* symbol)
110                 {
111                     return
112                         symbol->RegisterForeignFunction(L"SystemCoreForeignFunctions", L"MemCreate"new MemCreate(this)) &&
113                         symbol->RegisterLightFunction(L"SystemCoreForeignFunctions", L"MemAlloc", MemAlloc) &&
114                         symbol->RegisterLightFunction(L"SystemCoreForeignFunctions", L"MemFree", MemFree) &&
115                         symbol->RegisterLightFunction(L"SystemCoreForeignFunctions", L"MemIsValidHandle", MemIsValidHandle) &&
116                         symbol->RegisterLightFunction(L"SystemCoreForeignFunctions", L"MemGetHandleSize", MemGetHandleSize) &&
117                         symbol->RegisterLightFunction(L"SystemCoreForeignFunctions", L"MemGetOwnerHandle", MemGetOwnerHandle);
118                 }
119             };
120 
121             Ptr<LanguagePlugin> CreateMemoryManagerPlugin()
122             {
123                 return new SystemCoreMemoryManagerPlugin();
124             }
125         }
126     }
127 }

    外部函數(shù)分兩種,一種是需要全局狀態(tài)的,而另一種不需要。在不需要的時候,我提供了一個不會跟虛函數(shù)打交道的接口來加快(雖然其實可以忽略,只是為了滿足那些有畸形性能欲望的人的心理而已)運行時的性能。

    就先說到這里了。NativeX函數(shù)庫的測試用例已經(jīng)開始在做了,可以去Vczh Library++3.0下載最新代碼之后,在下面的目錄找到:
    Library\Scripting\Utility\:這里是外部函數(shù)的實現(xiàn)。
    UnitTest\Binary\ScriptCoreLibrary\:這里是NativeX將外部函數(shù)簡單的封裝起來之后的函數(shù)庫,以及他們的測試用例。我為NativeX實現(xiàn)了一個簡單的單元測試框架。
    UnitTest\UnitTest\TestScripting_Utility_System_CoreNative.cpp:這個是NativeX單元測試框架的host。
posted @ 2011-01-01 05:14 陳梓瀚(vczh) 閱讀(3937) | 評論 (7)編輯 收藏

距離元旦也就十幾天了,2010就要過去了。從第一行Hello World到現(xiàn)在,已經(jīng)有10年了,所幸從未中斷,因此從某種意義上來講,我已經(jīng)寫了10年的程序了。每個人回顧以往走過的路的時候,往往會發(fā)現(xiàn)今天的結果來源于之前的一些“關鍵步驟”。顯然我也是一樣的,所以這次的總結跟以往不同,就不列出之前做過的種種程序,而是聊一聊這些關鍵步驟和影響我的人給我?guī)淼挠绊憽.斎凰愕蒙详P鍵步驟的,只能是那些能夠左右人生軌跡的事情。

老爸、外婆和爺爺
這倒不是說老爸老媽把我生下來了怎么樣怎么樣。老爸在我幼小的時候教我一些簡單的數(shù)學,給了我很多書,還有外婆教我識字,結果就是我從大概二年級開始就能夠閱讀老爸留給我的一些科普讀物了。這些科普讀物是他小的時候看的,上面還有語錄,每一篇的幾位都是偉大的思想指引我們前進云云。當然這并不妨礙書本的內(nèi)容的質(zhì)量。老爸的書也都一直保存得很好,后來我爺爺也給我弄了一套科普的啟蒙讀物,現(xiàn)在還保留著,只不過很多翻爛了。這套書是翻譯的,小日本寫的,不過內(nèi)容卻十分豐富。里面包含了數(shù)學、物理、生物、手工和一些其他的很多東西,甚至連汽車和飛機的結構都有。加上外婆也十分贊成并且指引我看這些書,其結果就是從小就對一些科學的事情感興趣——當然也包括數(shù)學。從三年級開始到中學,老爸就給我買一些數(shù)學奧林匹克的書。當然這并不是讓我去參加競賽用的,只是他覺得既然他小時候也喜歡搞數(shù)學那我也應該繼承這個優(yōu)點,從而就讓我去弄那些東西了。在五年級的時候,那次全市的數(shù)學競賽老爸也幫了我很多,我也拿了很好的成績。維持了那么多年從不間斷的強大的自信心和信念就是從這個時候開始的。人喜歡搞一些事情很大程度上都是因為那些事情曾經(jīng)被搞得很好,因此我也就喜歡上數(shù)學了,后來有機會體驗到了數(shù)學的定理和公式的美妙之處,讓我一發(fā)不可收拾。

汕頭市華僑中學的領導們
這是個好學校。我整個讀書的生涯,唯一一次體驗到什么是素質(zhì)教育就是在這里。可是后來由于各種微妙的問題導致這所學校的競爭力下降,這從某種程度上來說算是悲哀吧。我第一次接觸到編程就是在這里。初中二年級的時候,學校開Basic的課,但是并沒有試圖讓我們參加競賽——其實連提都沒提,只是就這么當成正常的課來上。把編程學得好,滿足下面兩個條件的話基本上可以說就是在走捷徑,第一個是會從心底里對公式和定理產(chǎn)生美的感覺,第二個就是要持續(xù)不斷地在編程上體會到成就感。這也是我為什么在一篇寫給師弟師妹的文章里面提到剛開始的時候?qū)W習制作軟件界面也是十分重要的,因為這會讓你產(chǎn)生源源不斷的動力,好讓你給以后學習算法打下精神基礎。QBasic教完自然就教Visual Basic了,當然都是很淺的內(nèi)容。不過我由于受到吸引,從那以后就一直往書店里面跑,去掃蕩各種跟Visual Basic有關的書,后來學到了不少。我初二在新華書店很偶然的發(fā)現(xiàn)了那本《Visual Basic高級圖形程序設計教程》,不過坦白說我其實是被插圖吸引的。那個時候發(fā)現(xiàn)Visual Basic竟然可以僅憑代碼繪制出那么漂亮的圖形,從而興趣提高了不少。不過學習這個也是很辛苦的,這導致我不得不在初三的時候就去尋找并學習立體解析幾何,高中的時候提前學習數(shù)學分析,都是為了看懂這本書啊。這本書我從初二一直看到上了大學,還帶去宿舍看,看了好多年才把它每一頁都琢磨透。這從某種程度上來說也算是緣分吧。

英語補習老師李培濤
初中的英語被我一不小心搞的一塌糊涂,甚至到了快不及格的地步了,所幸當時我媽(特別感謝)非得讓我找一個英語的補習老師,所以就遇到了李老師了。雖然說補習課是要交錢的,不過李老師人倒是很好,不是為了收錢而收錢,還是花了很大精力實踐了因材施教的。我的英語就被他給搞好了。我們知道英語對于編程來說是不可或缺的一個重要條件,因為中文的資料從數(shù)量或者質(zhì)量上來說,都遠遠比不上英文的資料。如果英語不好,這除了阻止知識到達你的大腦里面以外,沒有好處。

汕頭市第一中學的張朝陽老師
高一的時候是張老師給我們上的計算機課,這個時候他告訴我們有NOI這種東西,不過我著實對算法沒什么興趣,因為那個時候我對圖形更感興趣,而且絕大多數(shù)圖形的算法都不是搜索算法,而是跟數(shù)學知識有著更直接的聯(lián)系。因此我就沒有花多少時間在算法上面了。不過其實什么時候?qū)W習算法并不重要,只要你在工作之前學了就好了。原本那個時候也想靠NOI看看能不能混個保送什么的,由于我其實也不太認真做這個,因此只好親自高考了。但是在這里我并不是說張老師教給了我什么知識,其實那段時間我都是靠自學。只不過因為我在非NOI的編程競賽里面的成績很好,所以他給我大開方便之門,讓我可以利用學校的各種資源。我們都知道萬惡的學校經(jīng)常會不知不覺做出一些扼制青少年素質(zhì)全面發(fā)展的事情,因此張老師給我的方便是十分重要的,包括我可以擁有機房的鑰匙以便我在任何時候可以進去使用計算機寫程序。課還是要上的,但是由于我每一年都參加NOI,所以自習課我就可以跑去機房了,寫代碼的時間也就大大增加了,這著實是十分有好處。

CSTC的同僚們
CSTC我現(xiàn)在也搞不清楚究竟他們的使命是干啥,不過印象里面就是北京工業(yè)大學的幾個寫代碼比較厲害的人搞起來的。我有幸在上高中的時候接觸到了他們,其中曾毅和唐良兩個人對我的幫助很大。曾毅告訴我為了將來的前途也好,為了自己編程能力的發(fā)展也好,搞一個好學??偸潜仨毜?。唐良是在我上了大學之后告訴我這個世界上還有《算法導論》這本書,讓我的數(shù)據(jù)結構和算法知識有了十分穩(wěn)固的基礎。當然其實不會數(shù)據(jù)結構和算法并不是說你就寫不了什么復雜的程序,而只是導致你寫出來的復雜的程序質(zhì)量很差性能比較低而已。在高中的時候我已經(jīng)做出了一個pascal的無指針版本的解釋程序了,不過在這個時候我說實話除了鏈表以外,什么都不知道,編譯原理也不知道,所有的東西都是硬湊出來的。當然程序還是能運行的,就是寫好之后就無法再修改了,實在改不下去。

華南理工大學的陳健老師
高三的時候?qū)懗鰜淼膒ascal解釋器實在是讓我十分興奮,所以在剛?cè)雽W不久聽說我們的班主任陳建老師教編譯原理的,我就跟她說我對這方面有興趣了,而且當時還為我的下一個解釋器寫了一個很長的設計文檔。這份文檔一開始只是寫給我自己的,后來順便就給她看了。陳老師倒是沒說什么,過了許久,給了我一本《編譯原理》。當然這不是龍書,說實話那本課本也非常糟糕,只是這讓我知道這個世界上還有這種東西,也就足夠了。大一的時候迅速看完了這本書,覺得很不爽,就把龍書搞到手,然后看了一部分。大一結束的時候就做出一個面向?qū)ο髱0搴屠占撵o態(tài)類型腳本語言了,陳老師實在是功不可沒。作為老師,能教你什么是不重要的,告訴你你還有什么不會才是最重要而且最有用的。

華南理工大學的陳天老師
這位老師給我們上了大一的C++課,不僅功底扎實,而且可以課也講得很好,無奈在我大三的時候說是實在不行了,跑去做程序員了。我就不對這件事情作評論了。陳天老師不僅告訴了我《設計模式》是十分重要的,而且也經(jīng)常鼓勵我進行更加深入的學習,對我?guī)椭艽蟆?/p>

g9yuayon
這是個人才啊,而且編程水平也十分地令人嘆為觀止。不過他對我?guī)椭畲蟮哪^于告訴我這個世界上還存在著《Parsing Techniques》了。這是世界上最好的描述語法分析的書,連龍書的前幾個章節(jié)都不如這本書講得好。當然龍書還是包含了后端的,而《Parsing Techniques》是只有前端的。不僅如此,他還給了我不少論文看。其實如果看得下去的話,論文帶來的幫助遠比算法要大得多。因為數(shù)據(jù)結構和算法真正普遍實用的也就那么幾種,其實知識量是十分少的,還比不上數(shù)學分析。既然數(shù)學分析一年就可以上完,那實用數(shù)據(jù)結構和算法其實是不需要花那么久的。不過那些更加深刻的數(shù)據(jù)結構和算法當然不在此列了——還是很多的。但是論文,是方向性十分強,而且解決的問題其實范圍更狹窄的東西。只不過如果認真研讀論文的話,可以學到很多知識以外的東西,譬如說作者是如何整理他們的結果的。遇到好心的作者的話你連他們怎么發(fā)現(xiàn)這個事情都可以知道。由于從小就喜歡數(shù)學,所以看論文的時候看得十分入迷,也就看得更加認真仔細了。g9yuayon介紹給我的論文的確都是十分漂亮的,在我掌握了知識的同時,又讓我的基礎變得更扎實,并且對編程也更加喜愛了。

龔敏敏一伙
這倒是一個共同作用的結果,也是我第一個聯(lián)系比較緊密的圈子。群里面的人都分布在各大公司,而且水平都不錯,并且都是在研究圖形學的。至于說為什么會跟他們接觸,當然是因為高中的時候?qū)D形學特別熱衷的關系了。雖然后來轉(zhuǎn)去做編譯器了,不過學習圖形學并不是一個浪費,因為這個漫長的過程讓我的數(shù)學知識變的扎實,而且也產(chǎn)生了很多題目讓我練習編寫一些至少有點小規(guī)模的程序。實踐是檢驗真理的唯一標準,這話是不錯的。

我還要提一下LYT同學。LYT并沒有在編程上幫助我,其實是我在教LYT寫代碼,只是LYT肯讓我教那么久著實也不容易。為了教LYT學會寫簡單的編譯器,讓我不得不將我學過的知識從頭到尾整理了一遍,而且還讓我思考如何使得一個人在學會編程的同時可以保持樂趣、自信心和良好的習慣。這個過程十分有意義,不僅讓我有一個機會可以從頭整理我學會的知識,思考一些更加深刻的東西,讓自己對知識的掌握更加深刻和牢固,而且其實對被教也是有幫助的。利己利人,何樂不為。LYT經(jīng)過了我三年的精心指導,從對編程什么都不知道開始,最終順利拿到了網(wǎng)易的offer,而且工資也沒比我低多少,實在是讓我感到十分高興。

在我2009年7月份畢業(yè)之后就去了Microsoft而且尚未跳槽。從畢業(yè)后開始到現(xiàn)在這段時間現(xiàn)任女朋友2A同學給了我很大的支持,并沒有覺得整天宅在電腦前寫代碼看動畫片很沒前途,而且還幫忙尋找各種書帶我去書店鼓勵我等等,對此十分感謝。

當然這并不是說其他人就對我沒有幫助,而只是沒有滿足文章一開始提出來的“左右人生軌跡”的條件而已。因為對我有幫助的人其實非常多,志同道合的朋友也不少,在這里我就不一一列舉了。

祝各位讀者們也能夠?qū)幊谈信d趣而且在這個道路上不斷堅持越走越遠。

<><><><><><><><><><>
后記。突然想起來我忘記寫上,其實小日本的動畫片都是一些非常具有教育意義的東西,這讓我學會了很多黑暗的社會沒有任何機會讓我知道的人生的道理。大家一定要看啊。

<><><><><><><><><><>
后記2。今天空明流產(chǎn)說他是搞圖形那一群人里面為數(shù)不多的還做做shader前端的,所以我再提一下,啊哈哈哈。

posted @ 2010-12-18 09:17 陳梓瀚(vczh) 閱讀(10666) | 評論 (33)編輯 收藏
    時隔一個月,終于在Vczh Library++ 3.0的IDE工程里實現(xiàn)了用戶自定義類型變綠(抄C#的娃哈哈)鼠標移動到對象上會出tooltip、顯示函數(shù)參數(shù)提示和Code snippet的功能了。由于我的語法樹的每一個節(jié)點都包含了它在源代碼中的位置,所以鼠標指向一個字符的時候,可以計算出他在語法樹的位置,從而可以查到他的聲明的語法樹節(jié)點,再用聲明節(jié)點的位置就可以把聲明的代碼復制出來顯示在tooltip上面了:

    同樣的方法可以用來實現(xiàn)顯示函數(shù)參數(shù)。這個比tooltip要復雜一點,因為要吧語法樹的聲明重新組織成代碼才能顯示出來,而且還有模板函數(shù)的類型問題。不過現(xiàn)在有兩個小功能還沒實現(xiàn),第一個是在沒輸入的時候移動光標不會更新參數(shù),這只是個小問題。另一個是對一個函數(shù)指針調(diào)用的時候做提示,這個還要進一步考慮。下圖顯示的是對一個模板函數(shù)做參數(shù)提示的時候,參數(shù)的類型會自動特化:

    接下來就是code snippet了。Code snippet是一個強大的功能,可以讓你免除一些無謂的手指的勞動。Visual Studio里面提供了大量的code snippet,不過在這里我暫時只提供for和forr兩種,用來輸入for循環(huán)。下面是使用code snippet輸入一個for循環(huán)的全過程:











    Code snippet是一個比較復雜的功能,在這里我只實現(xiàn)了上下文無關的一些特性。Visual Studio里面的就更為高級了,他在插入一個類名的時候,可以根據(jù)上下文來判斷是否需要出現(xiàn)完整的namespace。當然由于現(xiàn)在我用來做intellisense的語言還沒有這么復雜的元素,所以也就無從做起了。

    所有的代碼可以在Vczh Library++ 3.0里面找到。這篇文章的代碼跟(十)的時候的代碼已經(jīng)大為不同了。經(jīng)過一系列的重構,intellisense功能最終被做成一個靈活的插件形式,所有的細節(jié)都可以更改,甚至連code snippet那個黃色的輸入位置都可以再往上畫東西。因為在開發(fā)intellisense的時候發(fā)現(xiàn)了NativeX語言語法上一個二義性,因此NativeX的語法也做了一處小修改。而且我趁著這個時候重構了所有NativeX的測試用例,把在C++里面構造語法樹改成了用一系列make file和反射函數(shù)并運行的方式直接使用NativeXProvider編譯、運行main函數(shù)并與記錄在index文件中的結果進行比較的方法。

    接下來可以做的事情就比較多了。首先我要開始完成NativeX的調(diào)試功能,其次我要拿Microsoft SQL Server那個超級復雜的T-SQL來研究一個從文法產(chǎn)生intellisense代碼(是的,你沒看錯,是intellisense代碼)的方法,最后要在intellisense上實現(xiàn)NativeX的重構。對于那個自動生成intellisense代碼的算法,目前還僅僅出于YY階段,當然生成出來的也只能是上下文無關的intellisense。譬如說幫你列出數(shù)據(jù)庫里面的所有表啦,或者幫你列出前面聲明過的變量啦,不屬于自動生成的范圍。不過自動生成的intellisense還是會告訴你“現(xiàn)在需要彈出變量列表,需要提供內(nèi)容”的這樣一種信息來讓你可以往里面添加一些不能自動生成的東西。當然做不做得出來那是另外一回事了,先研究研究。
posted @ 2010-12-04 18:59 陳梓瀚(vczh) 閱讀(13432) | 評論 (16)編輯 收藏

    有兩個星期沒有更新博客了,主要是最近在研究一種更靈活的代碼編輯框的框架設計,修了很多bug,還有公司的事情多了起來?,F(xiàn)在全部都解決了,因此開始寫這一篇博客。上一篇文章提到了我搞定了一個智能提示的原型,當然現(xiàn)在已經(jīng)在Vczh Library++ 3.0上面添加了鼠標指向一個對象顯示聲明代碼和打括號的時候提示函數(shù)參數(shù)(部分完成)的功能了。今天來說一下我是如何實現(xiàn)這些功能的。當然我不會講所有細節(jié),只會講重點,如何實現(xiàn)那個界面也不包括在這里。我要說的是,如何立刻知道任意一個位置所在的代碼究竟是什么東西。

    如果你沒有讀過之前的幾篇文章的話,建議去翻一翻,因為我之前提到了一些背景,還有我實現(xiàn)的C#版yacc(當然只是指功能,并不兼容),IDE和編譯器的語法分析器的異同和實現(xiàn)一個IDE用的語法分析器要注意的地方。

    語法分析總是產(chǎn)生語法樹或者分析樹的,無論開發(fā)什么能夠感應代碼內(nèi)容的工具,都逃不過語法分析。因此可以肯定的是,在你敲代碼的時候,IDE真的在背后生成了一棵樹,只不過為了要達到普通文本框的輸入性能,很多東西都要移動到后臺去做,但是為了瞬間響應并作智能提示,有一些東西要移動到前臺做。他們之間的分界線想要界定清楚其實也不是很難。

    假設我們要編輯一份超大文件(幾萬行吧,再超過要開除的哈),每當你打字修改它的時候,一定會進行語法分析并產(chǎn)生語法樹。對于這么大規(guī)模的代碼要產(chǎn)生語法樹肯定不是瞬間就能完成的(我那個東西大概要一秒鐘多一點),因此這一步是在后臺完成的。但是當你打一個"."的時候,你肯定希望立刻就要彈出列表的內(nèi)容。為了知道列表的內(nèi)容,你肯定得先知道那個"."出現(xiàn)在了什么表達式里面,以及"."前面的那個表達式究竟是什么類型,這是離不開全文分析的。但是全文分析又太慢,所以我引入了一個技術。

    為了完成這個技術,你必須在前臺分析得到那個表達式。我們很容易就知道,我們是不可能等待后臺分析給我們提供數(shù)據(jù)的。所以在這里我們要做的是,緩存當前我們感興趣的代碼。在這里簡單化一下,如果我們只需要提供按"."彈出列表的話,我們只需要緩存語句(statement)就可以了。怎么做呢?假設我們已經(jīng)可以通過所在的位置得到代碼的內(nèi)容(下面會講),那么我們顯然可以知道光標的位置所在的語句的語法樹對象究竟是什么。有了這個語法樹對象,我們就可以從代碼里面直接把這個語句的代碼文字復制出來,然后緩存語句的代碼、語句所在的全文位置和語句所在的作用域。作用域是語法樹的一部分,在做完語法分析之后,只需要做簡單的語義分析建立作用域就可以計算很多東西了。這個緩存會在光標位置移動的時候更新,也會在當前的全文分析結束的時候更新。

    一旦緩存下來之后,你往里面打了一個字符,那我不僅可以更新文本框里面的內(nèi)容,我還可以更新緩存里面的代碼的內(nèi)容,同時還可以知道新的緩存開始結束位置。一個語句通常都是很短的,最多也就一百來個字符,因此我們立刻在前臺對它做語法分析。而且往一個語句里面打字的話,99%以上的情況是不會影響到上下文的,所以這個語句的舊作用域?qū)ο笕匀豢捎?/strong>。這個時候我們用舊的作用域?qū)ο髞韺π碌恼Z句做語義分析,那么就可以知道這個語句每一個表達式的類型了,從而知道了"."前面的表達式究竟是什么類型。然后利用舊作用域?qū)ο?,我們就可以知道這個類型包含了多少成員。到了這一步,列表里面的對象就構造完畢了。

    然而后臺的全文分析總是會結束的,所有的信息在這個時候就準備好了,然后發(fā)個消息給前臺讓它更新緩存。兩種更新緩存都是用GUI的消息驅(qū)動的,所以不可能同時發(fā)生,只會先后發(fā)生。之前談到的臨時更新跟后臺的全文分析是并行的,不過這個不會影響我們。只要我們正確處理后臺跟前臺的信息交換,那么整個智能感應的計算過程就可以做得十分安全,不會發(fā)生死鎖。我相信這一點應該不是很難。

    那么,現(xiàn)在回到了兩個最原始的問題。第一個是如何通過位置查找語法樹。這個很容易解決,只要在語法分析的時候把所有跟位置有關的信息都記錄在樹里面就可以了。第二個問題是我們?nèi)绾翁幚碛脩魧戝e的代碼。平時編譯原理里面所教授的自動錯誤恢復其實是不好用的,你看看VC++的編譯器在你寫錯了什么東西之后,大部分的錯誤信息基本上都沒法看,因此如何進行錯誤恢復肯定要我們自己進行精心設計。但是問題來了,我們?nèi)绾螌崿F(xiàn)它呢?顯然手寫語法分析器會讓我們心煩意亂根本做不下去(還要處處記得記錄位置信息……),因此我們需要一個語法分析器生成器。

    在這里我建議大家去閱讀我博客上的兩篇文章,你可以從這兩篇文章所給的鏈接看到一些其他的東西,講的是如何用組合子開發(fā)語法分析器。我這里給語法樹添加了一個新屬性,也就是一種組合起來強大但是又容易指定的錯誤恢復技術了。這里的錯誤恢復技術分為兩種,一種是針對循環(huán)的,這個大家看代碼就可以了,因為跟第二種——也就是序列關系的文法的錯誤恢復——非常相似,只是一個理論上的變換而已。

    內(nèi)容是這樣的。假設我們需要分析下面的表達式:EXPRESSION + "." + MEMBER,那么我們總是希望在殘缺不全的代碼里面恢復出盡可能正確的信息。我們知道一旦出現(xiàn)了".",用戶想要寫的必然是一個訪問對象成員的表達式,因此我們在"."那里表上記號,變成EXPRESSION + "." + MEMBER。標記有一個副作用,也就是一旦標記所包含的語法分析成功了,那么整條語法會保證產(chǎn)生出指定的語法樹結構。如果用戶出現(xiàn)了錯誤,那么所有的錯誤都會被當成用戶少輸入了什么東西而引起的。雖然這一個假設對于編譯器來說不太合適,但是對于IDE來說顯然是合適的。但是這種做法很容易在分析列表結構的代碼里引起死循環(huán),所以需要做很多測試來保證你的標記不會造成問題。

    下面的例子也可以輔助說明這種方法的有效性。舉個例子,你需要做一個函數(shù)。你在寫函數(shù)的過程中顯然會臨時或者不小心少些一些東西——有時候我們并不是把所有的事情都想清楚了才開始寫代碼的。這個時候為了正確分析出函數(shù)的結構,我們做下面的語法并標記:
    FUNCTION_DECLARATION ::= TYPE + NAME + "(" + list<TYPE + NAME, ","> + ")" + COMPOSITE_STATEMENT
    VARIABLE_DECLARATION ::= TYPE + NAME + optional("=" + EXPRESSION) + ";"
    然后總是保證FUNCTION_DECLARATION的優(yōu)先級比VARIABLE_DECLARATION更高,我們就總是可以恢復出最正確的語法結構了。這一種做法對于你在連續(xù)輸入代碼的過程中進行正確的提示是相當好用而且方便的。

    至于代碼生成器本身怎么實現(xiàn),還是去Vczh Library++ 3.0下載代碼吧。

posted @ 2010-11-22 03:29 陳梓瀚(vczh) 閱讀(13693) | 評論 (14)編輯 收藏
僅列出標題
共35頁: First 7 8 9 10 11 12 13 14 15 Last 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              国产精品一香蕉国产线看观看 | 国产人成精品一区二区三| 久久久久久精| 亚洲午夜精品在线| 亚洲国产精品综合| 久久久久国产一区二区| 一区二区欧美视频| 亚洲国产精品va在看黑人| 国产欧美精品| 欧美三区免费完整视频在线观看| 久久久欧美精品sm网站| 午夜免费日韩视频| 在线视频日韩| 亚洲精品日韩在线观看| 欧美成人午夜激情在线| 久久免费黄色| 久久精品国产清高在天天线| 亚洲图片在区色| 一区二区三区欧美日韩| 最新精品在线| 亚洲欧洲美洲综合色网| 在线成人中文字幕| 国内成人自拍视频| 国产欧美精品日韩区二区麻豆天美 | 久久久久久久久久久一区| 午夜国产精品视频| 亚洲女女做受ⅹxx高潮| 亚洲视频免费看| 亚洲视频一二区| 中文在线不卡| 中文精品99久久国产香蕉| 日韩亚洲欧美中文三级| 亚洲毛片在线看| 日韩视频永久免费| 宅男噜噜噜66一区二区| 亚洲天堂偷拍| 亚洲欧美国产高清va在线播| 亚洲永久在线观看| 亚洲欧美一区二区三区久久| 亚洲综合首页| 久久国产精品色婷婷| 欧美资源在线观看| 久久精品一本| 久久伊人精品天天| 免费观看成人鲁鲁鲁鲁鲁视频| 久久婷婷久久一区二区三区| 老妇喷水一区二区三区| 免费日韩av| 欧美女激情福利| 欧美少妇一区二区| 国产伦精品一区二区三区高清| 国产精品日韩电影| 国内成人精品2018免费看| 在线观看欧美日韩| 亚洲精品男同| 亚洲免费伊人电影在线观看av| 先锋a资源在线看亚洲| 欧美在线观看你懂的| 老司机成人在线视频| 亚洲电影在线观看| 亚洲图片你懂的| 久久久国际精品| 欧美国产精品日韩| 国产精品久久久久影院亚瑟 | 欧美一二三视频| 久久午夜精品一区二区| 欧美精品久久久久a| 欧美视频中文一区二区三区在线观看| 国产精品视频yy9099| 黄色综合网站| 一本大道久久精品懂色aⅴ| 亚洲免费网址| 免费人成精品欧美精品| 日韩视频在线一区| 久久精品国产第一区二区三区| 欧美电影免费| 国产欧美一区二区精品仙草咪 | 亚洲国产一区二区三区高清| 亚洲一区二区免费| 免费人成网站在线观看欧美高清 | 一区二区三区你懂的| 久久精品91久久久久久再现| 欧美激情导航| 黄色一区二区三区四区| 亚洲一区二区三区影院| 男男成人高潮片免费网站| 一本色道久久99精品综合| 久久久www成人免费精品| 欧美日韩在线观看一区二区三区| 国产视频久久网| 99亚洲伊人久久精品影院红桃| 欧美中文字幕久久| 亚洲国产国产亚洲一二三| 香蕉久久夜色精品国产| 欧美日韩国产在线播放网站| 曰韩精品一区二区| 欧美一区二区三区喷汁尤物| 蘑菇福利视频一区播放| 亚洲欧洲av一区二区三区久久| 欧美风情在线| 亚洲成色777777在线观看影院| 亚洲欧美另类久久久精品2019| 亚洲高清影视| 久久久久久久久蜜桃| 国产人久久人人人人爽| 亚洲视频网站在线观看| 亚洲高清电影| 久久婷婷人人澡人人喊人人爽| 国产免费亚洲高清| 亚洲午夜高清视频| 亚洲欧洲一区二区三区在线观看| 欧美影院成人| 国产日韩成人精品| 亚洲综合精品自拍| 一区二区三区|亚洲午夜| 欧美激情 亚洲a∨综合| 在线日韩视频| 免费观看国产成人| 久久久噜噜噜久久中文字免| 国产一区二区三区黄| 久久国产精品久久久| 亚洲欧美日韩成人| 国产精品美女在线观看| 中日韩高清电影网| 99riav久久精品riav| 欧美日韩三级视频| av成人黄色| 日韩视频在线永久播放| 欧美另类视频| 亚洲一区二区精品在线| 一本到高清视频免费精品| 欧美日韩综合精品| 亚洲性xxxx| 亚洲欧美激情视频| 国产女优一区| 久久九九免费视频| 久久久久久久成人| 亚洲国产高清高潮精品美女| 欧美成人在线免费观看| 欧美成人精品在线视频| 91久久亚洲| 99精品国产99久久久久久福利| 欧美日韩国产系列| 亚洲欧美日韩国产中文在线| 亚洲综合成人在线| 狠狠色丁香久久综合频道| 蜜桃久久av| 欧美极品影院| 亚洲欧美综合另类中字| 午夜天堂精品久久久久| 国产一区二区视频在线观看| 蜜乳av另类精品一区二区| 欧美成人三级在线| 亚洲一级片在线观看| 午夜精品剧场| 亚洲激情视频网站| 一区二区三区欧美视频| 国产欧美日韩综合一区在线播放| 开心色5月久久精品| 欧美激情一区二区三区四区| 亚洲一区二区三区四区在线观看 | 亚洲美洲欧洲综合国产一区| 国产精品v欧美精品v日本精品动漫| 午夜精品久久久久99热蜜桃导演| 性伦欧美刺激片在线观看| 一区精品在线| 日韩一二三在线视频播| 国产日韩精品视频一区二区三区| 美女脱光内衣内裤视频久久网站| 欧美电影免费| 欧美在线视频导航| 欧美aⅴ99久久黑人专区| 亚洲一区二区在线免费观看视频| 久久国产精品久久w女人spa| 日韩手机在线导航| 久久不射电影网| 中文一区二区在线观看| 欧美一区二区视频免费观看| 99国产一区| 久久国产加勒比精品无码| 日韩一级黄色av| 欧美一区综合| 亚洲婷婷综合久久一本伊一区| 久久精品av麻豆的观看方式| 在线午夜精品| 久久久久五月天| 亚洲欧美久久久久一区二区三区| 美脚丝袜一区二区三区在线观看| 亚洲欧美日韩精品久久久| 久久先锋影音av| 欧美在线电影| 欧美日韩美女| 亚洲二区在线视频| 国产一区二区三区久久悠悠色av| 日韩午夜一区| 亚洲日韩欧美一区二区在线| 欧美在线亚洲| 欧美亚洲免费| 欧美日韩在线精品一区二区三区| 美女脱光内衣内裤视频久久网站|