hiibolt/rosy
GitHub: hiibolt/rosy
将 ROSY 科学编程语言转译为 Rust 的编译器工具链,专为束流物理模拟和高性能计算应用提供类型安全和高性能执行能力。
Stars: 8 | Forks: 0
# Rosy
一个现代的 Rust 实现,用于 ROSY 编程语言的转译器(transpiler),专为科学计算和束流物理应用设计。
## 什么是 Rosy?
Rosy 是一个完整的转译器工具链,可将 ROSY 源代码转换为原生可执行的 Rust 程序。ROSY 是一种最初为 COSY INFINITY 束流物理模拟环境开发的科学编程语言,现在作为一个现代转译器重新实现,并做出了几项关键设计决策:
**转译而非解释**:Rosy 不直接执行脚本,而是生成自包含的 Rust 程序,这些程序会编译为原生二进制文件。这提供了:
- **Rust 的内存安全保证**,无运行时开销
- **数值计算性能可与手写 Rust 媲美**
- **零运行时依赖** - 生成的二进制文件完全独立
- **编译时类型检查** 在执行前捕获错误
**基于注册表的类型系统**:所有操作符使用 `TypeRule` 注册表作为唯一事实来源,用于:
- 转译期间的类型兼容性验证
- 运行时分发到优化实现
- 自动生成测试以进行全面验证
**为科学计算而生**:原生支持:
- **微分代数 (DA/CD 类型)** 用于自动微分和泰勒级数
- **MPI 并行化** 内置 `PLOOP` 结构用于分布式计算
- **多维数组** 支持任意维度 `(RE ** 2 ** 3)`
- **复数、向量和矩阵** 作为一等类型
- **强类型安全** 对所有操作进行编译时检查
**测试驱动开发**:每个语言功能都通过自动化输出对比与 COSY INFINITY 的参考实现进行验证,确保行为兼容性。
## 语言特性与语法
```
BEGIN;
{Function to add two numbers}
FUNCTION (RE) ADD_TWO a (RE) b (RE);
ADD_TWO := a + b;
ENDFUNCTION;
{Function to multiply and add}
FUNCTION (RE) COMPUTE x (RE) y (RE);
VARIABLE (RE) temp;
temp := x * y;
COMPUTE := temp + 10;
ENDFUNCTION;
{Procedure demonstrating conditionals}
PROCEDURE CONDITIONAL_DEMO;
VARIABLE (LO) is_true;
VARIABLE (LO) is_false;
is_true := TRUE;
is_false := FALSE;
IF is_true;
WRITE 6 "First condition is TRUE";
ELSEIF is_false;
WRITE 6 "Second condition is TRUE";
ELSE;
WRITE 6 "Neither condition is TRUE";
ENDIF;
IF is_false;
WRITE 6 "This should not print";
ELSE;
WRITE 6 "ELSE clause works!";
ENDIF;
ENDPROCEDURE;
{Procedure demonstrating vectors and arrays}
PROCEDURE VECTOR_DEMO;
VARIABLE (VE) vec;
VARIABLE (RE 2 3) matrix;
{Concatenate values into vector}
vec := 1 & 2 & 3 & 4 & 5;
WRITE 6 "Vector: " ST(vec);
{Access and assign array elements}
matrix[1, 2] := 42;
WRITE 6 "Matrix[1,2] = " ST(matrix[1, 2]);
ENDPROCEDURE;
{Procedure demonstrating loops}
PROCEDURE LOOP_DEMO;
VARIABLE (RE) sum;
sum := 0;
LOOP i 1 5;
sum := sum + i;
WRITE 6 "i = " ST(i) ", sum = " ST(sum);
ENDLOOP;
ENDPROCEDURE;
{Main entry point}
PROCEDURE RUN;
VARIABLE (RE) x;
VARIABLE (RE) y;
VARIABLE (RE) result;
x := 3;
y := 4;
result := ADD_TWO(x, y);
WRITE 6 "Adding " ST(x) " + " ST(y) " = " ST(result);
result := COMPUTE(x, y);
WRITE 6 "Computing " ST(x) " * " ST(y) " + 10 = " ST(result);
CONDITIONAL_DEMO;
VECTOR_DEMO;
LOOP_DEMO;
ENDPROCEDURE;
RUN;
END;
```
### 关键语言特性
- **强静态类型**:`(RE)` 实数, `(ST)` 字符串, `(LO)` 逻辑/布尔值, `(CM)` 复数, `(VE)` 向量, `(DA)` 微分代数, `(CD)` 复数 DA
- **多维数组**:`(RE 2 3 4)` 声明一个 2×3×4 的实数数组
- **拼接操作符**:`&` 从标量构建向量:`1 & 2 & 3` 创建一个向量
- **提取操作符**:`|` 提取向量长度用于迭代
- **类型转换**:`ST()` 转换为字符串,`CM()` 转换为复数,`LO()` 转换为逻辑值
- **过程与函数**:过程无返回值,函数返回类型化值
- **注释**:`{This is a comment}` 使用花括号
- **输出**:`WRITE 6 +` 写入 stdout (单元 6)
## 安装
### 前置条件
- **Rust 工具链** (1.70+): 从 [rustup.rs](https://rustup.rs/) 安装
- **(可选) Nix**: 用于具有 MPI 支持的可复现开发环境
### 从源码构建
```
# 克隆 repository
git clone https://github.com/yourusername/rosy.git
cd rosy
# 构建 transpiler
cargo build --release
# 二进制文件将位于 target/release/rosy
# 可选择安装到您的 PATH
cargo install --path rosy
```
### 使用 Nix (推荐用于 MPI 功能)
```
# 进入包含所有依赖项的 development shell
nix develop
# 正常构建并运行
cargo build --release
```
Nix 环境提供了完整功能所需的 MPI 库和 LLVM。
## 快速开始
### 运行 ROSY 脚本
测试脚本最快的方法是使用 `rosy run`:
```
# 直接运行脚本(编译后的 binary 保留在 .rosy_output/)
rosy run examples/basic.rosy
# 开启优化运行
rosy run examples/basic.rosy --release
# 使用自定义构建目录
rosy run examples/basic.rosy -d /tmp/my_build
# 启用详细日志记录
RUST_LOG=info rosy run examples/basic.rosy
```
### 构建可执行文件
创建独立的二进制文件:
```
# 构建并复制 binary 到当前目录
rosy build examples/basic.rosy
# 创建 ./basic executable
# 指定输出名称
rosy build examples/basic.rosy -o my_program
# 开启优化构建(编译较慢,执行更快)
rosy build examples/basic.rosy --release
# 自定义构建目录
rosy build examples/basic.rosy -d /tmp/build
```
### 工作流程
1. **编写** ROSY 源代码(`.rosy` 扩展名)
2. **转译** 使用 `rosy build script.rosy`
3. **执行** 生成的二进制文件 `./script`
转译器在 `.rosy_output/` 中生成完整的 Rust 项目,使用 cargo 编译,并生成自包含的可执行文件。
## 示例
`examples/` 目录包含各种演示:
- **`basic.rosy`** - 函数、过程、循环和向量操作
- **`vectors_arrays.rosy`** - 多维数组索引和操作
- **`if_statements.rosy`** - 使用 IF/ELSEIF/ELSE 的条件分支
- **`da_test.rosy`** - 用于自动微分的微分代数
- **`ploop.rosy`** - 使用 MPI 分发的并行循环
- **`global_vars.rosy`** - 变量作用域和闭包捕获
运行任意示例:
```
rosy run examples/.rosy
```
## 项目结构
该项目组织为一个 Rust workspace,包含多个相互关联的 crate:
- **`rosy_transpiler/`** - 主转译器二进制文件,解析 ROSY 源码并生成 Rust 代码
- **`rosy_lib/`** - 运行时库,在 Rust 中提供 ROSY 数据类型和操作
- **`rosy_output/`** - 生成的 Rust 可执行文件的模板目标
- **`rosy_ide_tools/`** - 开发工具,包括 VSCode 语法高亮扩展
## 贡献:添加新语言特性
### 添加新表达式
1. **阅读 `manual.md`** - 在附录 A 中找到操作符/函数定义,记下类型表(左类型 + 右类型 → 结果类型)和示例用法
2. 语法定义添加到 `rosy/assets/rosy.pest`(作为基本项的 `term` 或二元操作符的 `infix_op`)
3. 中缀操作符添加到 `rosy/src/ast.rs` 的 Pratt 解析器优先级表
4. 在 `rosy/src/program/expressions/.rs` 中创建包含解析逻辑的新结构体
5. 模块声明添加到 `rosy/src/program/expressions/mod.rs`
6. 枚举变体添加到 `ExprEnum`
7. 实现 Pratt 解析器映射(基本项用 `map_primary`,操作符用 `map_infix`)
8. 实现 Traits:`TranspileWithType`、`TypeOf` 和 `Transpile`
9. 对于操作符:在 `rosy/src/rosy_lib/operators/.rs` 中定义 `TypeRule` 注册表,包含手册中的测试值
10. 构建触发代码生成(`cargo build`)以生成测试文件
11. COSY/ROSY 输出对比验证行为与参考实现匹配
### COSY 与 Rosy 的区别
- 当 `NP == 1` 时,PLOOP 不会恢复为 LOOP 行为
- Rosy 提供 `BREAK` 语句,而 COSY 不提供
### 添加新语句
1. **阅读 `manual.md`** - 在相应部分找到语句/过程定义,包括语法、参数和示例
2. 在 `rosy/assets/rosy.pest` 的 `statement` 产生式下添加语法规则
3. 在 `rosy/src/program/statements/.rs` 中创建新结构体
4. 模块声明添加到 `rosy/src/program/statements/mod.rs`
5. 枚举变体添加到 `StatementEnum`
6. 在 `mod.rs` 的 `Statement::from_rule` 中添加模式匹配 case
7. 实现 Traits:`FromRule` 和 `Transpile`
8. 集成测试添加到 `examples/` 目录
9. COSY/ROSY 输出对比验证端到端行为
### 测试驱动开发
所有语言功能遵循严格的 TDD 工作流:
- 测试值嵌入 `TypeRule` 注册表(用于操作符)
- `cargo build` 自动生成 `.rosy` 和 `.fox` 测试脚本
- 同时转译 ROSY 和 COSY INFINITY 版本
- 合并前输出差异必须完全相同(无近似)
- 注册表具有三个目的:类型检查、运行时分发和测试生成
### 文档与帮助
随着语言趋于稳定,此仓库内容将逐步充实。在此之前,敬请期待 :)
标签:COSY INFINITY, HPC, MPI并行, Rust, 内存安全, 原生二进制, 可视化界面, 多维度数组, 微分代数, 数值计算, 束流物理, 源到源编译, 科学计算, 类型系统, 编程语言, 编译器, 网络流量审计, 自动微分, 转译器, 通知系统, 通知系统, 通知系统, 静态类型, 高性能计算