# TLUSTY Rust 重构规范 ## 1. 选定下一个重构目标 优先处理依赖少无io的函数 注意:DATA 语句(硬编码的数据表)已经由scripts/extract_fortran_data.py生成到src/data.rs中 不要管复杂不复杂和有无common依赖, 按python3 scripts/analyze_fortran.py --priority | head -10 的顺序来 分离出来的原始fortran函数在/home/fmq/program/tlusty/tl208-s54/rust/tlusty/extracted文件夹下 ### 优先级排序 **核心原则**: 优先处理"传递未实现依赖=0"的函数,它们不依赖其他未完成的函数。 按以下顺序选择待重构函数: 1. **无未实现依赖** (传递未实现=0) - 可立即开始,无需等待其他函数 - 包括纯函数和只有 COMMON 依赖的函数 2. **少量未实现依赖** (传递未实现=1~3) - 需要先完成少数依赖函数 - 用 `--tree` 查看具体依赖链 3. **多未实现依赖** (传递未实现>3) - 依赖链较长,最后处理 - 或考虑整体重构策略 4. **有 I/O 依赖的函数** - 最后处理,可能需要设计新的 I/O 抽象层 ### 查询命令 CSV 列结构: `fortran_file,unit_name,unit_type,is_pure,common_deps,call_deps,has_io,rust_module,status` #### 依赖树分析 ```bash # 输出重构优先级列表(按未实现依赖排序,推荐!) python3 scripts/analyze_fortran.py --priority # 输出指定单元的依赖树 python3 scripts/analyze_fortran.py --tree UNIT_NAME # 输出完整传递依赖的 CSV python3 scripts/analyze_fortran.py --full > fortran_analysis_full.csv ``` **优先级列表说明:** ``` 重构优先级列表 (按未实现依赖排序) ==================================================================================================== 单元名 未实现 传递未实现 深度 直接调用 传递调用 IO ---------------------------------------------------------------------------------------------------- C 0 0 0 0 0 ○ ALIFR3 0 0 0 0 0 ○ ``` - **未实现**: 直接依赖中未完成的函数数 - **传递未实现**: 所有递归依赖中未完成的函数数(关键指标!) - **排序**: 传递未实现少 → 深度低 → 依赖少 - 只显示未完成(pending)的函数 - IO 列: ○ = 无IO, ✓ = 有IO **依赖树输出示例:** ``` 依赖树: ALISK1 ○ ============================================================ 直接依赖: 4, 传递依赖: 27, 未实现: 20 未实现依赖: ALIFRK, OPACF1, OPADD, ROSSTD, ... ------------------------------------------------------------ ○ ALISK1 (4未实现) ├── ○ OPACF1 (6未实现) │ ├── ○ OPADD (5未实现) │ │ ├── ○ cia_h2h2 (1未实现) │ │ │ └── if [未找到/未实现] │ │ └── ✓ locate │ └── ... └── ○ ALIFRK ``` - ✓ = 已完成, ○ = 待处理 - `(N未实现)` = 该节点有 N 个直接依赖未完成 - 顶部汇总:传递未实现依赖数及列表 - 子节点按未实现依赖数排序(多的在前) #### 按纯度筛选 无io的纯函数已经全部实现重构 #### 按 I/O 筛选 ```bash # 有 I/O 的未完成函数 (最后处理) awk -F, '$7=="True" && $9=="pending"' fortran_analysis.csv # 无 I/O 的未完成函数 (优先处理) awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv # 无 I/O 且无调用依赖的未完成函数 awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv ``` #### 按 COMMON 依赖筛选 ```bash # 只依赖 BASICS 的未完成函数 awk -F, '$5=="BASICS" && $9=="pending"' fortran_analysis.csv # 依赖 BASICS 和 ATOMIC,但无其他依赖 awk -F, '$5 ~ /^BASICS\|ATOMIC$/ && $9=="pending"' fortran_analysis.csv # 不依赖 MODELQ 的未完成函数 (MODELQ 最复杂) awk -F, '$5 !~ /MODELQ/ && $9=="pending"' fortran_analysis.csv # 列出所有不同的 COMMON 依赖组合 awk -F, '{print $5}' fortran_analysis.csv | sort | uniq -c | sort -rn ``` #### 按状态筛选 ```bash # 所有已完成函数 awk -F, '$9=="done"' fortran_analysis.csv # 所有进行中函数 awk -F, '$9=="in_progress"' fortran_analysis.csv # 统计各状态数量 awk -F, '{print $9}' fortran_analysis.csv | sort | uniq -c ``` #### 组合筛选 ```bash # 最佳候选:无 I/O + 无调用依赖 + 纯函数或简单 COMMON awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv # 次优候选:无 I/O + 有调用依赖但依赖已完成 awk -F, '$6!="" && $7=="False" && $9=="pending"' fortran_analysis.csv # 查看特定函数的依赖信息 awk -F, '$2=="TARGET"' fortran_analysis.csv ``` #### 按代码大小排序 ```bash # 按行数排序(选小的先做) cd tlusty/extracted wc -l *.f | sort -n | head -30 # 查看小文件 + 纯函数 for f in $(ls *.f); do lines=$(wc -l < "$f") name=$(basename "$f" .f) if grep -q "True.*pending" ../../fortran_analysis.csv && [ $lines -lt 100 ]; then echo "$lines $name" fi done | sort -n ``` #### 快速查看 ```bash # 查看重构进度摘要 echo "已完成: $(awk -F, '$9=="done"' fortran_analysis.csv | wc -l)" echo "待处理: $(awk -F, '$9=="pending"' fortran_analysis.csv | wc -l)" echo "纯函数待处理: $(awk -F, '$4=="True" && $9=="pending"' fortran_analysis.csv | wc -l)" echo "无IO待处理: $(awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv | wc -l)" ``` ## 2. 重构流程 ### Step 1: 分析 Fortran 源码 ```bash # 查看源码 cat tlusty/extracted/TARGET.f ``` 检查: - [ ] INCLUDE 文件列表 - [ ] COMMON 块 - [ ] 调用的其他函数 - [ ] 是否有 I/O ### Step 2: 创建 Rust 模块 ```bash # 创建文件 touch src/math/TARGET.rs ``` ### Step 3: 实现函数 遵循命名规范: - Fortran `FUNCTION` → Rust `pub fn` - Fortran `SUBROUTINE` → Rust `pub fn` (返回值用参数或元组) - COMMON 块 → 结构体参数 ### Step 4: 添加到 mod.rs ```rust // src/math/mod.rs mod target; pub use target::target; ``` ### Step 5: 编写测试 ```rust #[cfg(test)] mod tests { use super::*; use approx::assert_relative_eq; #[test] fn test_target_basic() { // 基本测试 } } ``` ### Step 6: 运行测试 ```bash # 单个模块测试 (不要 cargo test 全量!) cargo test target ``` ### Step 7: 更新追踪表 ```bash # 如果是一对一映射,脚本自动识别 python3 scripts/analyze_fortran.py > fortran_analysis.csv python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md # 如果是一对多映射,先更新 SPECIAL_MAPPINGS ``` ## 3. SPECIAL_MAPPINGS 维护 ### 何时需要更新 当一个 Rust 文件实现多个 Fortran 函数时,需要添加映射。 ### 位置 `scripts/analyze_fortran.py` 第 72 行 ### 格式 ```python SPECIAL_MAPPINGS = { # Rust 文件名 -> [Fortran 函数名列表] 'gfree': ['gfree0', 'gfreed', 'gfree1'], 'interpolate': ['yint', 'lagran'], 'sgmer': ['sgmer0', 'sgmer1', 'sgmerd'], 'ctdata': ['hction', 'hctrecom'], 'cross': ['cross', 'crossd'], 'expint': ['eint', 'expinx'], 'erfcx': ['erfcx', 'erfcin'], # 新增映射... } ``` ### 添加新映射后执行 ```bash python3 scripts/analyze_fortran.py > fortran_analysis.csv python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md ``` ## 4. 状态更新流程 ### 手动更新状态 如需手动标记状态,编辑 `fortran_analysis.csv`: ```csv # status 列: done, pending, in_progress, skip filename.f,UNIT,SUBROUTINE,False,"...",...,False,src/math/xxx.rs,done ``` 然后重新生成 Markdown: ```bash python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md ``` ## 5. 代码规范 ### 文件头注释 ```rust //! 模块简要说明。 //! //! 重构自 TLUSTY `filename.f` ``` ### 函数注释 ```rust /// 函数功能说明。 /// /// # 参数 /// /// * `x` - 参数说明 /// /// # 返回值 /// /// 返回值说明 /// /// # 示例 /// /// ``` /// use tlusty_rust::math::func; /// assert!((func(1.0) - 2.0).abs() < 1e-10); /// ``` pub fn func(x: f64) -> f64 { ... } ``` ### 精度要求 | 函数类型 | 容差 | |---------|------| | 简单数学运算 | 1e-10 | | 多项式近似 | 1e-7 | | f32 数组 | 1e-24 | ### 常见陷阱 | 问题 | 解决方案 | |------|----------| | Fortran 1-indexed | `arr(i)` → `arr[i-1]` | | `-LOG(X)` | 是 `-ln(X)` 不是 `ln(-X)` | | powi 类型歧义 | 用显式乘法 `(a)*(a)` | | 矩阵列优先 | `A(j,i)` → `a[(i-1)*N + (j-1)]` | ## 6. 快速命令参考 ```bash # 查看重构进度 cat FORTRAN_TRACKING.md | head -20 # 进度统计 echo "已完成: $(awk -F, '$9=="done"' fortran_analysis.csv | wc -l)" echo "待处理: $(awk -F, '$9=="pending"' fortran_analysis.csv | wc -l)" # 推荐方式:查看优先级列表(按未实现依赖排序) python3 scripts/analyze_fortran.py --priority | head -30 # 查看函数依赖树(含未实现依赖数) python3 scripts/analyze_fortran.py --tree FUNCTION_NAME # 找最佳候选:无IO + 无调用依赖 awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv | head -5 # 找纯函数 grep "True.*pending" fortran_analysis.csv | head -5 # 找无IO的函数 awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv | head -5 # 测试单个模块 cargo test module_name # 更新追踪表 python3 scripts/analyze_fortran.py > fortran_analysis.csv && \ python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md # 编译检查 cargo build 2>&1 | grep error ```