编程语言的诞生:Slate [第一部分] [第一部分] 介绍 Slate!那么它现在能做什么呢?一门新语言?为什么?它有什么不同?我能用它吗?你是怎么做到的?

2025-06-10

编程语言的诞生:Slate [第一部分]

[第一部分] 简介

石板!

那么它现在能做什么呢?一种新的语言?为什么?它有什么不同?我能用它吗?

你是怎么做到的?

我发明了一种新的编程语言!(((注意:目前它只能将数字文字相加并导出常量,但它可以运行!!))

[第一部分] 简介

石板!

最近,我一直在开发一种全新的编程语言,它叫做 Slate!我会把它写成一个系列,大致从头到尾记录我开发编译器、标准库,甚至一些 Slate 程序的进度。

Slate 是(第一个?)直接从源代码编译为WebAssembly 的编程语言。是的,这就是我这么久以来一直在问 WASM 的原因 :)。它的语法主要受到 JavaScript ES2015+ 的启发,同时也受到了 Java、Kotlin 等语言的影响。

那么它现在能做什么呢?一种新的语言?为什么?它有什么不同?我能用它吗?

目前,这就是它所做的一切。

/**
 * https://github.com/nektro/slate/blob/master/tests/02.grammar/01.operators/001.slate
 */
//
export const expected = 80;
//
export function main(): i32 {
    return 48 + 32;
}
Enter fullscreen mode Exit fullscreen mode

怎么办?

您可以导出整型常量文字,并导出一个用于将整型文字相加的函数。就是这样。但slate.js可以完全解析它,并导出一个执行相同操作的 WASM 模块,尽管目前还只是非常字面化的。

为什么要做?

我真心热爱 JavaScript。这份热爱源于对 Web 平台的广泛热爱,而 JS 正是我们所能拥有的一切。直到现在!WebAssembly 解答了那个老问题:“除了 JavaScript,Web 上还有其他语言吗?”。WASM 则让 JavaScript 可以访问所有语言[1]。因此,一方面出于对 JS 的热爱,另一方面出于创建自己的语言的渴望,为了尝试实现我从未见过的功能,我开始着手通过 WASM 创建一种专门用于 Web 的语言。

[1]:前提是上述语言有合适的工具链

通过这个系列,我将记录大致整个旅程。

有何不同?

Slate 是强类型的。所以这是它与众不同的地方。但我还想添加一些功能,比如运算符重载、对象扩展(比如<Object>.prototype在静态类型语言中,在“上添加”操作符)等等。

我可以用它嗎?

从技术上讲是的!如果你想编译上面的程序并在你自己的支持 WebAssembly 的浏览器中运行它,那么你可以执行以下操作:

import * as slate from "https://rawgit.com/nektro/slate/master/src/slate.js"

const slate_program = `
/**
 *
 */
//
export const expected = 80;
//
export function main(): i32 {
    return 48 + 32;
}
`;

Promise.resolve(slate_program)
.then(x => slate.parse(x))
.then(x => x.instance)
.then(x => x.exports)
.then(x => {
    // `x` == { expected: 80, main: func() { [native code] } }
});
Enter fullscreen mode Exit fullscreen mode

你是怎么做到的?

与任何其他语言一样,制作编译器有许多类似的步骤,并且所有步骤都在 Slate 中进行。

  • 词法分析
  • 解析器
  • 语义分析器
  • 代码生成
  • 链接器

1.词法分析

这一步之所以简单,是因为当我创建 HTML 预处理器并将其添加到我的basalt JavaScript 库时,这部分用到的大部分代码已经写好了。Slate 词法分析器的代码可以在这里找到

我们的词法分析器会获取程序的文本,并为我们做一些非常方便的事情。它必须删除注释,并将代码转换为带有数据的标记列表,以便我们稍后将其传递给解析器。

因此,在正确设置词法分析器后,basalt 将把我们的测试程序转换为类似下面的代码。

[
    Key("export"),
    Key("const"),
    Id("expected"),
    Symbol(=),
    Int(80),
    Symbol(;),
    Key("export"),
    Key("function"),
    Id("main"),
    Symbol("("),
    Symbol(")"),
    Symbol(":"),
    Id("i32"),
    Symbol("{"),
    Key("return"),
    Int(48),
    Symbol("+"),
    Int(32),
    Symbol(";"),
    Symbol("}")
]
Enter fullscreen mode Exit fullscreen mode

2. 解析器

当我编写 HTML 预处理器时,这部分流程也非常复杂,所以解析也是basalt 中的一个模块。Basalt 帮助我们构建了解析器,但我们仍然需要添加所有必要的功能。Slate 的解析器在这里。熟悉计算机科学的朋友,我们正尝试通过伪上下文无关语法创建一种形式语言。ANTLR是该领域的另一个大型项目,旨在创建一个格式更类似于巴科斯范式的词法分析器/解析器。

简而言之,我们必须想出一系列模式,这些模式可以获取我们之前的标记列表并将其压缩为一个表达式,然后我们可以稍后对其进行分析以创建我们的程序。

经过该过程后,我们的测试程序看起来更像这样:

注意:我跳过了代码演示部分,因为解析器的输出非常冗长,下一步我们将对其进行压缩以显示相同的信息,但采用更有用的格式

3.语义分析器

这部分由 Slate 中的“转换器”完成,它从解析器获取非常详细的输出,对其进行验证,然后生成AST。Slate转换器的源代码可以在这里找到

那么现在我们的程序是什么样的?

File(
    Export(
        Const(
            "expected"
            80
        )
    )
    Export(
        Function(
            "main"
            Parameters(
            )
            "i32"
            Block(
                Return(
                    Add(
                        48
                        32
                    )
                )
            )
        )
    )
)
Enter fullscreen mode Exit fullscreen mode

4.代码生成

呼!快完成了!现在我们有了一个不错的 AST,但现在需要将其编译为 WebAssembly,以便能够通过WebAssembly.instantiateStreaming()等方式运行。为了简化操作我决定让我的编译器生成文本格式(而不是二进制格式)的 WASM ,然后使用wabt将文本转换为二进制 WASM。相信我,我喜欢 WebAssembly 及其含义,但即使是尝试弄清楚文本格式也很困难。目前关于这些格式的文档很少,我所依赖的大部分是 WASM 平台规范测试和各种 WASM 测试环境的输出。

从我们的 AST 生成 WAST 的代码实际上是附加在转换器发送出的对象上的,因此该代码在这里。生成上述 WAST 后,我们应该得到以下内容:

(module
    (memory $0 1)
    (global i32 (i32.const 80) )
    (export "expected" (global 0) )
    (func (export "main") (result i32)
        (i32.add (i32.const 48) (i32.const 32) )
    )
)
Enter fullscreen mode Exit fullscreen mode

万岁!🙌

5. 链接器

目前我们实际上已经完成了。导入功能目前尚未实现,而且还没有标准库,所以这个阶段必须稍后再进行。


感谢阅读!如果你喜欢这篇文章,请告诉我你对 Slate 未来的期待,敬请期待!

未来将推出:

  • 设计理念和长期目标
  • 更多运营商
  • 类型推断以添加对浮点数和对象的支持
  • 变量
  • ifwhilefor, ETC
  • 字符串
  • 更多功能
  • 课程
  • 元编程

可节省您滚动时间的链接:

在 GitHub 上关注 Slate!https://github.com/nektro/slate
在 Twitter 上关注我!https://twitter.com/nektro
在 Dev 上关注我!https://dev.to/nektro

鏂囩珷鏉ユ簮锛�https://dev.to/nektro/the-making-of-a-programming-language-slate-part-1-4528
PREV
轻松将 Excel 电子表格解析为 JSON 格式?我为什么需要这个功能?如何使用它?
NEXT
Safari 是新的 Internet Explorer