關於 Cirru Editor 存儲格式

Cirru 是一個使用語法樹編輯器來編寫代碼, 以此繞開語法限制的方案.
目前成熟的編輯器方案有 Stack EditorCumulo Editor,
其中 Cumulo Editor 是我目前開發當中正在持續維護的, 用於開發 ClojureScript.git

Cirru Editor 首先會用 Vector 和 String 的遞歸結構來表示代碼.
更進一步, 基於 Clojure 的 Namespace 設計, 對文件的組織方式進行了拆分,
好比下面是 Cirru Editor 存儲格式的例子, 每一個文件被拆分紅 ns defs proc 三部分:github

{"app.comp.container" {:ns ["ns"
                            "app.comp.container"
                            [":require"
                             ["[]" "respo.comp.space" ":refer" ["[]" "=<"]]]],
                       :defs {"comp-container" ["defcomp"
                                                "comp-container"
                                                ["store"]],
                              "on-click" ["defn" "on-click" ["e" "dispatch!"] ["dispatch!" ":inc" "nil"]]},
                       :procs []},
 "app.main" {:ns ["ns"
                  "app.main"
                  [":require"
                   ["[]" "app.schema" ":as" "schema"]]],
             :defs {"dispatch!" ["defn"
                                 "dispatch!"
                                 ["op" "op-data"]],
                    "*store" ["defonce" "*store" ["atom" "schema/store"]],
                    "ssr?" ["def" "ssr?" ["some?" ["js/document.querySelector" "|meta.respo-ssr"]]],
                    "main!" ["defn"
                             "main!"
                             []
                             ["println" "|App started."]],
                    "mount-target" ["def" "mount-target" [".querySelector" "js/document" "|.app"]]},
             :procs [["set!" [".-onload" "js/window"] "main!"]]},
 "app.updater.core" {:ns ["ns" "app.updater.core"],
                     :defs {"updater" ["defn"
                                       "updater"
                                       ["store" "op" "op-data"]
                                       ["case" "op" [":inc" ["update" "store" ":data" "inc"]] "store"]]},
                     :procs []},
 "app.schema" {:ns ["ns" "app.schema"],
               :defs {"store" ["def" "store" ["{}" [":states" ["{}"]] [":data" "0"]]]},
               :procs []}}

完整的例子, 好比 Stack Editor 使用的存儲格式, 在 namespace 稍微有區別:
https://github.com/mvc-works/...
而 Cumulo Editor 使用的格式存儲了更多的信息(於是沒有作格式化):
https://github.com/mvc-works/...mvc

整體上使用的格式仍是統一的, 依據如下規則:app

  • 文件結構按照 namespace 劃分, 用 Map 存儲
  • 每一個文件當中按照 ns defs proc 拆分, 用 Map 存儲
    • ns 存儲命名空間的定義
    • defs 存儲變量的定義, 用 Map 存儲
    • proc 存儲腳本代碼序列, 大多數爲空的 Vector
  • 代碼對應 S-Expression, 語法強行拆減

這個格式是爲了編輯器操做的便利而設計, 並非最終代碼,
於是也就須要編譯出代碼, 從而能夠被其餘編譯器或解釋器解析.
Cirru 格式的編譯器須要作的事情有:編輯器

  • 對 namespace 進行轉換生成文件
  • 單個文件內對 ns defs proc 進行組合拼接
    • 其中 defs 存在依賴關係, 須要進行簡單依賴分析和排序
  • 解釋 S-Expression 生成目標語言源碼

Cirru 目前對應的是動態類型的腳本語言, 好比 Clojure.
因爲使用了語法樹做爲存儲格式, 必定程度上會給代碼分析帶來方便,
但也因爲動態語言缺乏類型提示, 實際上可供分析的信息有限,
從而難以提供模仿 VS Code 提供的代碼提示功能和重構功能.佈局

這個格式的好處是整個項目容易被放進 Cirru 的網頁編輯器當中.
而後藉助 Cirru Editor 的實現, 提供佈局管理和實時同步.ui

相關文章
相關標籤/搜索