PLT 板


LINE

看板 PLT  RSS
※ [本文轉錄自 Programming 看板 #1K6QEZAk ] 作者: wayfarer (maniac) 看板: Programming 標題: [心得] 寫一個自己的程式語言 -- ACLang 時間: Wed Sep 17 23:07:04 2014 寫一個自己的程式語言 -- ACLang (æ- klæng) ACLang 是個 C-Like 的動態型別語言,目前大部份語法已完成, 目標是成為 Embedded-Scripting Language,開發 Plugin 用。 這篇只是在寫 ACLang 過程中隨手的心得而已,有興趣就看一下吧。 ACLang 完整程式碼在: https://github.com/madedit/aclang 編譯好的Win32執行檔可在此下載: http://sourceforge.net/projects/aclang/files/?source=navbar 可輸入多行程式碼,最後要按 Ctrl+D & Enter 才是真正開始執行輸入的程式。 可用: printAST(1); 開啟印出 AST 的功能 printIR(1); 開啟印出 LLVM IR 的功能 printGC(1); 開啟印出 GC delete 的功能。 對開發自己語言有興趣的可先參考此篇文章: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/ Writing Your Own Toy Compiler Using Flex, Bison and LLVM 以下心得文開始: * 手寫 Lexer & Language Syntax: ACLang 是 C-Like 的語法,純粹只是個人喜好。 我並沒有使用 Lex/Flex 之類的工具來做, 第一是 Lexer 的功能算是簡單的, 就只是處理輸入的一整段程式碼,切成一個一個的 Token; 第二就是有些語法用 Lex 來做不夠彈性,錯誤處理也比較麻煩。 一開始是參考 D 的語法來寫的,所以會有一些 D 才有的語法小功能,像是: * var i = 987_654_321; //可在數字中隨意插 _ * print( 0x8000_0000_0000_0000 ); * var b = 0b0110_0011; //二進位數字 0b 開頭 * var a = /+ /+ +/ +/ 100; //階層式的範圍註解 /+ +/ ACLang 也參考了很多 Squirrel (http://squirrel-lang.org/), 像 array, table 型別是從 Squrriel 來的,而 Squirrel 也參考很多 Lua。 ACLang 裡對要使用的變數都要先明確的用 var 或 local 宣告, 避免像 Lua 變數打錯字還是當做有效變數(只是值是nil)的問題。 用 var 宣告表示此變數會存到一個指定的 table 中,如: var ::a = 10; //在 root-table 新增變數 a var this.t = {}; //在 this-table 新增變數 t var t.x = "abc"; //在 t table 新增變數 x 因為 t 沒有指定 scope,所以會以 this-table 為第一順位。 變數的 scope 就是以指定的為主,有 :: (root-table) 與 this. (this-table) 若沒指定就先找 local變數,再找 this-table,最後找 root-table。 local 則表示此變數只會存在現在的執行的 function 中, 當離開此 function 即無法存取此 local 變數,除非用 return 的方式傳出。 以效率來說盡量使用 local 變數會比較好。 每個 function 都會有個隱性的 this-table, 若是在 global 的話, this-table 就是 root-table 。 * Parser & AST,使用 GNU Bison: 網路上可找到 ANSI C 的 yacc 語法檔,我是用這個再修改成 ACLang 的語法。 Parser 透過 Lexer 取得每個 Token,再由建立好的表格找到這 一系列 Token 對應到的程式區塊,然後執行這個程式區塊, 這個程式區塊裡面就是產生 AST (Abstract Syntax Tree) 的程式碼。 寫語法定義一定會遇到很多 conflicts,只有想辦法消除了。 像 if(ooo) xxx; 跟 if(ooo) xxx; else yyy; 就一定會衝到, 就只能用 %nonassoc %prec 來解了。 就跟 Lexer 一樣,用 Bison 來做 parser 會遇到的問題就是不夠彈性, 還有錯誤處理有些麻煩的問題,Bison 印出來的錯誤訊息太過制式化了, 除非以後 Parser 也要改成自己手寫的,不然就只能先這樣了。 * Code Generation: 在經過 Parser 產生 AST 後,每個 AST 可對應到一個 LLVM::Value*, 這樣可很簡單的針對每一個 AST 寫個 codegen 的 function 出來, 回傳值都是 LLVM::Value* 。 大部份 IR 指令都可用 LLVM::IRBuilder 裡包裝好的 function 來產生。 ACLang 使用 LLVM 的 JIT 功能做中介層,但底層還是 C++ 寫的Code, 例如 var a = "123" + 456; 這個加法的運算實際會去呼叫 ACLang 向 LLVM JIT 註冊的一個全域函式 opAddVar(),這個函式裡面才會 去判斷兩個變數的型別再來決定要做整數相加還是字串連結。 LLVM 有提供 CppBackend 的功能,就是可以把 LLVM IR 轉換成 C++ 的 code, 有時候不知道怎麼create某些 IR,就可以用這個作為參考。 以後 ACLang 的 C++ 底層也可用 LLVM 的 CppBackend 轉成 LLVM 的 IR, 再利用LLVM的IR最佳化提升效能。不過這也是個大工程,以後有空再說吧。 * Data Type & Variable ACLang 是動態型別語言,目前有以下類型: * integer: int32 & int64 * float: float & double * string * array * table * function * userfunc: C/C++寫的 function 再 bind 到VM中,stdlib中的都是(如 print) 變數Variable在使用前必須用 var 或 local 明確宣告,例如: var a, b, c=[1,2,3]; for(a,b : c) print(a, b); for(local c, d : [1,2,3]) print(c, d); local t = { a=10 }; var t.b = 20; //在 table t 新增 b 變數 function也是變數的一種,可當參數傳遞: function f1(f) { f(100); } var f2 = function(i) { print(i); }; f1(f2); * Virtual Machine: VM 在 ACLang 只是個包裝所有功能的架子。 VM.runCode(code) 會 compile 傳進來的 code, 用 LLVM JIT 編譯成一段 function 再去執行它。 VM 裡有個最主要的 RootTable,所有的資料都是存在裡面。 * Garbage Collection: GC 已是現代程式語言必備的功能,讓你只需要 new ,不需要管 delete, 由語言幫你檢查並 delete 不再使用的資料。 ACLang 有個中央控管的資料結構 root-table,所以實作 GC 並不是非常困難。 ACLang 使用的是 Tri-Color Incremental Mark & Sweep GC , 所有的 Variable, Function...等等一切資料都會在 root-table 裡面, 然後當要產生物件時都是透過 gc.createObject(), GC再將產生物件都存在一個 List 裡面,存實際 new 出來的所有變數, 然後只要去 mark root-table 裡面的變數, 若沒被 mark 到就表示此變數是無主孤魂不再被使用,可以被回收刪除了。 這個演算法的好處是可以使用 gc.incrementalGC(time) 告訴此次gc會花多少時間, 讓使用者決定本次要花多久來做 GC,例如在遊戲中每個frame花個一個clock來做GC。 當然也可使用 gc.completeGC() 做一次完整的GC,這就可能會花很久時間了, 若是在遊戲中你就可能會發現遊戲lag一下。 * Error Handling: * Compile-Time Error 在Compile階段會有 Lexer&Parser&LLVM JIT編譯時的錯誤, 比較先進的Compiler都可以在遇到一個錯誤時設法壓住這個錯誤, 繼續Compile剩下的Code,看能不能再找到更多的錯, ACLang 沒這麼強,只能一次處理一個錯。 * Run-Time Error 目前還沒有完整實作,只有最基本的,在執行時遇到錯誤就印出錯誤訊息, 然後用 setjmp/longjmp 跳回一開始設定的插入點,結束程式。 例如字串除數字: var a = "123" / 10; 目前只會印一行錯誤訊息而已,以後還需要印出 CallStack 跟行號, 才能讓使用者能更清楚是哪裡發生錯誤。 * StdLib: 像是 print(), typeof() 之類的都是用 C++ 寫的function, 再 bind 回 ACLang VM 中使用的 userfunc。 以後會再增加字串處理、數學函式、檔案讀寫等等的標準函式庫。 目前要bind function還是必須寫個 wrapper function才能讓 ACLang VM使用, 以後或許可以再改進用 C++ template 的方式做。 * 效能: 雖然是用 LLVM 的 JIT 產生 native code,但是 ACLang 是動態型別的語言, 所以還是必須在執行時期動態判斷變數的型別,才能正確的進行運算, 例如: var a = "abc" + 123; //a會等於"abc123",123先轉成字串,再連接起來 因此效能就比不上靜態型別的語言。 還有在每次call function時都會產生一些暫時的變數用來傳遞參數, 這也是很花時間,需要再做改進。 * TODO: * 類似 OOP 裡 class 的繼承功能 與 Operator Overloading 目前已有初步的想法了,會用類似 Lua 的 metatable 的作法, 這個是之後會優先實作的功能。 * namespace 其實就是用 table 包著 table 來實作就可以了。 * delegate 可改變傳給 function 的 this-table。 * 移除 LLVM JIT 產生的 function ACLang 每個 function 裡實際上是包著 JIT 產生的 function pointer, 目前當 function 被 gc delete 掉後,JIT的function還是存在著, 之後要再看看怎樣移除。 對寫個自己的 Programing Language 有興趣的話可以一起討論, Thanks~~ --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.136.11.150
※ 文章網址: http://webptt.com/m.aspx?n=bbs/Programming/M.1410966435.A.2AE.html
1F:推 suhorng: 推 111.248.47.80 09/17 23:28
2F:→ suhorng: 請問可以轉錄嗎? 111.248.47.80 09/17 23:28
3F:→ wayfarer: 可以,請隨意。 223.136.11.150 09/17 23:44



※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: suhorng (111.248.47.80), 09/17/2014 23:46:54
4F:推 NilPtr: 高手 是說我最近剛好也想研究LLVM呢 12/23 23:29
5F:推 NilPtr: 補推。是說Lua的型態頗有趣,就是用Union包了一堆東西 12/23 23:34







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP