Rust

Rust 开发编译器速成(二):计算编译器

书接上文。本章节会接触一些真正硬核的东西,包括从 Ast 生成 IR,以及制作一个迷你版的 LLVM,并且能够输出 LLVM IR 代码。 目标 我们会实现一个 AOT 编译器,它能够编译类似如下的语句: 11;-mem*3-1;print(mem);print(mem+7); 输出: 1-4 23 可以使用命令行 1calc -e "1;-mem*3-1;print(mem);print(mem+7);" | lli - 来运行。 环境准备 我们会沿用上一章节的代码,所以请确保你已经完成了上一章节的代码。 然后我们虽然不需要依赖 LLVM 就能生成 LLVM IR,但为了能够运行 LLVM IR,我们还是需要安装 LLVM。以 MacOS 为例: 1brew install llvm 确保 lli 命令能够运行即可。 另外我们多了一个依赖: 1id-arena = "2.2.1" 它的作用是提供竞技场分配,这样我们可以避免使用令人头秃的 Rc<RefCell<T>> 以及对应的 Weak。下面用了你就知道了。 生成 IR 前的准备 LLVM 中的 Value 首先需要介绍一下 Value。 Value 是所有 IR 实体的基类。每个 Value 都是一个命名的值,可以是整数、浮点数、指针、函数等等。Value 可以作为操作数用于构建表达式或指令,并用于定义全局变量、局部变量和函数的参数和返回值。 Value 有许多子类,如 Instruction、Argument、Constant 等等,它们各自有不同的功能。但是,不同的 Value 实例都有一些共同的特点,例如它们都有一个唯一的名称(以及命名前缀),可以拥有一个类型,还可以被分配给任何指令作为操作数。 Read more...

Rust 开发编译器速成(一):计算解释器

在本系列的第一篇文章中,我们将学习如何使用 Rust 编写一个简单的计算解释器。本文的目标是让你理解如何使用 Pest 的 PEG 文法解析器生成器处理字符串。这个过程主要涉及到编译的前端,但基本只是调包,不需要太多的编译原理知识。 目标 我们会实现一个解释器,它能够解释如下的语句: 11 + 2;print(mem); 输出: 3 环境准备 首先,我们需要创建一个新的 Rust 项目。打开终端,输入以下命令: 1$ cargo new calc-comp 2 Created binary (application) `calc-comp` package 3$ code calc-comp 这样就能创建一个名为 calc-comp 的新项目,并用 Visual Studio Code 打开。 同时,编辑 Cargo.toml 安装如下依赖: 1[dependencies] 2lazy_static = "1.4.0" 3pest = "2.5.5" 4pest_derive = "2.5.5" lazy_static 用于定义静态模块全局变量。 pest 是一个 PEG 文法解析器生成器。 pest_derive 是 pest 的派生宏。 设计语法规则 在 src 目录下创建一个名为 calc.pest 的文件,该文件定义了语法规则。我们将使用一个名为 pest 的 Rust 库来定义语法规则。Pest 可以帮助我们将语法规则表达为一个简单易读的代码。 Read more...

SHA256 哈希算法原理和 Rust 实现

介绍 作为日常生活中每个网络用户都会使用的算法,SHA256 的原理可能却鲜有人知。 SHA256 的输入是任意长度的字节串,输出是一个 256 bit 的字节串。例如, 输入:字符串 abc(相当于字节数组 [0x6c, 0x65, 0x73, 0x73, 0x2d, 0x62, 0x75, 0x67, 0x2e, 0x63, 0x6f, 0x6d]) 输出: 1[0x20, 0x1a, 0xb7, 0x03, 0x64, 0x78, 0xee, 0x8a, 0xba, 0x2e, 0xb3, 0xc7, 0xc0, 0xc6, 0x5b, 0x8b, 0x17, 0x49, 0x58, 0x52, 0xf4, 0xeb, 0xe1, 0x5b, 0x79, 0xe5, 0x34, 0x39, 0x6f, 0x29, 0x0c, 0x5b] 示例 我们以 less-bug.com 为例,来演示 SHA256 的计算过程。 我们有 8 个特殊的常量,成为初始哈希变量(initial hash variables),它们是 32 位无符号整数,用十六进制表示如下: 1static H: [u32; 8] = [ 2 0x6a09e667, 3 0xbb67ae85, 4 0x3c6ef372, 5 0xa54ff53a, 6 0x510e527f, 7 0x9b05688c, 8 0x1f83d9ab, 9 0x5be0cd19, 10]; 它们之所以是这些值,其实是发明算法的人自己选的。他从自然数中前 8 个质数的平方根的小数部分中,取前 32 位作为初始值。 Read more...
1 of 1