手写编程语言-如何为 GScript 编写标准库( 二 )

其中的实现源码基本上是借鉴了 Go 的标准库,先来看看 StringBuilder 的源码:
class StringBuilder{byte[] buf = [0]{};// append contents to buf, it returns the length of sint writeString(string s){byte[] temp = toByteArray(s);append(buf, temp);return len(temp);}// append b to buf, it returns the length of b.int WriteBytes(byte[] b){append(buf, b);return len(b);}// copies the buffer to a new.grow(int n){if (n > 0) {// when there is not enough space left.if (cap(buf) - len(buf) < n) {byte[] newBuf = [len(buf), 2*cap(buf)+n]{};copy(newBuf, buf);buf = newBuf;}}}string String(){return toString(buf);}}主要就是借助了原始的数组类型以及 toByteArray/toString 字节数组和字符串的转换函数实现的 。
class Strings{// concatenates the elements of its first argument to create a single string. The separator// string sep is placed between elements in the resulting string.string join(string[] elems, string sep){if (len(elems) == 0) {return "";}if (len(elems) == 1) {return elems[0];}byte[] bs = toByteArray(sep);int n = len(bs) * (len(elems) -1);for (int i=0; i < len(elems); i++) {string s = elems[i];byte[] bs = toByteArray(s);n = n + len(bs);}StringBuilder sb = StringBuilder();sb.grow(n);string first = elems[0];sb.writeString(first);string[] remain = elems[1:len(elems)];for(int i=0; i < len(remain); i++){sb.writeString(sep);string r = remain[i];sb.writeString(r);}return sb.String();}// tests whether the string s begins with prefix.bool hasPrefix(string s, string prefix){byte[] bs = toByteArray(s);byte[] bp = toByteArray(prefix);return len(bs) >= len(bp) && toString(bs[0:len(bp)]) == prefix;}}Strings 工具类也是类似的,都是一些内置函数的组合运用;
在写标准库的过程中还会有额外收获,可以再次阅读一遍 Go 标准库的实现流程,换了一种语法实现出来,会加深对 Go 标准库的理解 。
所以欢迎感兴趣的朋友向 GScript 贡献标准库,由于我个人精力有限,实现过程中可能会发现缺少某些内置函数或数据结构,这也没关系,反馈 issue 后我会尽快处理 。

由于目前 GScript 还不支持包管理,所以新增的函数可以创建 Class 来实现,后续支持包或者是 namespace 之后直接将该 Class 迁移过去即可 。
本文相关资源链接
  • GScript 源码:https://github.com/crossoverJie/gscript
  • Playground 源码:https://github.com/crossoverJie/gscript-homepage
  • GScript Docker地址:https://hub.docker.com/r/crossoverjie/gscript

经验总结扩展阅读