--- 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 |