Designing a Programming Language: I

Table of Contents

Table of Contents

1 假设

随着编程语言越来越多,世面上出现了各种不同的范式。即便如此,总体来说编程语言分为两大阵营:静态语言和动态语言。为了避免繁杂的历史问题和任何不必要的进一步分析,本文将会做一系列假设来简化一些事情。其中一个假设就是静态语言总是会被编译成机器码,动态语言总是在解释器中运行,虽然这不总是正确的。

如果验证一门语言是静态的还是动态的呢?在静态语言中,变量和过程有严格的类型定义。尝试访问一个在作用域中不存在的变量将会导致编译时语法错误。在解析语言源代码时,所有变量和函数的位置是由词法位置决定的。即给出相关的作用域范围,就能根据变量定义的顺序找到它。

例如,在 Visual Basic 中定义一个变量:

一个简单的示例如下:

Dim num1, num2 As Integer
Dim text As String

这是静态语言的变量定义原型。当变量首次声明的时候,必须指定它的类型。与之不同的是,动态语言则不需要,下面是一段ECMA脚本:

var num1, num2;
var text;

在这个示例中,没有为这些变量指定任何类型。 你可以赋予变量 num1 任何类型的值。不仅如此,变量声明过程也是完全是没有必要的,动态语言的类型信息存储在值对象中。

除Javascript之外,还有很多流行的动态语言,如:Python, Ruby, Lua, Scheme, Lisp等。除了语法风格和表达程度不一样,其他方面都非常类似,如一致的类型系统。所以动态类型语言还常常被理解成鸭子类型或鸭子语言。

我们在从头开始设计鸭子语言的时候,会遵循这些共同特性。不过我们要时刻告诫自己,从零开始构建一门语言仅仅是一个锻炼,在探索过程中我们将不考虑实用性和可行性,当完成这一过程之后再来考虑其他有用的想法。

在开始之前,我要友好地提醒一下各位读者:接下来的章节可能会包含一些非常复杂的知识,即使我已经尽我所能使用朴素和简单的语言来陈述他们。我建议大家在开始此次『语言设计之旅』之前做一些编程语言设计的调研,之后再继续阅读本文。

2 语法

现在网上应该很容易就能找到一份关于词法表达式的新手指南、Wiki或者某语言语法向导的完整文档,不过先暂时放下这些让我们继续吧。有时从语法层面来看,设计一门语言好比在参考手册上画线做笔录,但这本手册并不是已经写好存在的,或许还会随时间推移发生变化。我这样解释的目的不是建议你设计的编程语言要被精雕细琢,并且实现多么牛逼的概念。相反,我们应该在每一步都思考是否能改变、扩展,随着时间能否进化。一个任务解决所有的问题是不现实的,我们应该有更多的方法来改变事情并且让我们的努力不会白费。

考虑到这一点,我们将在原子层面梳理一下 鸭子语言 的基本机制,在此同时也会探索事情的本质。我们会挖掘语言的本质,以透辙地理解语言的精粹,如果能这样便足够了。编程语言也是表达作者观点的系统。为了更好的与同行交流,我们需要有共同点。

我们将使用命令式风格创建一门非常中立的语言,虽然函数式风格可能会最终渗入,但现在我们的目标是为大多数程序员服务。

那从哪里着手呢?从 语句 这个最基础的概念开始吧。大家都知道操作是由语句组成,如:给你两个值,把它们相加,然后把结果赋给一个变量;如果一个表达式返回值为 , 则执行一个语句块;对一个表达式求值,然后传参做过程调用等等。语句块会被描述成语句列表,函数声明也是一种语句,由函数名和一系列参数名构成,函数体中还有一系列语句。/if//else/ 语句也是类似的。这种语句中还包含了其他语句。

为了进一步继续,先来研究一段具体的示例。

if some condition then

    here is a block of statements

end

这是一个最简单的 IF 语句。考虑到当我们的条件求值为 false 时,我们总会想执行另外一些语句,所以我们仍须支持 ELSE 语句。

if some condition then

    here is a block of statements
    to run if the condition is true

else

    here is a block of statements
    to run if the condition is false

end

注意看上面的语法,貌似我们借鉴了 Lua 的结束标记,但这真的只是巧合。我们也可以像 BASIC 一样,把 IF 的结束标记从 END 换成 ENDIF 。我对使用哪个无所谓,没有任何倾向。

我更坚持的是要在语法中使用完整的词汇。我觉得这样更清晰,可读性更强,比起那些使用大量界定符号来构建结构强多了。因此,如果有可能我们将在语法中使用完整的词汇。

上面刚提到过函数定义/声明,来看看函数定义的语法:

function our_new_function(parameter1, parameters2)

    here we have statements that do work
    if this function returns a value then we might have

    return ourResult

    at the end

end

这里我们不会做任何限制。函数可以定义在另一个函数里面,函数只在定义的范围可见。我们不想在刚开始定义的时候就介绍限制,因为他们可能并不是我们的预期。

Date: 2015-07-17 Fri

Author: Gu Weigang

Created: 2018-12-12 三 18:17

Validate