Joke:一切从 console.log 开始

1,418 阅读4分钟

halo,大家好,我是 132,今天我要宣布一件大事,那就是,我终于搞好 joke 了

前天我写了一篇很直白的编译原理的文章

按照我自己的冥思,想出来一种能在千行代码以内实现一门语言(引擎)的思路,因为评论里有人感兴趣,所以我也趁热打铁,马上捋了一遍出来

github地址在这里:github.com/yisar/joke

然后接下来,按步骤描述一下:

用例

console.log(123)

是的你没有看错,就这一句最常见的代码,但其实它是 console 方法的成员 log 方法,然后执行 log 方法传进去一个 123 参数,然后把 123 给打印出来

lexer

lexer 做的事情最简单,就是拆字符串,得到 tokens,其实就是把字符串全部拆开:

["console",".","log","(",123,")"]

parser

parser 做的事情其实也不难,主要是遍历 tokens,然后得到一颗 AST 的树,长这样:

[NodeList([Call(Member(Identifier("console"), "log"), [Number(123.0)])])]

这是 rust 中,用来描述 tree 的方式,使用结构体,虽然不如 js 使用对象直白,但其实更容易操作

剩下的就是遍历这棵树,值得一提的是,rust 遍历很有意思,通常有两种方式,一种是类似 js 的 function 方式,一个 fn 搞定;另一种是和 class 类似,使用 impl struct,这种方式一般是实现 next() 这种迭代器方法……

我选择后者,毕竟未来这层遍历将会是一个很大的遍历,impl struct 的方式更容易拓展

codegen

codegen 是用来生成字节码的,它做的事情是将 AST 转换为 bytecodes,关于为什么需要转字节码,这部分目前我也没 get 到精髓

但是至少对于 joke 来说,目前它的作用就是拆 AST,拆成字节码和状态,字节码让 vm 去跑,状态用来实现执行堆栈和 gc

字节码长这样,十六进制的:

[1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 1, 0, 0, 0, 3, 5, 1, 0]

vm

vm 要做的事情将代码跑起来,比如按照用例,它做的事情就比较简单,就是全局维护一个状态栈,上面挂了 console.log 方法

未来还要有作用域,原型链,闭包,event loop……

思考

之前一直写 js,但是其实我对它内部的执行原理不是很懂,但是突然自己写 js 引擎,就不得不去思考这些曾经不关注的东西

  1. gc

说实话,gc 是我最初的灵感来源,为什么我要用 rust 写 js 引擎的初衷

我们都知道 rust 独有的所有权,可以很安全的管理内存,所以我就想,利用这一特性,有没有可能实现【绝对安全】的 gc?

如果能做到,那么就区别于 v8 等其他动不动就内存泄漏的引擎了……

答案是肯定可以的~ deno 提供了一种 isolate 思路,这种思路就是比较安全的,虽然我不知道 deno 是否能做到,毕竟有 v8

  1. 作用域,原型链,闭包,event loop

这些东西是 js 的基本,过去每次面试,被问到这些内容,就很拉分

现在轮到我自己写,这部分内容是重中之重,我需要好好冥思,力求设计出最简单的心智模型

其实很重要的是原型链,搞定这玩意,那么基本上所有 userland 的 API(map、some、bind 这些) 都不需要内置了,都可以基于原型在 js 层进行 polyfill

  1. Deno

很多人肯定很好奇,Deno 隐藏的全局变量放在哪儿的

Deno core 除了 isolate,还有很重要的 binding 和 shareQueue,虽然它是绑 v8 和 rust,但是换到 joke 来说,还是能够给 joke 带来新的灵感

最终完全可以搞一个类似的机制,那么所有的内置 API 都可以外置(Array、Ojbect、Date、Math、Josn等)

总结

通过精巧的设计,joke core 完全可以做到最小化,预期可以在一千行以内

顺便还可以利用 rust 的特性,解决 v8 的内存问题

顺便还可以外置所有 API

说实话,每次我写一个东西,评价都褒贬不一,很多人会说,不能用,没人用,不业务……

但是我写一个东西,真的不是为了让它能用,也不在意性能好坏,标准与否

我更在意的是一种新思路,巧妙的设计……

最后,放一下群号:813783512,欢迎来玩
然后,放一下 github:https://github.com/yisar/joke ,欢迎 star,欢迎 pr~