当前位置: 首页 > news >正文

关于 Cirru Editor 存储格式

Cirru 是一个使用语法树编辑器来编写代码, 以此绕开语法限制的方案.
目前成熟的编辑器方案有 Stack Editor 和 Cumulo Editor,
其中 Cumulo Editor 是我目前开发当中正在持续维护的, 用于开发 ClojureScript.

Cirru Editor 首先会用 Vector 和 String 的递归结构来表示代码.
更进一步, 基于 Clojure 的 Namespace 设计, 对文件的组织方式进行了拆分,
比如下面是 Cirru Editor 存储格式的例子, 每个文件被拆分成 ns defs proc 三部分:

{"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/...

总体上使用的格式还是统一的, 依据以下规则:

  • 文件结构按照 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 的实现, 提供布局管理和实时同步.

相关文章:

  • SecureCRT 使用技巧
  • shell脚本进阶。
  • Chapter2:策略模式
  • dubbo之直连提供者
  • dubbo之回声测试
  • C# 类型 type
  • hadoop安装部署
  • 用微软.NET架构企业解决方案 学习笔记(四)业务层
  • 协作方法——黑板模型
  • 14.插入数据、复制数据--SQL
  • 研磨设计模式之 单例模式-2
  • 初入SpringBoot——使用IDEA构建最小SpringBootDemo
  • Spring.NET学习笔记7——依赖对象的注入(基础篇) (转)
  • Forword(请求转发)与Redirect(重定向) 区别
  • [delphi]保证程序只运行一个实例
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • dva中组件的懒加载
  • JS专题之继承
  • overflow: hidden IE7无效
  • react 代码优化(一) ——事件处理
  • 当SetTimeout遇到了字符串
  • 数据仓库的几种建模方法
  • 怎么将电脑中的声音录制成WAV格式
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • $GOPATH/go.mod exists but should not goland
  • %check_box% in rails :coditions={:has_many , :through}
  • (9)STL算法之逆转旋转
  • (C)一些题4
  • (TOJ2804)Even? Odd?
  • (zt)最盛行的警世狂言(爆笑)
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (过滤器)Filter和(监听器)listener
  • (三)elasticsearch 源码之启动流程分析
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)德国人的记事本
  • ***详解账号泄露:全球约1亿用户已泄露
  • *1 计算机基础和操作系统基础及几大协议
  • .gitignore
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • .NET中winform传递参数至Url并获得返回值或文件
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [23] GaussianAvatars: Photorealistic Head Avatars with Rigged 3D Gaussians
  • [AIGC] SQL中的数据添加和操作:数据类型介绍
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [BUUCTF]-PWN:[极客大挑战 2019]Not Bad解析
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [HDOJ4911]Inversion
  • [HNOI2006]鬼谷子的钱袋
  • [JS入门到进阶] 哎,被vite小坑了一波,大家记得配置build.cssTarget为‘chrome61‘
  • [nlp] tokenizer
  • [raspberry pi3] 串口线使用
  • [Spring] IOC控制反转/DI依赖注入详细讲解
  • [svc]logstash和filebeat之间ssl加密
  • [单片机框架][bsp层][N32G4FR][bsp_pwm] pwm配置和使用