建立这个仓库的想法/初衷,是为了给下面这些编程爱好者提供一个学习语言的场所:
- 想学语言设计的初学者
- 有一定经验的编程经验者
开始有想法写这个的时候,准备写个20篇就差不多了,结果越写越多,不知不觉篇数翻倍了。
说实话,来来回回写了差不多半年时间,花费了大量的业余时间。目的很单纯,就是希望通过 自己的微薄之力,能够给那些希望进步,希望学习语言设计的程序猿提供一些关于语言设计的资料。
通过这一系列文章的学习,读者能够了解到语言设计并不是一个令人晦涩难懂的东西。 如果通过本系列的学习,读者能够设计自己的语言,本人会感到非常欣慰。
当时写这一系列文章的时候,我就给自己定了一个规则,我不会去讲一些深奥的逻辑, 而是希望用最浅显的语言来阐述一些内容。
本系列文章采用go
语言进行讲解,因此读者在阅读之前,最好能够掌握一些go
语言的基础。
但是如果你没有go
语言的基础,看懂讲解的内容应该也不会很困难。
市面上有很多语言设计方面的书籍,同时从网上也能够找到很多语言设计方面的资料。 我个人比较喜欢的是:
- Crafting Interpreters(https://craftinginterpreters.com/)
- Let's Build A Simple Interpreter(https://ruslanspivak.com/lsbasi-part1/)
但是由于它们都是英文的,所以有些读者读起来可能会感到比较吃力。
每篇文章对应的代码目录下都有一个run.sh
文件,只需要运行这个文件即可。
先声明一下,本系列教程设计的语言,使用的是基于【树遍历解释器(Tree walking interpreter)】的,且本系列不涉及虚拟机(Virtual Machine)及字节码等相关知识。 文章中的很多内容是基于Thorsten Ball的书籍《Writing an interpreter in go》。
我们将从实现一个简单的计算器开始,一步一步实现一个功能丰富的脚本语言。
每一篇文章的代码都对应一个目录(编号从1开始),讲解文章放在doc目录下。所有的文章(markdown格式)都是使用typora
编写的。
使用typora
的好处是,它可以将其生成pdf或者html文档。当然如果读者需要,我可以将生成的pdf/html文档发给读者。
里面的有些章节可能比较难懂(例如和go语言交互那一篇),读者完全可以略过不看,直接读取下一篇文章。
对于每一篇所新增加的内容,读者可以使用比较工具,来查看新增的代码逻辑。
下面是目录(中文文档见doc目录):
- 简单计算器
- 识别标识符(identifier)
- true, false和nil支持
- Let语句支持
- Scope(作用域)
- 追加对
let
语句和标识符的解释(Evaluating) - 运行期错误处理(Run-Time error handling)
return
语句支持块语句
支持- 字符串表达式支持
- 函数支持
内置(Built-in)函数
支持- if-else判断支持
- 取反(!)支持
- 数组(Array)支持
- 哈希(Hash)支持
方法调用(Method Call)
支持后缀表达式(++、--)
支持赋值表达式(=)
支持- 元祖(Tuple)支持
命名函数(Named function)
支持与浏览器交互
支持- for循环支持
- while和do循环支持
- 多重赋值(multiple assignment) & 多重返回值(multiple return)
printf函数
支持逻辑与(&&)、逻辑或(||)
支持import
支持- 重写main函数
正则表达式(regular expression)
支持- 与
go
语言交互 - Panic, panic, panic...
file
内置对象支持os
内置对象支持struct
支持switch-case
支持try-catch-finally
支持匿名函数
支持链式比较操作符
支持in操作符
支持范围操作符(..)
支持变参函数(Variadic Functions)
支持复合赋值运算符
(+=, -=, ...)支持- 真正意义上的多重赋值
- 尾递归调用优化(Tail Recursive Call Optimization)
字符串变量内插
支持函数装饰器(Decorator)
支持命令执行(Command Execution)
支持增强哈希(Enhanced Hash)
支持管道操作符(|>)
支持有序哈希(Ordered Hash)
支持单一执行文件(single standalone exe)
支持标准库(standard library)
支持