1个不稳定版本
使用旧的Rust 2015
0.1.0 | 2017年9月8日 |
---|
#44 在 #transpiler
93KB
2.5K SLoC
dyon_to_rust
Dyon到Rust转换器
更多信息,请查看文档。
许可
许可协议为以下之一
- Apache许可证2.0版本 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT),由您选择。
贡献
除非您明确说明,否则您有意提交的任何贡献,均应按上述方式双授权,不附加任何额外条款或条件。
lib.rs
:
Dyon到Rust转换器
有关Dyon的更多信息,请访问http://www.piston.rs/dyon-tutorial/
注意:此转换器处于早期开发阶段,将包含错误和缺失功能!
动机
Dyon没有垃圾收集器,但使用生命周期检查器。与Rust类似,这种设计选择有可能提高运行时性能。与Rust不同,Dyon没有借用语义,但使用写时复制。Dyon还有一个可变检查器,这使得将其转换为Rust变得更容易。
Dyon是为脚本高效性设计的,其语法和对象模型类似于JavaScript、go
协程(如Go)和可选类型检查,以及使用?
语法(如Rust)的错误处理。
此外,Dyon还具有许多功能,例如用于逻辑(数学循环)、问题解决(使用秘密跟踪证明组合)、快速生成文本和高效内存使用(链接结构)、4D向量、HTML十六进制颜色、闭包和当前对象(优于全局变量)。
将Dyon代码转换为Rust有很大的动力,因为在项目开发过程中,大量代码可能在Dyon中原型化。在后期测试代码时,性能开始变得更加重要。与其为了性能而在Rust中重写,转换器可以更容易地自动化此过程中的某些部分。
目标
假设Dyon-to-Rust转换器永远不会完美。因此,重点将放在Dyon的有用子集上。
- 短期内,开发者将专注于使片段的转换工作
- 中期内,开发者将专注于片段代码的高性能
- 长期内,开发者将尝试支持尽可能多的语言功能,并将转换器运行时与Dyon标准库集成
- 在非常长的时期内,您可能能够将加载脚本创建的整个模块进行转译,并期望它能够无问题地运行。
例如,转译器可能会对您的代码中的类型做出假设,从而生成高效的代码,但可能无法通过Rust编译器。一般来说,如果转译器“不能证明它是错误的,那么它就会这么做”。换句话说,它会持乐观态度,希望最终结果良好。这并不像听起来那么危险,因为Rust编译器非常严格。这些假设并不是为了允许不安全的代码,而只是转译器在Rust类型中的选择。
基于这个假设,转译器将在早期阶段变得有用,并利用Dyon和Rust之间的相似性,将一些类型检查的工作卸载给Rust编译器。由于代码主要是直接从Dyon抽象语法树(AST)进行翻译,因此人们也更容易进行贡献。
设计
这个库有两个作用
- 作为转译器
- 转译代码的运行时环境
需要一个运行时,因为
- 由于Dyon中的一些功能差异很大,转译后的代码需要辅助方法来查找正确的函数。
- 一些功能需要与Dyon库进行交互。
在转译器上工作
“source”文件夹包含同一名称的“ .dyon”和“ .rs”文件对。以“ .dyon”结尾的文件包含原始的Dyon源代码,而以“ .rs”结尾的文件包含翻译成Rust的代码。
当在终端窗口中输入 cargo test
时会检查源文件。如果存在任何字符不匹配,将会报告错误。因此,当对转译器进行修改时,必须遍历所有失败的案例,并检查代码是否正确。
这种工作流程非常严格,但有助于增强信心,即某些更改不会过多地影响现有代码的翻译。
“source”文件夹中有两个特殊的文件
- “test.dyon” - 用于编写一些测试代码。
- “test.rs” - 生成的Rust代码
默认情况下,“tests::test”单元测试会覆盖“test.rs”。您可以在单元测试代码中通过标志更改此行为。
要编译,请在终端窗口中输入 rustc source/test.rs -L target/debug/deps
。
要运行,请输入 ./test
。
幕后
转译器实际上只是一个巨大的函数,它从Dyon模块生成Rust代码(单个文件)。
Dyon模式包含执行Dyon时使用的AST(抽象语法树)。它包含运行Dyon代码所需的所有信息,除了函数。函数存储在模块中,根据它们是否是内建函数(Dyon标准库)、加载的函数(Dyon脚本)或外部函数(Rust)而具有不同的类型。
AST包含在预编译中解决的静态ID,它告诉变量在哪里位于栈上。这意味着转译器只需要跟踪栈的长度。在代码中,这作为stack_len
参数传递。
栈长度跟踪的正确使用是从Dyon的运行时行为中确定的。因此,转译器正在模仿Dyon执行的行为。具有重叠索引的变量使用Rust代码块在不同的作用域中保持。
函数调用使用相对索引,因为Dyon模块可以动态组合。这意味着当模块依赖于其他模块时,需要额外的测试。
功能
目前,由于处于非常早期的阶段,没有支持的语言功能的映射。
目前,生成的Rust代码只使用索引。
例如,您将看不到变量名
let mut _0 = 2.0;
foo(&mut _0);
将来,您可能可以通过一个CodeSettings
结构体来告诉代码生成器使用来自Dyon的变量名。
依赖项
~1.5MB
~33K SLoC