Cirru 是我在探索的玩具, 希望让编程语言的编写更有趣
最初我准备的是做结构化的编辑器, 但是效果不够理想
www.tudou.com/programs/view/lehLxTKfc5w/?phd=1
然后备用方案是模仿 Lisp 写法, 但是基于缩进, 方便阅读跟书写, 的一套语法
http://repo.cirru.org/parser/
关于细节可以看相关社交网站上贴出来的想法, 比较凌乱的:
https://github.com/Cirru/
https://twitter.com/CirruLang
http://weibo.com/jiyinyiyong/profile?&key_word=cirru
目前我探索了一下, 写了若干种语言的 Parser 的实现
https://github.com/Cirru/?utf8=%E2%9C%93&query=parser
我是从 CoffeeScript 版本手工转到这么几个语言的...
另一个是执行代码方面, 之前尝试写解释器, 不理想, 我太弱了
所以干脆, 不做后端, 尽量把语法树编译到现成的语言的 AST 之类的
比如编译到 ES6 的 AST, 然后在浏览器端以 JavaScript 运行
http://v2ex.com/t/181804
现在做了支持, Grunt, Gulp(要等 4.x), Webpack 都能用 CirruScript 运行
https://github.com/tkellen/js-interpret/blob/master/index.js#L3
之前想做编译 LLVM IR.. 我太弱了.. 后来想到用 Julia, Julia 后端是 LLVM
于是就引出来 Sepal 命名的项目, 就是把 Cirru 语法转到各种 AST
除了 ES6 能用, 我尝试了 Julia, Ruby, Racket, 原理上确定能走通了:
https://github.com/Cirru/?utf8=%E2%9C%93&query=sepal
当然, 这个距离真的用 Cirru 写代码还很远很远, 我写写 ES6 已经够玩了
发这个帖子主要想看下有没有同学对 Cirru 这个想法感兴趣
而且, 杂七杂八的想法, 已经远远超乎我的技能范围了...
比如说, 基于已有的 Cirru Parser 开发玩具, 或者做真的使用的项目出来
比如说, 编写更多语言的 Parser 实现, 主要用来装逼...
比如说, 找个支持 AST 元编程的语言, 比如 Python 跟 Nim, 尝实现 Sepal
比如说, 把 Cirru 编译到 Lua bytecode, LLVM IR 或者类似, 太牛逼了有没有 >_<
比如说, Cirru 代码就是语法树, 那么 Diff 的时候对树进行 Diff, 好像挺有意思
比如说, 语法树可以用来演示解释器, 做成交互动画版的 Demo 会很好玩
比如说, 万一真的做出来个很好用的结构化编辑器了怎么办
自定义编程语言我觉得是很装逼的事情, 相信会有很多同学对设计编程语言感兴趣
Cirru 用了很奇葩的方案, 而不是正规 lex, parse, optimize, generate 流程...
但是作为玩具, 我觉得比起写 BNF 或者 PEG 搞复杂的语法要好多了
而且现在 CirruScript 的实现项目 Sirpus 已经勉强自举, 至少能玩了...
https://github.com/Cirru/scirpus/blob/master/src/operations.cirru
希望有人喜欢玩我造的这个玩具 : )
有好点子可以在微博 @题叶 或者微信 jiyinyiyong 交流下
1
h4x3rotab 2015-05-02 02:47:01 +08:00
以前接触过llvm ir,感觉最大的问题其实是动态语言的类型系统和llvm的强类型系统差的太多,解决了这个问题其他应该都好说
|
2
jiyinyiyong OP @h4x3rotab 看过大神对 Python 放大招类型推断, 办法还是有的. 就是挺难.
http://www.stephendiehl.com/llvm/ http://dev.stephendiehl.com/numpile/ |
3
Jex 2015-05-02 10:56:17 +08:00 1
说实话我在这方面的想法也很多,但一直耐着没有直接写这类东西。设计一个语言,光是语法上有点小变化我感觉没有多大实用价值,尤其是已经有了S-Expression,最多只能设计一个基于Indentation Layout的无括号版的S-Expression。一言概之,除了语法,没有其它特点。
如果没有强大的类型系统或者类型推导,把你的语言编译到LLVM上性能估计跟直接转换成JS差不多。 Sementic diff 我上次看到这个产品: https://www.semanticmerge.com/ 至于Parser,我还是觉得直接抄BNF简单,我这个拖延了快停掉的项目,就是自己重写了个支持左递归的ParserCombinator,这样直接把ECMAScript Spec中的BNF文法直接抄写到代码里面,然后Duang就变成AST了: https://github.com/JexCheng/jacobin/blob/master/test/ParsecTest.js#L42 >> 语法树可以用来演示解释器, 做成交互动画版的 Demo 会很好玩 这个想法正是我去年打算实现的 Jester: https://github.com/JexCheng/jester 但觉得Esprima的AST太麻烦,后来就转而开发Jacobin,Jacobin里用 (伪)Parsec直接Duang就能得到S-Expression。。。呃,后来觉得JS Debug起来还是太麻烦,就暂时放弃用JS实现这些项目了。 |
4
jiyinyiyong OP @Jex 嗯, 语法上就是缩进的 Lisp, 能改进的地方不多,
我的思路就是直接写 AST, 简化造轮子的第一步, 在这个基础上有些事情就简单了, 因为写好的代码就是一棵嵌套的树, 也就是后续的玩具有个简单而且统一的基础. LLVM 真心难, 解释器是不需要重新设计类型系统, LLVM 这边绕不过去了 现在就是 Julia 类型推断厉害, Julia 的 AST 生成的 LLVM IR 能直接用就好了 不过那样能不能生成整个可以用的语言还是另一回事.. 不考虑了 ES5 的语法学习成本还是比 Scheme 要高的~ 而且未来做图形化肯定要推翻 但是 Cirru 的话图形化以后直接就是语法树的样子, 可以无缝过渡 我刚弄明白 Haskell 的 Monad 怎么回事, Parsec 还没弄明白怎么回事.. 语法解析方面我还差很偷懒的... 楼上好厉害.. 对了还有关于 Diff 那个, 其实还可以用在协同编程上边 假设 N 个人同时连接一个服务器上的文件在编辑, 每个人一个操作就是一个 Patch 因为他们是在不同的树的分支上操作, 所以相互之间就不会影响, 比文本要简单一些 而且树的话可以在只打开一个分支编辑, 而不用打开整棵树或者整个文件 这个东西我手头技术成熟之后可以搞一个 Demo 试一下 |
5
Jex 2015-05-18 21:25:33 +08:00 1
@jiyinyiyong 你的Editor的视频我看半天没看明白到底咋样 -_-! 声音也听不清
基于Tree diff 的协同编程工具,我印象中好像很久以前看到Eclipse有过一个插件。 对了,我好奇你的语言中对于 `connect({name:'Bob',age:28},{name:'Alice',age:18})` 是写成类似这样的缩进呢? ``` connect $ object object name: 'Bob' name:'Alice' age: 28 age: 18 ``` 还是这样的呢? ``` connect $ object name: 'Bob' age: 28 object name:'Alice' age: 18 ``` 好吧,应该毫无疑问只能实现成后者 |
6
Jex 2015-05-18 21:29:55 +08:00 1
@jiyinyiyong 评论里缩进全没了,你自己猜缩进本来应该什么样子吧。嗯,这又是基于缩进的语言不方便的一点。
|
7
jiyinyiyong OP @Jex 好吧我的嗓音放到视频上更难听懂了, 小房间里录的, 效果也不好.
视频的话只是演示一下 Cirru 代码是能错图形化工具编辑生成的. 这个算不上特别好的功能, 只能说有这个特性的话未来图形化很容易. 缩进确实不方便, 但是 Cirru 不是为了这类场景设计的, 所以不管了. 看这边 https://gist.github.com/jiyinyiyong/f34e2981aff6987d2c03 |
8
jiyinyiyong OP |