Cirru 是怎樣編譯到 Clojure 的

2021-09-16 12:29:31 字數 3034 閱讀 7473

這篇文章解釋一下 cirru 到 clojure **的編譯步驟.

目前編輯使用的是 cumulo editor, 參考這裡的 demo.

cirru 是整個大的專案的名字, cirru 本身的目標是 ast 程式設計,

而 cumulo editor 是目前專案下最新的語法樹編輯器. 也就是 ast 裡的 syntax tree.

所以在新聞中你看到的 cirru 的存在形態, 目前是這樣的:

這個函式表示的是下面這段 clojure **:

(defcomp

comp-search

(buffer query mock-ssr?)

(div

(div

{}(if mock-ssr?

(div (<> span "loading..." nil))

(input

})))

(=< nil 16)

(if (>= (count query) 2)

(let [results (->> information

(filter

(fn [item]

(string/includes?

(string/lower-case (:title item))

(string/lower-case query)))))]

(if (empty? results)

(div (<> span (str "找不到" (pr-str query) ".") nil))

(div

(->> results (map-indexed (fn [idx item] [idx (comp-item item)])))))))

(=< nil 16)

(if (>= (count query) 2) (comp-search-engine query))))

這中間有比較複雜的編譯過程. 我首先把上面的內容, 簡化.

比如當中的 dom, 在瀏覽器當中實際上是 html, 大致可以表示成:

這個結構用 json 表示的話, 可以是:

["defcomp", "comp-search", ,

["div"]]

這在 clojure 裡, 類似的 json 的資料格式叫做 edn, 和 json 相似, 看上去這樣:

["defcomp" "comp-search" 

["div"]]

不過實際當中考慮到原資訊和優化方案, 這個結構其實很複雜

比如說這"comp-search"實際儲存當中的會帶上很多資訊:

完整的結構非常繁瑣, 需要借助工具才能檢視, 如果非要檢視的話:

歸結一下來說, 大致上 cirru 在程式中使用和最後儲存的格式對應是這樣:

["defcomp" "comp-search" 

["div"]]

這是 s-expression 的一套簡寫. 只要用 vector 和 string 就能直白地表示.

雖然 clojure 語法不僅僅是 s-expression, 但是說大部分可以用 s-expression 表示沒問題.

當然, 這樣肯定不能表示 macros, 也不能表示各種 reader 生成的語法.

實際開發當中可以和 clojure **混用, 好在很多**其實這套方案是足夠的.

還要考慮的乙個問題是 cirru 當中為了統一字首表示式約定了一些寫法,

在 clojure 當中存在慣用的寫法, 這就需要預先進行轉換了.

比如 cirru 當中["{}" [":a" "1"]]對應,["" "1"]對應[1],

甚至字串標記"|str1"對應"str1", 都需要做轉換.

為了完成這個功能, 我寫了乙個模組專門在 symbol 層面做了資料轉換:

在這個模組當中, 甚至的caseletdefn等函式或特殊格式做了調整,

某種程度上和在 clojure 當中習慣是不一致的, 但是在 cirru editor 當中很更清晰.

也是得益於 lisp 整個語法設計的精巧, 才能很容易達成.

生成**反而是簡單的, 由於現成的類庫比較強大:

fipp 可以接受 symbol 型別的 s-expression, 返回格式化完成的**.

而且這個**的布局和縮排都比較符合人們閱讀的習慣.

這是 fipp 給出的乙個將 quote list 編譯到 clojure **字串的 api:

(fipp.clojure/pprint '(let [foo "abc 123"

bar ]

(do-stuff foo (assoc bar :w 4)))

)

所以總結下來, 從最初的 cirru editor 採用的儲存格式:

["defcomp" "comp-search" 

["div" ["{}" [":style" "style-searcher"]]]]

首先會在 symbol 層面進行一些轉化, 得到乙個 quoted list:

'(defcomp comp-search ()

(div ))

最後由 fipp 生成帶縮排的**字串:

(defcomp comp-search ()

(div ))

C 是如何編譯的

c 是如何編譯的?net的程式是由多種語言編譯的,如c vb c j 等,但是最後都會由各自的編譯器編譯為一致的中間語言 il 最後由 clr提供執行環境 將中間語言編譯為 機器碼 供cpu執行。為了儘量減少中間 編譯為機器 的效能損失,中間語言採用 即使編譯 也被稱為 jit編譯 這種編譯方式只編...

怎樣把C 程式部署到PDA上

通過安裝方式在pocket pc上面安裝程式,通常只能安裝到裝置有限的儲存空間或者儲存卡上的指定位置,感覺不太方便,而且安裝程式會在系統目錄及登錄檔中留下很多安裝記錄,也會占用裝置的儲存空間。使用軟體的綠色版本就可以解決這些問題,但軟體廠商通常不會直接提供軟體的綠色版本給使用者,這就需要我們自己動手...

請問?外包到騰訊工作是怎樣一種體驗?

最新發現,在按當地最低標準繳納社保的前提下,公司依然沒有根據當地規定的繳納比例給員工繳納社保,醫療保險公司繳納比例僅為3 養老保險僅繳納6.5 ps.我自己繳納的部分比公司交的還高 工傷保險僅繳納0.035 也就是幾毛錢。失業保險繳納0.28 生育保險是唯一符合繳納比例的 9.9元 留下感動的眼淚,...