摘要: 今天上完課回來繼續把昨天晚上剩下的using字句完成。使用Syngram寫編譯器真是舒服啊,直接在代碼里面加兩條推導式就完成了。昨天發現了InsertEnv指令的bug以后,改過來了。不過InsertEnv不能用在using身上,只好另外寫了一個UsingEnv指令,把環境以及上游的鏈表而不是多個環境插進當前的環境中。這里展示了class和namespace是如何通過閉包(函數)來實現的,以及他們的構造過程。
class以及namespace都是通過在return的跳轉目標后添加指令而保證return結束但是不修改class和namespace表達式的返回值。
class函數的參數是父類的構造子,class函數在所有代碼之前首先構造好一個父類的鏈表,然后通過InsertEnv將這個表引用到自己身上,從而實現了正確的scope。然后讓constructor為空函數。ClassName.new()的時候首先運行class函數(使用callctor而不是invoke來自動找到父類并添加到參數中),然后復制堆棧,獲取construct
閱讀全文
posted @
2008-05-11 21:37 陳梓瀚(vczh) 閱讀(1532) |
評論 (4) |
編輯 收藏
摘要: 今天抓到了一個隱藏了3個月的bug。這個bug以前一直沒有被找到,因為以前寫的用于測試腳本的代碼都沒有出現類成員函數使用非全局的外部對象的情況。Vampire.Kiss用我的Vczh Free Script代替PHP開發了一個網站,過程中也向我提了不少要求。其中有一套就是想在腳本中加入namespace。其實這是相當合理的,只是我沒想到腳本第一次應用就會被用來開發庫。因此今晚就加上了namespace。
實際上在目前的結構中添加namespace并不復雜,因為namespace也可以用閉包來模擬。其實閉包不僅僅是函數,而是一段帶了上下文的指令表。因為namespace本身也是用于控制符號在上下文中解釋方法工具,因此使用閉包來做也就是十分合適的了。想到以前是用閉包模擬class的時候,曾經實現了一個把一堆環境鏈接到上下文中的指令。類的繼承實際上也是控制符號在類成員函數的符號在上下文解釋方法的工具,因此我使用了如下方法來讓閉包可以順利地模擬class的繼承:
閱讀全文
posted @
2008-05-11 10:07 陳梓瀚(vczh) 閱讀(1849) |
評論 (5) |
編輯 收藏
摘要: 有個同學近來一直在做一個魔獸世界戰況分析(名字好像叫DeusCraft),說是很火。只是用C#覺得不是很爽,想移植到C++上面來。但是那個東西在分析的時候用了好多正則表達式,于是只好找了些正則表達式引擎來測。
測試的文件一共有27萬多行,首先通過一個檢查時間的正則表達式。如果成功,則在接下來的20幾條正則表達式中驗證字符串命中哪一條,然后開始做剩余的工作。原先在C#上花了12秒分析,后來換了boost的正則表達式花費40秒,然后從MSR上找了一個號稱比boost快4倍的正則表達式引擎,結果還是40秒(都是微軟的,咋差距這么大……)。于是同學用他自己做的正則表達式引擎花了23秒(此數據不太記得),我用我以前那個東西花費108秒(-_-|||)。
于是我們這幾天就在優化正則表達式引擎,到了今天同學那個花費13秒,我那個12秒。Visual Studio 2008 Team System上有一個Performance Wizard,用于在程序執行的過程中統計各個函數所占用的時間,可以方便定位,看出效率瓶頸,非常好用。
閱讀全文
posted @
2008-05-07 05:21 陳梓瀚(vczh) 閱讀(15440) |
評論 (21) |
編輯 收藏
摘要: 華南理工大學軟件學院本科05級3班,陳梓瀚(vczh)
游戲規則:
1:地圖上可以建立三種炮塔塔,游戲有上、左兩個敵人的起始點,兩個起始點的敵人分別到下、右兩個終止點。
2:每一盤有1000個等級分別從1-200的敵人從起始點出發自動尋路前往終止點。如果有10個敵人到達了終止點的話則游戲結束,玩家輸。如果所有的敵人都被消滅或到達終止點之后,到達終止點的敵人沒有10個的話則游戲結束,玩家贏。
3:建立炮塔的方格敵人不能通過。在建立一個炮塔的時候,如果程序發現這個炮塔的建立會導致敵人找不到任何路徑前往各自的終止點的話,則建立被禁止。
4:炮塔可以是用金錢建立或升級,可以賣出貨的金錢。消滅敵人能夠獲得金錢。
5:三種炮塔分別是
·升級后數量變多,射程變長,攻擊力變強
·升級后速度變快,射程變長,攻擊力變強
·升級后一次爆炸傷害的范圍變大,射程變長,攻擊力變強
·升級一次后減速范圍變大,減速因子變大
6:炮彈在 閱讀全文
posted @
2008-05-02 21:46 陳梓瀚(vczh) 閱讀(9534) |
評論 (27) |
編輯 收藏
摘要: 第一次用C#寫游戲。在C#上寫算法果然是一個挑戰,時間復雜度太大的話造成的后果比C++明顯好多,于是總是盡量把東西做成O(n)或者O(nlogn)。這次就在上面實現了一個尋路算法。
這個尋路算法是這樣的:在16×16的方格上有一些終點,東西在格子上只能上下左右行動。每一個格子需要記錄到其中一個終點的最近的路的第一個方向(就像三層循環的尋路算法一樣,最后給出矩陣的那個)。 閱讀全文
posted @
2008-04-30 05:29 陳梓瀚(vczh) 閱讀(4447) |
評論 (5) |
編輯 收藏
摘要: Lazy Compile使用Syngram動態創建語法分析器的代碼實在是太慢了,debug竟然需要8秒鐘來處理91條比較長的文法。于是我打開了Visual Studio 2008的Performance Wizard查看運行時消耗的資源,結果發現竟然都消耗在自己那個array類的operator[]里面了。那一段代碼是用來檢查文法的左遞歸引用關系是否出現環的。結果就把用到的四個array全部換成bool*了,當時只是為了創建二維數組方便使用了array類。
過后,debug的時間立刻降為2秒鐘不到,于是我又打開Performance Wizard看了一次,這次消耗的瓶頸終于轉移到一個合理的地方了。
結果:array竟然比指針慢了無窮多倍,得找個時候重新寫一次。不過這段代碼好象是去年寫的,也沒經過什么性能測試,也難怪發現不了問題。在此帖上代碼,等Lazy Script寫完了重新審查一下自己的那套模板庫(NTL,Non-standard Template Library,娃哈哈)。 閱讀全文
posted @
2008-04-27 19:53 陳梓瀚(vczh) 閱讀(2626) |
評論 (6) |
編輯 收藏
摘要: 這幾天一直在忙學校的比賽,到了今天終于有空了。
Lazy Script的語法實在是很復雜,因此不得不在進行第一步的名字檢查之后把原本的語言轉換為內部使用的一種元語言。這種元語言設計的原則是盡量簡單。譬如列表構造和do-end語句就需要被轉換掉。進行了轉換以后,就需要對元語言進行一個類型方程組的建立。這一步暫時還沒有建模好,而且實際工作需不需要真的構造出一組方程組還不知道。目前還比較沒有頭緒的就是如何對模板函數的類型方程建模。
舉個例子,譬如我們對上一篇文章中提到的代碼進行類型方程組的構造: 閱讀全文
posted @
2008-04-27 10:16 陳梓瀚(vczh) 閱讀(2134) |
評論 (0) |
編輯 收藏
摘要: 花了兩天的時間終于完成了Vczh Lazy Script的語法分析工作。語法分析是編譯的第一步,旨在把輸入的字符串(代碼)分析稱跟代碼結構一致的語法樹,以便后續工作。
藉著去年開發的Syngram工具包,這兩天過得還算輕松,僅僅對語言做了一份配置,不過這份配置也花掉了1200多行代碼。語法分析其余的部分是數據結構。目前的數據結構僅僅用于再現語言的結構,而沒有附加任何的數據。接下來的工作是檢查所有的identifier,看看有沒有哪些identifier是使用錯誤的。一般來說都是在左值使用函數、類構造標簽參數不全、轉移運算符指向的函數并沒有聲明成函數等等比較基本的東西。但是后續的工作就相當地麻煩了。
作為一門lazy+pure的函數范式程序語言,我模仿了Haskell的大部分語法,加上自己的一點點修改(因為Haskell的語法實在是太詭異了),但是主要功能是沒有變化的。等上面所說的identifier完成以后,我就要開始寫Lazy的類型推導程序了。類型推導程序用于計算出代碼中省略的類型聲明,相當于把整份代碼轉換成類型方程然后求解 閱讀全文
posted @
2008-04-22 04:03 陳梓瀚(vczh) 閱讀(2552) |
評論 (4) |
編輯 收藏
摘要: 已經忘了是去年還是前年聽到微軟說要在C# 3.0里為C#添加lambda表達式,與此同時Java的團隊也一直在說想為Java添加lambda表達式。到了今天,C#似乎已經把這個特性加進去了,Java還沒有。Java說這個特性還在計劃列表之中,不過暫時可以使用匿名類來代替。想必是因為在Java中表示函數指針的方法比較奇怪罷……
其實無論是lambda表達式(事實上應該叫匿名函數)或是匿名類,都能歸屬到一種叫閉包的東西上面。閉包原來是代數中的用語,只是那些研究理論的老大們覺得這玩意兒也能拉到“閉包”里面去,于是就叫閉包了。匿名函數原本是丘奇發明的一個lambda-calculus的其中一部分,后來計算機的老大們突然發現lambda-calculus非常適合用來充當程序設計語言的模型,于是就對它進行了非常多的擴充,還弄了個什么類型理論出來。好像扯遠了。
想象一下如下使用閉包的代碼:
MyClosure=func(Number1)
{
return func(Numbe 閱讀全文
posted @
2008-04-20 21:55 陳梓瀚(vczh) 閱讀(7712) |
評論 (5) |
編輯 收藏
摘要: ExpCmList -> Expression ["," ExpList]
ArrCmList -> [LeftValue "<-"] Expression ["," ArrList]
CaseList -> LeftValue ":" Expression ";" [CaseList]
DoList -> ([LeftValue "="]Expression | LeftValue "::" TypeDes ) ";" [DoList]
WhereList -> (FuncHead | FuncBody) ";" [WhereList]
Exp0 ->
Exp0 -> FuncName
Exp0 -> "(" [ExpCmList] ")"
Exp0 -> "[" [ExpCmList] "]"
Exp0 -> "[" Expression "|" ArrCmList "]"
Exp0 閱讀全文
posted @
2008-04-20 20:50 陳梓瀚(vczh) 閱讀(1864) |
評論 (3) |
編輯 收藏