用 Cirru 语法运行 WebAssembly 的 Hello World

2015-10-18 18:59:21 +08:00
 jiyinyiyong
> 先说明一下, WebAssembly 目前没有定稿, 现在做的只是玩具

不过实际上推进蛮快的, 最近追的新闻, OCaml C# JavaScript 的实现都看到了
特别是在 Twitter 上看 @indutny 狂刷新闻, 只知道这人是 Node core team member...
https://twitter.com/indutny
WebAssembly 最近相关的消息可以看新闻:
https://auth0.com/blog/2015/10/14/7-things-you-should-know-about-web-assembly/

然后 @indutny 搞的几个库包括:
https://github.com/indutny/wasm-cfg
https://github.com/indutny/wasm-jit/
https://github.com/indutny/wasm-ast/
https://github.com/indutny/wasm-cli

基本上是模仿 JavaScript 定义了一套 AST, 设计了 C 风格的语法
然后自己解析, 再以 JIT 的形式生成代码并且执行
底层用了 jit.js 和 nmap.js , 主要是 C++ 我看不懂这块不管了

总之就是这样的语法, 安装 `wasm-cli` 以后可以命令行执行

```wast
void main() {
i32.store(addr.from_64(i64.const(0)), i32.const(0x6c6c6568));
i32.store(addr.from_64(i64.const(4)), i32.const(0x6177206f));
i32.store(addr.from_64(i64.const(8)), i32.const(0x000a6d73));

std::print(addr.from_64(i64.const(0)),
addr.from_64(i64.const(11)));
}

export main
```

讲了一大堆, 然后我的做的是什么?

反正 Cirru 语法已经能写 JavaScript AST 很久了, 于是开始搞 WebAssembly 的 AST
不过注意下这个 AST 不是官方的, 以后很可能有变数
总之我写了 npm 模块, 可以从 Cirru 语法生成想要的 AST 了
https://github.com/Cirru/cirru-wasm-ast
https://github.com/Cirru/cirru-wasm-cli

所以, 现在可以全局安装 `cirru-wasm-cli` 这个模块, 然后创建一个 `hello-world.cirru` 文件:

```cirru
\ (void main) ()
i32.store (addr.from_64 (i64.const 0)) (i32.const 0x6c6c6568)
i32.store (addr.from_64 (i64.const 4)) (i32.const 0x6177206f)
i32.store (addr.from_64 (i64.const 8)) (i32.const 0x000a6d73)

std::print
addr.from_64 (i64.const 0)
addr.from_64 (i64.const 11)

export main
```

然后执行 `cirru-wasm-cli hello-world.cirru` 就可以看到 `hello wasm` 打印了
因为是底层代码, 所以 `hello` 在源码里看不出来... 暴露了我看不懂十六进制 - -!

他的 AST 我从他的 tests 里扒了一遍, 虽然以后可能变, 如果有人感兴趣看的话:
https://github.com/Cirru/cirru-wasm-ast/blob/master/src/ast.cirru
https://github.com/indutny/wasm-ast/blob/master/test/parser-test.js

到这里位置上边的部分就结束了

----

另外还有个玩具... 前面说了, WebAssembly 没有官方规定的标准的文本语法
所有有的地方是这样写的, 用 S 表达式..
https://github.com/WebAssembly/spec/blob/master/ml-proto/test/imports.wast
举个例子就像是这样...

```scheme
(module
(export "test" 0)
(func (result i32)
(i32.add (i32.const 1) (i32.const 2))))
```

Cirru 对付圆括号那是家常便饭了.. 于是早一点的时候就搞了一个工具
https://github.com/Cirru/sexpr-wasm-json
大致可以用来把下边的语法解析一下, 然后把上边的括号引号全生成出来

```cirru
module
export :test 0
func (result i32)
i32.add (i32.const 1) (i32.const 2)
```

总之社区已有两种的语法, 一种 Lisp 风格一种 C 风格, 我这边搞出一个缩进风格
对 WebAssembly 还有缩进语法有兴趣的同学来一起看看以后怎么搞~
3258 次点击
所在节点    分享创造
3 条回复
ChiangDi
2015-10-18 20:06:39 +08:00
为何对缩进有这样的执念,我很多时候宁愿敲敲括号或者分号。。。
jiyinyiyong
2015-10-18 20:39:31 +08:00
@ChiangDi 我不是处女座我觉得世界上比我执念的人有的是只是我执在缩进语法上边了
编程搞不好是我一辈子的事情, 真的让我多敲个几十万次括号分号真心难受
而且这种语法上的小坑搞不好还会影响到编程时候的思路..
再说学好编译原理装装逼不是挺好玩的一件事情么
bramblex
2015-10-20 13:19:05 +08:00
@ChiangDi 如果你能搞清楚一堆右花括号的话…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/228991

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX