某個大神真是牛逼得不行了, 連發文章用 LLVM 造語言
一篇是 Haskell, 一篇是 Python, 看得我都飄飄然了, 覺得好簡單
http://www.stephendiehl.com/llvm/
http://dev.stephendiehl.com/numpile/
整體上說, LLVM 已是很是棒的平臺了, 各類語言都能編譯到他
好比說 Rust, Julia, 兩個語言基本上就是靠着 LLVM 強大功能強大起來的
另外 Clang 跟 Swift 是蘋果自家就不消說了
我注意到 Haskell 竟然也支持選項開啓使用 LLVM 做爲編譯後端
沒看到完整列表記錄有哪些語言, 可是逛 Wiki 提到的已經很很多了
http://en.wikipedia.org/wiki/LLVMhtml
使用 LLVM 的話, 編譯的流程就清晰多了前端
源碼 -> AST -> LLVM IR -> LLVM Bytecode -> ASM -> Nativenode
通常 LLVM IR 的文件後綴是 .ll
, Bytecode 文件後綴是 .bc
其中 IR 是可讀的, 比彙編好懂一些, .bc
文件我沒怎麼接觸過了git
要看具體 IR 長什麼樣子的話, 其實用 Clang 能夠把 C 代碼一步步編譯過去
從 C 編譯到 LLVM IR, 而後 IR 編譯到彙編, 彙編生成機器碼
http://ellcc.org/demo/index.cgi
https://idea.popcount.org/2013-07-24-ir-is-better-than-assembly/github
我本身花了點時間照着試過, 好比說保存一個 IR 文件, 看看怎麼編譯.macos
text➤➤ cat hello.ll declare i32 @putchar(i32) define i32 @add(i32 %a, i32 %b) { %1 = add i32 %a, %b ret i32 %1 } define void @main() { %1 = call i32 @add(i32 0, i32 97) call i32 @putchar(i32 %1) ret void }
LLVM 的 lli
命令能夠直接運行 .ll
文件, llc
命令能夠編譯彙編:編程
text➤➤ lli hello.ll a➤➤ llc hello.ll ➤➤ l hello.ll hello.s
而後彙編能夠用 clang
直接編譯到二進制文件的,
只是很奇怪在 OS X 會多出一行來報錯, 去掉這一行而後編譯就經過了:vim
text➤➤ clang hello.s -o hello.native hello.s:2:2: error: unknown directive .macosx_version_min 14, 3 ^ ➤➤ vim he hello.ll hello.s ➤➤ vim hello.s ➤➤ clang hello.s -o hello.native
這個問題前面寫教程的大神也沒給解決, 估計大神不用 Mac...
https://github.com/sdiehl/kaleidoscope/issues/19
另外匯編編譯二進制文件的話 nsm
as
命令好像均可以, 我不大熟悉...後端
只是編譯 IR 的話, 我搜到了還有另外一篇給了另外一種途徑, 先編譯對象文件:數據結構
text$ llc -filetype=obj hello_world.ll $ gcc hello_world.o -o hello_world $ ./hello_world Hello World!
http://www.wilfred.me.uk/blog/2015/02/21/my-first-llvm-compiler/
這個我不大瞭解, 可是 Anyway 對象文件也是語言編譯的一個環節沒錯
要看生成代碼的話還有個很方便的辦法就是看 Julia 生成的代碼
神奇的 Julia 把 JIT 看成靜態編譯在用, 結果是在 REPL 當中直接看編譯結果
文章裏列舉的, 從 AST, 到 LLVM IR, 到 ASM 全都能打印, 我就說逆天...
http://blog.leahhanson.us/julia-introspects.html
做爲腳本語言入門並且心思花在腳本語言上的人, 我很不適應機器的思惟方式
雖然理解是理解, 但要寫代碼生成代碼最後能運行, 還真的是兩種感受
IF/ELSE 的控制邏輯轉化到低級語言, 相對還好懂一點
http://www.stephendiehl.com/llvm/#chapter-5-control-flow
可是看看各類高級一些的抽象怎樣被轉化到指令就以爲很揪心了
http://llvm.lyngvig.org/Articles/Mapping-High-Level-Constructs-to-LLVM...
我後來還想, Haskell 那樣的高階函數怎樣編譯爲指令呢? 想不出來傻掉了
大體接觸下來 LLVM IR 彷佛有幾點跟彙編之類的東西不一樣的
LLVM IR 假定寄存器有無限個, 因此變量名隨便用, 不怕用完
LLVM IR 的語句都是 Static Single Assignment, 大概意思就是隻能賦值一次吧
並且做爲低級語言, 是沒有嵌套的, 是帶類型的, 這個在編譯過程都要作
另外我後來才注意到基礎類型當中是沒有 String 的, 就像 C 同樣幾乎是 Int 模擬的
我對於底層的硬件這些細節太缺少了解了, 如今我真的太佩服 Haskell 了
C 這種語言徹底是編譯器開發者偷懶, 據說仍是直譯彙編的, 這叫什麼高級語言啊
我前些天還在看 Babel 怎麼編譯 ES6 到 ES5, 怎麼搞尾遞歸啊參數 Spread 啦
如今想一想動態語言當中字符串編譯仍是比 LLVM IR 溫柔很多的
並且能在 AST 基礎上進行操做, 已經比起 IR 有天壤之別了
我想起來 Go 語言也是把 AST 暴露出來給開發者操做的, 真是明智啊
https://github.com/jcla1/gisp
https://github.com/DAddYE/igo/
不過 Go, Lua 這些雖然贊, 可是返回多參數, 徹底是衝着實用設計的語言, 不能多想
LLVM 目前的綁定支持的語言很多 C++, OCaml, Haskell, Python, Go, Ruby, Node.
官方的 Kaleidoscope 目前也有多語言的版本 C++, OCaml, Haskell, Python
但官方文檔裏就 C++ 跟 OCaml, 並且 C++ 不知道比 OCaml 長多少...
我今天嘗試過安裝 Haskell, Go, Node 的版本.
Haskell 的缺依賴沒安裝成功, Go 的 llvm.org 倉庫證書失敗 GitHub 版本也沒裝成功.
Node 這邊的 node-llvm 跟 llvm-x 沒裝成功, 剛出來個 llvm2 裝了卻不會用
無論怎麼說 llvm2 是我今天惟一一個安裝成功的版本, 藉以安慰一下...
https://github.com/dirk/llvm2 第一個 commit 仍是 7 天前的..
原本我是想裝逼寫個編譯的 Demo 出來的, 文檔挖了兩天, 失敗了失敗了
可是類型推斷的話, 以以前寫解釋器的遞歸的方案, 仍是能推導出一部分的, 好比說
cirrutype-define funcName retType (arg1Type arg2Type) define funcName (arg1 arg2) ret r1
這樣的寫法, 我用類型聲明的方式, 能夠先明肯定義函數的類型是什麼
而後若是是嵌套的話, 好比定義變量 a
是 (1 + (3 + 4))
,
cirru% a (+ 1 (+ 3 4))
只有從內部往外一層層計算, 最終 a
的類型其實能夠推出來(假如這裏只用 float
)
並且, 嵌套表達式要轉換 SSA 那樣簡單的賦值指令的話, 能夠修改表達式返回的數據結構,
這樣 (+ 1 x)
再也不返回一個值, 而是對象, 有依賴代碼, 類型, 生成代碼, 這些東西..
cirruobject :depend $ array ":+ 3 4" :text + 1 %b :type :float
我只是想說, 中間有一部分仍是不難的, 可是對於高階函數真的要傻了
而後呢, 還有複雜的數據結果, 代數數據結構怎麼辦? 天曉得 Haskell 是怎麼實現的..
原來有一門高級語言能夠用是多麼不容易的事情, 真的應該知道知足啊
吐槽到此結束, 我仍是有那種想要本身發明編程語言的...維護自尊心之類的想法吧
只是從實際的複雜度上看, 我沒有足夠的精力跟資源能夠投入在裏邊
不過 LLVM 真的已經把語言編譯的門檻拉低累很是之多, 不少語言藉此冒出來了
LLVM 的文章有大神翻譯了幾章, 不過確實比不上直接海翻英文資源...
http://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.org/zh_CN/latest/
又想起要吐槽的事情了.. 前端那羣都在搞些什麼啊, 一天到晚發明新的框架新的工具 就不能學學編譯這邊發點 Paper 把底層原理搞清楚, 而後放點心思好好設計下平臺 V8, CommonJS, AMD, React, Webpack, 這些確實算得上深思熟慮, 可是其餘隨處搶山頭的技術也太多了吧, 打包工具滿地都是, MVC 框架滿地都是 好吧這麼說確實有點過, 微型框架獨到之處確實很多. 可是 Paper 跟平臺什麼真心少啊.