📚 Reorganize CLAUDE.md: slim down from 916 to 395 lines with proper doc links

- Keep essential information within 500 lines (now 395 lines)
- Maintain important syntax examples and development principles
- Move detailed information to appropriate docs files:
  - Development practices → docs/guides/development-practices.md
  - Testing guide → docs/guides/testing-guide.md
  - Claude issues → docs/tools/claude-issues.md
- Add proper links to all referenced documentation
- Balance between minimal entry point and practical usability
This commit is contained in:
Moe Charm
2025-08-31 06:22:48 +09:00
parent b003bdf25b
commit fff9749f47
54 changed files with 3965 additions and 917 deletions

View File

@ -0,0 +1,167 @@
# 開発プラクティス
## 🔍 技術判断の鉄則
### アーキテクチャ質問への対処手順
1. **実証ファイル確認**: `file app`, `nm app`, `ls target/`
2. **既存コード確認**: 関連ソース読み取り
3. **仮説検証**: 推測でなく実証ベース
4. **結論**: 確認済み事実のみ回答
### よくある質問の実証方法
- **JIT/LLVMのABI**: → `file string_len_app` でELF確認
- **MIR命令数**: → `grep "enum MirInstructionKind" src/mir/*.rs`
- **プラグイン実装**: → `ls plugins/*/target/release/`
- **C ABI統一**: → `nm app | grep nyash` でシンボル確認
## 🏗️ 設計原則
### 📦 Everything is Box - 内部実装でも箱原理を貫く
#### 1. **単一責任の箱**
```rust
// ✅ 良い例:各モジュールが単一の責任を持つ
MirBuilder: AST MIR変換のみ(最適化しない)
MirOptimizer: MIRの最適化のみ(変換しない)
VM: 実行のみ(最適化しない)
// ❌ 悪い例:複数の責任が混在
BuilderOptimizer: 変換も最適化も実行も...
```
#### 2. **明確なインターフェース**
```rust
// ✅ エフェクトは単純に
enum Effect {
Pure, // 副作用なし
ReadOnly, // 読み取りのみ
SideEffect // 書き込み/IO/例外
}
// ❌ 複雑な組み合わせは避ける
PURE.add(IO) // これがpureかどうか分からない
```
#### 3. **段階的な処理パイプライン**
```
AST → Builder → MIR → Optimizer → VM
↑ ↑ ↑ ↑ ↑
明確な入力 明確な出力 不変保証 最適化のみ 実行のみ
```
### 🎯 カプセル化の徹底
#### 1. **内部状態を隠蔽**
```rust
// ✅ 良い例:内部実装を隠す
pub struct MirOptimizer {
debug: bool, // 設定のみ公開
enable_typeop_net: bool, // 設定のみ公開
// 内部の複雑な状態は隠蔽
}
impl MirOptimizer {
pub fn new() -> Self { ... }
pub fn with_debug(self) -> Self { ... }
pub fn optimize(&mut self, module: &mut MirModule) { ... }
}
```
#### 2. **変更の局所化**
- 新機能追加時1つのモジュールのみ変更
- バグ修正時:影響範囲が明確
- テスト:各モジュール独立でテスト可能
### 🌟 美しさの基準
#### 1. **読みやすさ > 賢さ**
```rust
// ✅ 単純で分かりやすい
if effect == Effect::Pure {
can_eliminate = true;
}
// ❌ 賢いが分かりにくい
can_eliminate = effect.0 & 0x01 == 0x01 && !(effect.0 & 0xFE);
```
#### 2. **一貫性**
- 命名規則の統一
- エラー処理の統一
- コメントスタイルの統一
### 🚀 大規模化への備え
#### 1. **モジュール分割の原則**
```
src/
├── ast/ # AST定義のみ
├── parser/ # パース処理のみ
├── mir/ # MIR定義と基本操作
│ ├── builder.rs # AST→MIR変換
│ └── optimizer.rs # MIR最適化
├── backend/ # 実行バックエンド
│ ├── interpreter.rs # インタープリター
│ ├── vm.rs # VM実行
│ └── codegen_c.rs # C言語生成
```
#### 2. **テストの階層化**
- 単体テスト:各モジュール内で完結
- 統合テスト:モジュール間の連携
- E2Eテスト全体の動作確認
#### 3. **設定の外部化**
```rust
// ✅ フラグで挙動を制御(再コンパイル不要)
optimizer.enable_typeop_safety_net(flag);
// ❌ ハードコードされた挙動
#[cfg(feature = "typeop_safety_net")]
```
### 💡 デバッグとメンテナンス
#### 1. **段階的なデバッグ出力**
```bash
NYASH_BUILDER_DEBUG=1 # Builder のみ
NYASH_OPT_DEBUG=1 # Optimizer のみ
NYASH_VM_DEBUG=1 # VM のみ
```
#### 2. **問題の早期発見**
- 各段階でのアサーション
- 不変条件の明示的チェック
- 診断機能の組み込み
### 🎭 複雑さの管理
**複雑さは避けられないが、管理はできる**
1. 複雑な部分を局所化
2. インターフェースは単純に
3. ドキュメントで意図を明示
**判断基準3ヶ月後の自分が理解できるか**
## 🤝 プロアクティブ開発方針
### 🎯 エラー対応時の姿勢
エラーを見つけた際は、単に報告するだけでなく:
1. **🔍 原因分析** - エラーの根本原因を探る
2. **📊 影響範囲** - 他のコードへの影響を調査
3. **💡 改善提案** - 関連する問題も含めて解決策を提示
4. **🧹 機会改善** - デッドコード削除など、ついでにできる改善も実施
### ⚖️ バランスの取り方
- **積極的に分析・提案**するが、最終判断はユーザーに委ねる
- 「ChatGPTさんに任せてる」と言われても、分析結果は共有する
- 複数のAIが協調する場合でも、各自の視点で価値を提供する
### 📝 例
```
❌ 受動的: 「エラーをファイルに出力しました」
✅ 能動的: 「エラーをファイルに出力しました。主な原因は型の不一致7箇所で、
instance_id()のメソッド呼び出し修正で5つ解決できそうです。
また、関連してclone_boxの実装にも同様の問題を発見しました。」
```

View File

@ -0,0 +1,110 @@
# テスト実行ガイド
## 📁 **テストファイル配置ルール(超重要!)**
⚠️ **ルートディレクトリの汚染防止ルール** ⚠️
```bash
# ❌ 絶対ダメ:ルートで実行
./target/release/nyash test.nyash # ログがルートに散乱!
cargo test > test_output.txt # 出力ファイルがルートに!
# ✅ 正しい方法:必ずディレクトリを使う
cd local_tests && ../target/release/nyash test.nyash
./target/release/nyash local_tests/test.nyash
```
**必須ルール:**
- **テストファイル**: 必ず `local_tests/` に配置
- **ログファイル**: 環境変数で `logs/` に出力するか、実行後即削除
- **デバッグ出力**: `local_tests/` または `logs/` に保存
- **一時ファイル**: `/tmp/` を使用
**なぜ毎回ルートが散らかるのか:**
1. テスト実行時にカレントディレクトリにログ出力
2. エラー時のデバッグファイルが自動削除されない
3. VM統計やMIRダンプがデフォルトでカレントに出力
## 🧪 テスト実行
```bash
# 基本機能テスト
cargo test
# テストファイル作成・実行例
mkdir -p local_tests
echo 'print("Hello Nyash!")' > local_tests/test_hello.nyash
./target/debug/nyash local_tests/test_hello.nyash
# 演算子統合テストlocal_testsから実行
./target/debug/nyash local_tests/test_comprehensive_operators.nyash
# 実用アプリテスト
./target/debug/nyash app_dice_rpg.nyash
# JIT 実行フラグCLI
./target/release/nyash --backend vm \
--jit-exec --jit-stats --jit-dump --jit-threshold 1 \
--jit-phi-min --jit-hostcall --jit-handle-debug \
examples/jit_branch_demo.nyash
# 既存の環境変数でも可:
# NYASH_JIT_EXEC/NYASH_JIT_STATS(/_JSON)/NYASH_JIT_DUMP/NYASH_JIT_THRESHOLD
# NYASH_JIT_PHI_MIN/NYASH_JIT_HOSTCALL/NYASH_JIT_HANDLE_DEBUG
# HostCallハンドルPoCの例
./target/release/nyash --backend vm --jit-exec --jit-hostcall examples/jit_array_param_call.nyash
./target/release/nyash --backend vm --jit-exec --jit-hostcall examples/jit_map_param_call.nyash
./target/release/nyash --backend vm --jit-exec --jit-hostcall examples/jit_map_int_keys_param_call.nyash
./target/release/nyash --backend vm --jit-exec --jit-hostcall examples/jit_string_param_length.nyash
./target/release/nyash --backend vm --jit-exec --jit-hostcall examples/jit_string_is_empty.nyash
```
## 🔌 **プラグインテスターBID-FFI診断ツール**
```bash
# プラグインテスターのビルド
cd tools/plugin-tester
cargo build --release
# プラグインの診断実行
./target/release/plugin-tester ../../plugins/nyash-filebox-plugin/target/debug/libnyash_filebox_plugin.so
# 出力例:
# Plugin Information:
# Box Type: FileBox (ID: 6) ← プラグインが自己宣言!
# Methods: 6
# - birth [ID: 0] (constructor)
# - open, read, write, close
# - fini [ID: 4294967295] (destructor)
```
**plugin-testerの特徴**:
- Box名を決め打ちしない汎用設計
- プラグインのFFI関数4つabi/init/invoke/shutdownを検証
- birth/finiライフサイクル確認
- 将来の拡張: TLV検証、メモリリーク検出
## 🐛 デバッグ
### パーサー無限ループ対策2025-08-09実装
```bash
# 🔥 デバッグ燃料でパーサー制御
./target/release/nyash --debug-fuel 1000 program.nyash # 1000回制限
./target/release/nyash --debug-fuel unlimited program.nyash # 無制限
./target/release/nyash program.nyash # デフォルト10万回
# パーサー無限ループが検出されると自動停止+詳細情報表示
🚨 PARSER INFINITE LOOP DETECTED at method call argument parsing
🔍 Current token: IDENTIFIER("from") at line 17
🔍 Parser position: 45/128
```
**対応状況**: must_advance!マクロでパーサー制御完全実装済み✅
**効果**: 予約語"from"など問題のあるトークンも安全にエラー検出
### アプリケーション デバッグ
```nyash
// DebugBox活用
DEBUG = new DebugBox()
DEBUG.startTracking()
DEBUG.trackBox(myObject, "説明")
print(DEBUG.memoryReport())
```