這是用於正在編寫的書“Crafting Interpreters”的存儲庫。它包含本書的 Markdown 文本、兩個解釋器的完整實現,以及將兩者編織在一起形成最終站點的構建系統。
如果您發現錯誤或有建議,請在此提出問題。謝謝你!
在網上寫一本書並在完成之前將其發佈出去的絕對最好的事情之一就是像你這樣的人很友善地給我反饋,指出錯字,並發現其他錯誤或不清楚的文字。
如果您願意這樣做,那就太好了!您可以在儲存庫上提交錯誤,或者如果您願意的話可以發送拉取請求。如果您想傳送拉取請求,但又不想將建置系統設定為重新產生 HTML,請不要擔心。當我把它拉進去時我會這樣做。
另一種參與方式是分享您自己的 Lox 實作。移植到其他語言特別有用,因為並非每個讀者都喜歡 Java 和 C。
我是一種非常健忘、容易出錯的哺乳動物,所以我盡可能地自動化。
我在 OS X 機器上進行開發,但任何 POSIX 系統也應該可以運作。透過一些額外的努力,您應該也能夠在 Windows 上運行它,儘管我幫不了您太多。
大部分的工作都是由 make 精心策劃。建置腳本、測試運行器和其他實用程式都是用 Dart 編寫的。安裝 Dart 的說明在這裡。安裝 Dart 並在路徑上後,運行:
$ make get
這將下載建置和測試腳本使用的所有套件。
為了編譯這兩個解釋器,您的路徑上還需要一個 C 編譯器以及javac
。
一旦你完成了設置,請嘗試:
$ make
如果一切正常,將會產生本書的網站並編譯兩個解釋器 clox 和 jlox。您可以直接從儲存庫的根目錄執行任一解釋器:
$ ./clox
$ ./jlox
使用手寫的靜態網站生成器將 Markdown 和原始程式碼片段編織到最終的 HTML 中,該生成器最初是我第一本書的一個小型 Python 腳本,後來以某種方式成長為接近真實程式的東西。
產生的 HTML 提交到site/
下的儲存庫。它是由 Markdown 散文(位於book/
中)和從java/
和c/
中的 Java 和 C 實現編織而成的程式碼片段組合而成。 (原始程式碼中所有那些看起來很有趣的註解都是它如何知道哪個片段去哪裡的。)
完成所有魔法的腳本是tool/bin/build.dart
。您可以直接運行它,或者運行:
$ make book
這會批量產生整個網站。如果您正在逐步開發它,您將需要運行開發伺服器:
$ make serve
這會在以site/
目錄為根的本機上執行一個小型 HTTP 伺服器。每當您要求頁面時,它都會重新產生來源已變更的所有文件,包括 Markdown 文件、解譯器來源檔案、範本和資產。只需讓它繼續運行,在本地編輯文件,然後刷新瀏覽器即可查看更改。
您可以像這樣建立每個解釋器:
$ make clox
$ make jlox
這建立了每個解釋器的最終版本,因為它出現在書中該部分的末尾。
您還可以在每章末尾看到口譯員的樣子。 (我用它來確保它們即使在本書的中間也能正常工作。)這是由腳本tool/bin/split_chapters.dart
驅動的,該腳本對程式碼片段使用相同的註解標記來確定哪些程式碼區塊是出現在每一章中。它只需要每章末尾看到的程式碼片段,並在gen/
中產生原始程式碼的新副本,這是每章程式碼的一個目錄。 (這些也是查看原始程式碼的更簡單方法,因為它們刪除了所有分散注意力的標記註釋。)
然後,每個都可以單獨建造。跑步:
$ make c_chapters
在build/
目錄中,您將獲得每個章節的可執行文件,例如chap14_chunks
等。
$ make java_chapters
這會將 Java 程式碼編譯為每章子目錄中build/gen/
中的類別檔案。
我有一個完整的 Lox 測試套件,我用它來確保書中的解釋器做他們應該做的事情。測試用例位於test/
中。 Dart 程式tool/bin/test.dart
是一個測試運行程序,它在 Lox 解釋器上運行每個測試文件,解析結果,並驗證測試是否執行了預期的操作。
您可以針對多種解釋器執行測試:
$ make test # The final versions of clox and jlox.
$ make test_clox # The final version of clox.
$ make test_jlox # The final version of jlox.
$ make test_c # Every chapter's version of clox.
$ make test_java # Every chapter's version of jlox.
$ make test_all # All of the above.
歡迎您使用測試套件和測試運行器來測試您自己的 Lox 實作。測試運行器位於tool/bin/test.dart
,可以使用--interpreter
為自訂解釋器可執行檔提供運作。例如,如果您在my_code/boblox
有一個解釋器可執行文件,您可以像這樣測試它:
$ dart tool/bin/test.dart clox --interpreter my_code/boblox
您仍然需要告訴它要執行哪一套測試,因為這決定了測試期望。如果您的解譯器的行為應類似於 jlox,請使用「jlox」作為套件名稱。如果它的行為類似於 clox,請使用「clox」。如果您的解釋器只完成了書中某一章的結尾,您可以使用該章作為套件,例如「chap10_functions」。有關所有章節的名稱,請參閱 Makefile。
如果您的解釋器需要傳遞其他命令列參數來使用,請使用--arguments
將它們傳遞給測試運行器,它將轉發給您的解釋器。
asset/
– 用於產生網站的 Sass 檔案和 jinja2 範本。book/
- 每章文本的 Markdown 文件。build/
- 中間檔案和其他建置輸出(網站本身除外)位於此處。不致力於 Git。c/
– clox 的原始程式碼,用 C 編寫的解釋器。gen/
– 由GenerateAst.java 產生的Java 原始檔位於此處。沒有承諾。java/
– jlox 的原始碼,用 Java 寫的解釋器。note/
– 各種研究、筆記、TODO 和其他雜項。note/answers
– 挑戰的範例答案。沒有作弊!site/
– 最終產生的網站。該目錄的內容直接鏡像 craftinginterpreters.com。這裡的大部分內容都是由 build.py 產生的,但字體、圖像和 JS 只存在於這裡。一切都已提交,甚至生成的內容也是如此。test/
– Lox 實作的測試案例。tool/
– 包含建置、測試和其他腳本的 Dart 套件。