#transpiler #scripting #script #piston #dyon

nightly dyon_to_rust

Dyon到Rust转换器

1个不稳定版本

使用旧的Rust 2015

0.1.0 2017年9月8日

#44#transpiler

MIT/Apache

93KB
2.5K SLoC

dyon_to_rust

Dyon到Rust转换器

更多信息,请查看文档

许可

许可协议为以下之一

贡献

除非您明确说明,否则您有意提交的任何贡献,均应按上述方式双授权,不附加任何额外条款或条件。


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)进行翻译,因此人们也更容易进行贡献。

设计

这个库有两个作用

  1. 作为转译器
  2. 转译代码的运行时环境

需要一个运行时,因为

  • 由于Dyon中的一些功能差异很大,转译后的代码需要辅助方法来查找正确的函数。
  • 一些功能需要与Dyon库进行交互。

在转译器上工作

“source”文件夹包含同一名称的“ .dyon”和“ .rs”文件对。以“ .dyon”结尾的文件包含原始的Dyon源代码,而以“ .rs”结尾的文件包含翻译成Rust的代码。

当在终端窗口中输入 cargo test 时会检查源文件。如果存在任何字符不匹配,将会报告错误。因此,当对转译器进行修改时,必须遍历所有失败的案例,并检查代码是否正确。

这种工作流程非常严格,但有助于增强信心,即某些更改不会过多地影响现有代码的翻译。

“source”文件夹中有两个特殊的文件

  1. “test.dyon” - 用于编写一些测试代码。
  2. “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