当前位置: 首页 > 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]保证程序只运行一个实例
  • JavaScript-如何实现克隆(clone)函数
  • [笔记] php常见简单功能及函数
  • 「译」Node.js Streams 基础
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • canvas 绘制双线技巧
  • canvas 五子棋游戏
  • GitUp, 你不可错过的秀外慧中的git工具
  • JavaScript DOM 10 - 滚动
  • Java读取Properties文件的六种方法
  • laravel 用artisan创建自己的模板
  • LeetCode18.四数之和 JavaScript
  • leetcode讲解--894. All Possible Full Binary Trees
  • select2 取值 遍历 设置默认值
  • TCP拥塞控制
  • ucore操作系统实验笔记 - 重新理解中断
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 彻底搞懂浏览器Event-loop
  • 仿天猫超市收藏抛物线动画工具库
  • 七牛云假注销小指南
  • 强力优化Rancher k8s中国区的使用体验
  • 区块链分支循环
  • 一个完整Java Web项目背后的密码
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​ArcGIS Pro 如何批量删除字段
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (2)Java 简介
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (转)setTimeout 和 setInterval 的区别
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .net core Swagger 过滤部分Api
  • .NET MVC第五章、模型绑定获取表单数据
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net 高效开发之不可错过的实用工具
  • .NET/C# 的字符串暂存池
  • .net经典笔试题
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @RequestMapping 的作用是什么?