• <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>
            隨筆-341  評論-2670  文章-0  trackbacks-0
             
                之前的一篇文章曾經說過我在準備一個面向組合子編程的ppt和demo。在公司內部進行試運行之后,今天終于開講了。

                當然在這之間的幾個星期里面,我修改了ppt的內容,還有為demo添加了單元測試。所以我把ppt的內容和demo的代碼也一起打包上來了。

                ppt包含2003和2007兩種格式,demo使用的是Visual Studio2010的C#,當然是為了使用那個激動人心的“缺省參數”語法了。如果沒裝2010的話,那就趕緊裝一個哈,如果不想裝,那看看代碼就行了。
            posted @ 2010-09-01 20:42 陳梓瀚(vczh) 閱讀(5178) | 評論 (3)編輯 收藏
                因為在開發CMinus的過程中為了異常處理(最終沒有實現進CMinus),曾經學習了一下怎么用匯編語言寫try-catch,因此這個CPU相關的處理方法就被我偷了哈,實現在了NativeX的虛擬機里。

                在NativeX里面,try-catch和throw非常簡單。throw你可以加一個值當異常數據,也可以不加(不會修改上次的異常數據,可以當rethrow用)。catch的話沒辦法跟C++一樣根據類型來判斷,因此我會給你一個異常數據的指針,你自己看著辦哈,因為NativeX跟C一樣沒有RTTI。因此throw就很簡單了,就是恢復棧頂和棧底指針之后跳轉到最近的異常處理程序里面去。try和catch就是用來創建和銷毀異常處理程序的。所有的異常處理程序構成了一個鏈表,這個鏈表被我記在了堆棧里面,而最近的異常處理節點的指針則被我放在了整個堆棧控件的最頂部,接在后面的是異常對象的數據。你每次throw的東西的尺寸可以不同,因此占用的“堆棧最頂部空間”也不同。當然如果你函數遞歸太深而導致棧頂覆蓋了異常對象的數據區域時,就會觸發“堆棧溢出”事件。在NativeX里面堆棧溢出代表你這程序已經廢了,因此這個是不能catch的,虛擬機返回給宿主程序一個信號然后就停止執行了。

                我們來看一個簡單的例子,如何throw之后把異常對象的返回給函數,首先是代碼:
             1 /*NativeX Code*/
             2 unit nativex_program_generated;
             3 function int32 main()
             4 {
             5     (result = 10s32);
             6     try
             7         Throw();
             8     catch
             9         (result = ( * cast<int32*>(exception)));
            10 }
            11 
            12 function void Throw()
            13     throw 20s32;

                main函數首先將函數返回值設置成10,然后調用throw函數。throw函數會把20給throw出來,然后main函數catch了,把結果返回。NativeX使用了關鍵字exception來表達異常對象的地址。當然你如果要throw各種不同的東西的話,你得自己做標記(親自實現RTTI)了。好了,我們看看產生的指令:
             1 // unit nativex_program_generated;
             2      0: stack_reserve 0
             3      1: stack_reserve 0
             4      2: ret 0
             5 // function int32 main()
             6      3: stack_reserve 0
             7 // (result = 10s32);
             8      4: push s32 10
             9      5: resptr
            10      6: write s32
            11 // try
            12      7: exception_handler_push 14
            13 // Throw();
            14      8: stack_reserve 1
            15      9: stack_top 0
            16     10: call 20 1
            17     11: stack_reserve -1
            18 // try
            19     12: exception_handler_pop
            20     13: jump 18 1
            21     14: exception_handler_pop
            22 // (result = ( * cast<int32*>(exception)));
            23     15: exception_object_address
            24     16: resptr
            25     17: copymem 4
            26 // function int32 main()
            27     18: stack_reserve 0
            28     19: ret 0
            29 // function void Throw()
            30     20: stack_reserve 0
            31 // throw 20s32;
            32     21: exception_object_reserve 4
            33     22: push s32 20
            34     23: exception_object_address
            35     24: write s32
            36     25: exception_raise
            37 // function void Throw()
            38     26: stack_reserve 0
            39     27: ret 0

                try首先會將catch之后的第一個指令給exception_handler_push了,在try的結尾當然要取消掉這個異常處理函數了,因此pop一下,然后jump到catch后面。當然catch的第一件事也是exception_handler_pop。exception_object_reserve在棧頂預留指定的空間來存放異常對象,exception_object_address則是獲得異常對象的地址,exception_raise就是跳轉到最近的異常處理函數了。raise不會把異常處理函數的記錄給pop掉,所以要靠catch自己去pop。

                NativeX已經完成了,接下來就可以開始打造周邊工具了哇哈哈。將來的目標是將類似C#和Javascript的語言都編譯到NativeX上,然后為這三類語言寫很多語法分析器,然后他們就變成很多語言了。當然這些語言只是demo。Vczh Library++的目的是提供實現編譯器的中間每一層的類庫,因此想干嘛就可以干嘛了哈。
            posted @ 2010-08-28 01:14 陳梓瀚(vczh) 閱讀(3495) | 評論 (9)編輯 收藏
                 摘要:     如上一篇文章所說,Vczh Library++3.0的NativeX語言實現了計劃的所有泛型語法。讓我們來看一個簡單的例子:我們為類型寫一個Equals函數。我們可以為普通類型,譬如int32寫一個Equals函數。我們有Vector<T>類型,只要T類型擁有一個Equals函數,那么Vector<T>顯然也可以有Equals函數。問題...  閱讀全文
            posted @ 2010-08-26 03:09 陳梓瀚(vczh) 閱讀(3107) | 評論 (3)編輯 收藏
                這幾天寫了一個關于面向組合子編程的ppt。幾個月前跟某個dev lead借了他翻譯的中文版Pattern Hatching,條件是要在公司里面開一場關于設計模式的講座。其實本來一個月前就要講了,不過中間出了點事情,所以等到這個月才開始。因此我挑選了面向組合子編程的這個主題,做了個demo和ppt。

                面向組合子編程原本是函數式編程的內容,主要說的是既然我們可以用Composite模式(參見這里這里)來做出像樹一樣的數據結構,那么我們做出組合起來跟樹一樣的行為(譬如Command模式,用類代表行為)不也可以嗎?這個做法當然是行得通的,只不過一般我們很難看到一個需求的時候,可以意識到可以用面向組合子編程來搞定這個東西。因此我在這個ppt里面就舉了這樣的一個例子,也就是老掉牙的Log系統了:

                我們編譯器在編譯代碼的時候,會產生下面的文件:
                buildchk.err -- 記錄著錯誤
                buildchk.wrn -- 記錄著警告
                buildchk.log -- 記錄所有詳細信息和時間戳
                命令行窗口 -- 記錄摘要,當然錯誤和警告還是要輸出來的,只是內容可以簡要一點

                然后我就用面像組合子來開發了一個小巧玲瓏的系統,最終通過一個聲明式編程的接口暴露出來,然后你還可以往里面添加新的功能。

                當然系統還是要經得起修改的,因此我還舉了個例子,如果有了需求變更——
                err和wrn要加錯誤/警告的序號
                支持GUI了——跟VS的錯誤列表差不多

                最后展示了面向組合子編程最強大的威力——只需要添加零件,所有已經存在的工具都可以立刻在這個零件上面使用了,因此只需要非常少的代碼就可以完成這個需求變更。

                這里就放上我的ppt了。明天還要先開一個內部講座看看別人有什么意見然后進一步修改,完了demo在放出來。這個demo當然是C#寫的了,有GUI,C++寫GUI多麻煩啊……
            posted @ 2010-08-16 09:10 陳梓瀚(vczh) 閱讀(4913) | 評論 (15)編輯 收藏
                最近在忙一些其他的事情。因為工作的關系我稍微花了點時間研究了一下C#,因此就沒往博客上寫文章了。Vczh Library++ 3.0的工作也暫停了半個月,下個星期就要開始恢復了。最近Codeplex服務器的URL修改了導致項目連接不上,后來還是修掉了,主要是得手動更改sln文件的內容,花了好久才知道怎么做。

                目前的進度是實現了generic constraint的數據結構但是沒有加入語法分析和語義分析的內容。generic constraint比較簡單,就如同C#的那個where,我可以寫:
             1 concept T : IEq
             2 {
             3   
             4 }
             5 
             6 concept T : ISort
             7   where T : IEq
             8 {
             9   
            10 }
            11 
            12 generic<T>
            13 where T : ISort
            14 function void Sort(T* values, int count)
            15 {
            16   
            17 }

                這是很重要的,因為沒有了where,在Sort下面就沒辦法使用ISort和IEq里面定義的函數了。在NativeX可以成為一門真正可以使用的中間語言之前,還必須實現下面的功能:

               1、 generic constraint
                2、concept instance函數調用
                3、異常處理
                4、外部函數接口
                5、調試器接口
                6、裝載的時候檢查元數據引入表是否匹配了所有已經加載的assembly

                剩下的事情也不多了,就慢慢做吧。做完之后就可以開始寫一些parser來驗證這個NativeX究竟行不行了,我可以將Python和Basic都修改成一個類似C的語言(可以處理指針,沒有垃圾收集,等),然后把它編譯成NativeX的語法樹,這樣就可以開發一個支持多語言的編程接口并測試它了。
            posted @ 2010-08-06 18:31 陳梓瀚(vczh) 閱讀(3170) | 評論 (12)編輯 收藏
                 摘要:     根據之前的文章的討論,Vczh Library++3.0泛型全局存儲是一個大型的映射。假設你有下面的代碼: 1 generic<T>2 structure StorageType3 {4   wchar* name;5   T ...  閱讀全文
            posted @ 2010-07-17 21:28 陳梓瀚(vczh) 閱讀(2965) | 評論 (2)編輯 收藏
                第三篇草稿講了泛型concept的概念,這篇最終稿可以確定Vczh Library++ 3.0的NativeX所要支持的泛型concept的比較精確的特性了。

                泛型的concept的概念還是比較清晰的,這次我們便通過一個例子來講解他。假如在NativeX里面實現一個列表,顯然因為NativeX只有指針,所以寫起來大概就是:
            1 generic<T>
            2 structure List
            3 {
            4   T* items;
            5   int count;
            6 }

                于是我們想寫一個函數判斷兩個List是否相等。因為NativeX現在已經有模板函數了,所以我們很簡單的一個想法是,傳入兩個List<T>*,然后再傳入一個函數指針function bool(T,T),就可以寫出下面的函數了:
             1 generic<T>
             2 function bool ListEquals(List<T>* xs, List<T>* ys, function bool(T,T) comparer)
             3 {
             4   result=true;
             5   if(xs->count!=yx->count)
             6   {
             7     result=false;
             8   }
             9   else
            10   {
            11     variable int current=xs->count-1;
            12     while(current>=0)
            13     {
            14       if(!comparer(xs->items[current], yx->items[current]))
            15       {
            16         result=false;
            17         exit;
            18       }
            19       current--;
            20     }
            21   }
            22 }

                這個做法咋一看好像沒什么問題,但是如果我們要比較List<List<int>>怎么辦呢?我們可以先寫一個function bool IntEquals(int a, int b);,然后再寫一個function bool IntListEquals(List<T> a, List<T> b);,這個函數里面用IntEquals加上ListEquals<int>來實現,最后將他傳進ListEquals<List<int>>。到了這里還好,如果我們還想比較List<List<double>>、List<List<char>>等等,我們就要被迫搞出很多函數了。而且最大的問題是,當我們寫好這么多東西以后,我們想實現一個Find函數來查找List里面的對象的話,面對List<List<int>>、List<List<double>>等等的東西,我們又得重新寫一次了……

                這個問題在面向對象的語言里面都很容易做到,只需要在一個類里面實現operator==就可以了。那這兩種方法有什么區別呢?假設我們把C++里面的類去掉,那么我們會發現,ListEquals<T>的comparer參數是通過T自動找到的,而不是我們自己傳進去的。因此如何設計一套可以從類型找到某一組函數的機制,就因為我們把模板函數加入NativeX語言(基本上就是C語言)而變成了一個必須實現的功能了。在這里我準備引入concept這個概念。concept跟C++0x的concept以及haskell的type class的概念基本一致。現在就讓我們逐步在NativeX里面實現這套機制。

                我們在這里面對的問題是給一些給定的類型(或泛型類型,譬如說List<T>)實現Equals函數,然后每一個Equals函數里面如果需要其他類型U的Equals函數,可以直接找到,而不需要我們自己傳進去。因此這個問題可以抽象為,某些類型具有可以被兩兩比較是否相等的能力。因此定義如下:
            1 generic<T>
            2 concept Eq
            3 {
            4   bool Equals(T a, T b);
            5 }

                當然這些函數不能直接生出來,因此我們對于想比較的每一個類型都需要給出相應的Equals函數。下面的代碼為int類型定義了Equals:
             1 instance int : Eq
             2 {
             3   Equals = IntEquals;
             4 }
             5 
             6 generic<T>
             7 function bool IntEquals(int a, int b)
             8 {
             9   result=a==b;
            10 }

                每比較一次數字就得調用一次函數,這個開銷還是比較大的。在NativeX的所有設施都做好之后,我會開始做指令級別的優化,然后看看要不要實現自動判斷并inline的功能。有了int : Eq之后,我們就可以為List<T>也寫一個Eq了。如果我們給出了List<T>的Equals的話,為了使用這個Equals,T也必須有相應的Equals函數,于是我們可以寫:
            1 generic<T>
            2 instance List : Eq
            3   where T : Eq
            4 {
            5   Equals = ListEquals<T>;
            6 }

                最后就是實現ListEquals了,注意ListEquals函數內部是如何拿到類型T的Equals函數的:
             1 generic<T>
             2   where T : Eq
             3 function bool ListEquals(List<T> xs, List<T> ys)
             4 {
             5   result=true;
             6   if(xs->count!=ys->count)
             7   {
             8     result=false;
             9   }
            10   else
            11   {
            12      variable int current=xs->count-1;
            13      while(current>=0)
            14      {
            15        if(!Eq<T>::Equals(xs->items[current], yx->items[current]))
            16        {
            17          result=false;
            18          exit;
            19        }
            20        current--;
            21      }
            22   }
            23 }

                這里引入了一個新的語法:Eq<T>::Equals,用于自動搜索自己dll或者其他dll實現的這個函數。搜索會在虛擬機里面完成,編譯器只負責提供符號,并檢查類型。因此就大功告成了。

                這個instance的設計基本上來源于Haskell的type class,其實跟C++0x的那個concept關系還是比較小,畢竟NativeX沒有類,C++有類,Haskell沒有類。當然其缺點是你不能在定義了Eq<List<T>>::Equals的同時,專門為Eq<List<bool>>::Equals定義一個特殊的版本,就如同C++的偏特化一樣,這個就過于復雜了。雖然偏特化在C++的用處非常大,而且也十分常用,但是在NativeX里面就因為NativeX的模板可以編譯成二進制而會因為找不到高性能的實現方法被砍掉。
            posted @ 2010-07-13 04:26 陳梓瀚(vczh) 閱讀(3010) | 評論 (8)編輯 收藏
                 摘要:     經過一個星期的奮斗,二進制模板函數終于實現了,當然這還是沒有generic concept的版本。現在NativeX已經支持跟C#一樣的模板函數了:可以被編譯進獨立的二進制文件,然后另外一個代碼引用該二進制文件,還能實例化新的模板函數。現在先來看debug log輸出的二進制結構。首先是被編譯的代碼。下面的代碼因為是直接從語法樹生成的,所以括號什么的會比較多,...  閱讀全文
            posted @ 2010-07-12 03:12 陳梓瀚(vczh) 閱讀(3113) | 評論 (8)編輯 收藏
                似乎C++“過于復雜”已經成為了詬病,不過對于我個人來講我實在很難理解這個觀點。之前有個朋友說stream::operator<<很復雜,其實也就是幾個overloading。還有些人說傳參數的時候很復雜,這無非就是復制構造函數、析構函數和引用吧。雖然我個人覺得模板元編程其實才是C++里面最復雜的地方,但是鑒于模板元編程實際的用處不大,我想應該只有少數幾個人會使用它。但是這樣很多人還是C++復雜,那我就不知道究竟在指什么了。

                所以大家對C++有什么想噴的就趕緊留言哈,我也好看看別人是怎么理解的,然后討論討論。

                (不過從我自己的角度出發,我認為凡是編譯器不能檢查的東西(譬如可變參數,指針類型強制轉換),都遠比能檢查的東西(模板元編程)要復雜,因為人很容易犯錯,機器不會。)
            posted @ 2010-07-06 19:52 陳梓瀚(vczh) 閱讀(11489) | 評論 (68)編輯 收藏
                這年來屢屢被網友教育說不要造車輪,我覺得我有必要專門寫幾句話來闡述我的觀點。

                1:公司的代碼,自然有規定,你造不了車輪。
                2:自己外包賺錢的代碼,造了也只會浪費時間,這個隨便你。
                3:自己寫的代碼。無論你開源也好,不開源也好,自己寫那些不能換錢的代碼無非就是因為你寫的爽嘛,那造車輪還能提高自己功力,為啥總是有人來說這樣不行呢?這又不是公司的代碼,也不是拿去完成別人外包給我項目的代碼,這個時候你還用別人的東西,完全是沒有意義的。除非你所謂的學習就是學習如何使用別人的車輪。當然我自己的定義是,學習造車輪,不僅能知道很多你不造車輪不知道的東西,同時造完了,你看別人的車輪,瞬間就知道怎么用了。而且如果你想的話,你還能研究一下怎么比別人造得更好。什么?你相信自己無論如何這一輩子寫到死也比別人爛么?那就是另一回事了。
            posted @ 2010-07-01 01:14 陳梓瀚(vczh) 閱讀(5839) | 評論 (21)編輯 收藏
            僅列出標題
            共35頁: First 9 10 11 12 13 14 15 16 17 Last 
            亚洲va中文字幕无码久久| 人人狠狠综合久久88成人| 97久久国产亚洲精品超碰热| 香蕉久久永久视频| 久久国产一片免费观看| 精品精品国产自在久久高清| 婷婷久久久亚洲欧洲日产国码AV| 久久精品视频一| 久久亚洲精品无码VA大香大香 | 性做久久久久久久久浪潮| 99久久精品这里只有精品| 久久亚洲欧美日本精品| 成人国内精品久久久久影院VR| 青青草国产精品久久| 久久99精品国产麻豆蜜芽| 久久伊人五月天论坛| 97精品伊人久久大香线蕉| 免费久久人人爽人人爽av| 中文无码久久精品| 久久精品国产亚洲综合色| 国产99久久久久久免费看| 国产高潮国产高潮久久久91 | 精品久久久久久久无码| 久久久久女人精品毛片| 久久精品国产亚洲麻豆| 天天综合久久一二三区| 久久久久亚洲精品日久生情| 国产精品一区二区久久国产| 中文精品久久久久国产网址| 国内精品久久国产| 日本精品久久久久中文字幕8| 亚洲欧美成人久久综合中文网 | 久久精品国产亚洲av麻豆蜜芽| 精品国产乱码久久久久久呢 | 亚洲午夜久久久影院伊人| 狠狠色丁香久久婷婷综合五月| 久久er国产精品免费观看8| 老色鬼久久亚洲AV综合| 久久久WWW成人免费毛片| 久久国产亚洲高清观看| 一本大道久久东京热无码AV|