204 lines
5.2 KiB
Markdown
204 lines
5.2 KiB
Markdown
---
|
||
name: fortran-to-rust
|
||
description: "Fortran 到 Rust 的重构指南和工作流。触发条件:(1) 刚使用过fortran-analyzer skills 获得需要重构的模块(2)用户提到重构 Fortran 到 Rust;(2) 开始新的 Fortran 函数重构;(3) 翻译 Fortran 代码;(4) 处理 COMMON 块转换;(5) 用户问'怎么把 Fortran 函数转成 Rust'。提供完整重构流程、常见陷阱、测试规范。"
|
||
---
|
||
|
||
# Fortran → Rust 重构指南
|
||
|
||
将 TLUSTY/SYNSPEC 的 Fortran 函数重构为 Rust。
|
||
|
||
## 重构流程
|
||
|
||
### Step 1: 选择目标函数
|
||
|
||
使用 fortran-analyzer skills 获取需要重构的模块,不要因为行数多、复杂或者 COMMON 依赖就回避它们。如果已使用过就跳过,直接重构即可。
|
||
|
||
|
||
|
||
### Step 2: 分析 Fortran 源码
|
||
|
||
```bash
|
||
cat tlusty/extracted/TARGET.f
|
||
```
|
||
|
||
检查清单:
|
||
- [ ] INCLUDE 文件(COMMON 块,已经提取到src/state/下)
|
||
- [ ] 函数参数和返回值
|
||
- [ ] 调用的其他函数
|
||
- [ ] 是否有 I/O 操作
|
||
- [ ] DATA 语句(已预提取到 `src/data.rs`)
|
||
|
||
|
||
注意:不要因为代码复杂就回避它,复杂的函数往往是重构的重点。只要按照步骤逐行分析,就能找到合适的 Rust 实现方式。要完整实现 Fortran 的功能,不能删减任何逻辑。
|
||
|
||
### Step 3: 创建 Rust 模块
|
||
|
||
```bash
|
||
touch src/math/TARGET.rs
|
||
```
|
||
|
||
### Step 4: 实现函数
|
||
|
||
**命名映射**:
|
||
| Fortran | Rust |
|
||
|---------|------|
|
||
| `FUNCTION` | `pub fn` |
|
||
| `SUBROUTINE` | `pub fn`(返回值用元组或可变参数)|
|
||
| COMMON 块 | 结构体参数 |
|
||
|
||
### Step 5: 添加到 mod.rs
|
||
|
||
```rust
|
||
// src/math/mod.rs
|
||
mod target;
|
||
pub use target::target;
|
||
```
|
||
|
||
### Step 6: 编写测试
|
||
|
||
```rust
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use approx::assert_relative_eq;
|
||
|
||
#[test]
|
||
fn test_basic() {
|
||
// 基本功能测试
|
||
}
|
||
}
|
||
```
|
||
|
||
### Step 7: 运行测试
|
||
|
||
```bash
|
||
# 单个模块测试(不要全量 cargo test!系统会卡死)
|
||
# 方式1:静默警告,只显示测试结果
|
||
cargo test target -- --quiet 2>&1 | grep -E "^test|^running|^test result"
|
||
|
||
# 方式2:完全静默警告(推荐)
|
||
RUSTFLAGS="-A warnings" cargo test target 2>&1 | tail -10
|
||
|
||
# 方式3:仅查看测试结果
|
||
cargo test target 2>/dev/null
|
||
|
||
```
|
||
|
||
## 常见陷阱
|
||
|
||
| 问题 | Fortran | Rust |
|
||
|------|---------|------|
|
||
| 数组索引 | `arr(i)` 1-indexed | `arr[i-1]` 0-indexed |
|
||
| 负对数 | `-LOG(X)` | `-ln(X)` 不是 `ln(-X)` |
|
||
| 幂运算歧义 | `x**2` | `(x)*(x)` 避免类型歧义 |
|
||
| 循环变量 | 可能变负 | 用 `isize` 不用 `usize` |
|
||
| 矩阵存储 | 列优先 `A(j,i)` | `a[(i-1)*N + (j-1)]` |
|
||
| 精度 | 隐式类型 | 显式 `f64`/`f32` |
|
||
|
||
## 精度要求
|
||
|
||
| 函数类型 | 容差 |
|
||
|---------|------|
|
||
| 简单数学运算 | `1e-10` |
|
||
| 多项式近似 | `1e-7` |
|
||
| f32 数组 | `1e-24` |
|
||
|
||
```rust
|
||
use approx::assert_relative_eq;
|
||
assert_relative_eq!(result, expected, epsilon = 1e-7);
|
||
```
|
||
|
||
## 代码规范
|
||
|
||
### 文件头注释
|
||
|
||
```rust
|
||
//! 模块简要说明。
|
||
//!
|
||
//! 重构自 TLUSTY `filename.f`
|
||
```
|
||
|
||
### 函数注释
|
||
|
||
```rust
|
||
/// 函数功能说明。
|
||
///
|
||
/// # 参数
|
||
/// * `x` - 参数说明
|
||
///
|
||
/// # 返回值
|
||
/// 返回值说明
|
||
pub fn func(x: f64) -> f64 { ... }
|
||
```
|
||
|
||
## SPECIAL_MAPPINGS
|
||
|
||
一个 Rust 文件实现多个 Fortran 函数时,更新 `.claude/skills/fortran-analyzer/scripts/analyze_fortran.py`:
|
||
|
||
```python
|
||
SPECIAL_MAPPINGS = {
|
||
'gfree': ['gfree0', 'gfreed', 'gfree1'],
|
||
'interpolate': ['yint', 'lagran'],
|
||
'sgmer': ['sgmer0', 'sgmer1', 'sgmerd'],
|
||
# 添加新映射...
|
||
}
|
||
```
|
||
|
||
## 快速命令参考
|
||
|
||
```bash
|
||
# 查看重构进度
|
||
python3 .claude/skills/fortran-analyzer/scripts/analyze_fortran.py --priority | head -20
|
||
|
||
# 查看函数依赖树
|
||
python3 .claude/skills/fortran-analyzer/scripts/analyze_fortran.py --tree FUNCTION_NAME
|
||
|
||
# 测试单个模块(静默警告)
|
||
RUSTFLAGS="-A warnings" cargo test module_name 2>&1 | tail -10
|
||
# 或更简洁的方式
|
||
cargo test module_name -- --quiet 2>&1 | grep -E "^test|^running|^test result"
|
||
|
||
# 编译检查
|
||
cargo build 2>&1 | grep error
|
||
|
||
# 更新追踪表
|
||
python3 .claude/skills/fortran-analyzer/scripts/analyze_fortran.py > fortran_analysis.csv
|
||
```
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
rust/src/
|
||
├── math/ # 函数 (85+ 个 .rs 文件)
|
||
├── state/ # COMMON 块 (8 个模块)
|
||
│ ├── constants.rs # BASICS.FOR
|
||
│ ├── atomic.rs # ATOMIC.FOR
|
||
│ ├── model.rs # MODELQ.FOR
|
||
│ ├── arrays.rs # ARRAY1.FOR
|
||
│ ├── iterat.rs # ITERAT.FOR
|
||
│ ├── alipar.rs # ALIPAR.FOR
|
||
│ └── odfpar.rs # ODFPAR.FOR
|
||
└── data.rs # 静态数据(DATA 语句)
|
||
```
|
||
|
||
## 详细参考
|
||
|
||
完整的陷阱列表和解决方案见:`.learnings/LEARNINGS.md`
|
||
|
||
包含 14 个实际案例:
|
||
- F01-F02: 索引转换、表达式解析
|
||
- F03-F05: 类型推断、精度、溢出
|
||
- F06-F08: COMMON 块、测试数据、可变引用
|
||
- F09-F11: 依赖分析、列重叠、公式验证
|
||
- F12-F14: 大型结构体、GOTO 转换、mut 变量
|
||
|
||
重构前必读:**Quick Reference - Refactoring Checklist**(14 项检查)
|
||
|
||
## 相关 Skills
|
||
|
||
| Skill | 用途 | 状态 |
|
||
|-------|------|------|
|
||
| `fortran-extractor` | 提取 Fortran 文件 | ✅ 已完成 |
|
||
| `fortran-analyzer` | 分析依赖关系 | 活跃使用 |
|
||
| `fortran-to-rust` | 执行重构 | 本 skill |
|