從零開始的Lua教程(零):學習路線
從零開始的Lua教程(零):學習路線
出於分享學習心得和獲得同伴討論學習的目的,我打算寫一個教程給想要學習如何實現lua的同學提供一個參考。
我的學習經歷
我在去年4月開始接觸到遊戲引擎的腳本引擎,那時我在讀一本名為《遊戲腳本高級教程》的書。
書的內容是開發一個叫做xscript的腳本語言。作為xscript的前奏,書的開頭首先實現了xscript的彙編語言xasm,包括彙編器和解釋器。然後還有一個遊戲內控制檯系統(很多遊戲都有,比如上古捲軸和饑荒),可以認為控制檯系統是一個簡單的腳本語言。
這本書寫得很爛,但是在我的腦子裡植入了一個想法:腳本引擎是一個方便的開發工具。
經過一些搜索和學習,我選擇了lua語言並決定實現它。
我從4月開發到8月底,完成了python和c#兩個版本。
這裡我使用了原型開發方法:先使用python開發項目原型,理解實現框架和基本概念,使用pythonic的方式編寫優雅的代碼,忽略邊界條件和細節。然後再用c#重寫並最終實現項目。
8月底我結束了lua項目,這時python原型已經通過了官方大概1k行lua源文本的測試和我手寫的單元測試,並實現了以下功能:
- 實現大部分lua語法
- ANTLR輔助下實現的編譯器
- 虛擬機,附帶一個簡單的調試器
- 與宿主語言的互操作,即lua和python能互相調用函數
在使用c#重寫時,我發現語言之間的差異有時很大,c#實現到能運行hello world之後就草草結束。
今年3月底,我重新開始了這個項目,現在正在重寫這個項目,因為實習的原因,四月中旬暫停了這個項目。
學習路線
我提供一個學習路線:
- 首先需要一些編程的經驗,應該掌握一門強類型語言和一門弱類型語言
- 然後需要編譯原理的知識,包括以下主題:
- 瞭解編譯器大概如何工作(龍書第2章)
- 詞法分析
- 語法分析的LL演算法
- 代碼生成
- 然後實現一個json解析器,參見milo yip的json教程
- 從零開始的 JSON 庫教程 - Milo Yip的文章 - 知乎 https://zhuanlan.zhihu.com/p/22457315
- 然後選擇一個lua教程學習,比如菜鳥教程
- 回答以下兩個問題檢測學習效果:
- 元表查找機制是怎麼樣的?
- 實現一個簡單的OOP機制
- 閉包機制時怎麼樣的?
- 然後才開始實現lua,獲取以下資料後結合lua源代碼學習如何實現lua:
- 《Lua設計與實現》
- 《自己動手實現Lua》
- 《Programming in Lua 4th Edition》
- 《The Implementation Of Lua5》
- 《A No Frill Intro To Lua5.1 VM Instructions》
- 《Lua Bytecode Reference 5.3》
- 《The Evolution Of Lua》
這裡我不太能描述清楚具體的細節,或者給出一個step by step的guide,因為學習是每個人獨特的經歷。
比如有些資源在這一年裡我反覆學習了若干次,比如leptjson,很難去描述清楚哪一步做到什麼地步。
實現路線
我提供一個實現路線:
將lua分為前端編譯器和後端虛擬機兩個部分。
首先實現虛擬機。為了測試虛擬機,實現undump模塊,使用clua編譯出二進位chunk文件,由undump讀取出Proto實例,餵給虛擬機執行。
- 實現lundump模塊(luaU_undump函數)
- 實現lopcodes模塊
- 實現lobject模塊
- 實現虛擬機的指令循環(luaV_execute函數)
然後再實現編譯器,按詞法分析,語法分析,代碼生成的順序即可。
推薦閱讀: