Files
hakorune/docs/guides/testing-guide.md
nyash-codex d7805e5974 feat(joinir): Phase 213-2 Step 2-2 & 2-3 Data structure extensions
Extended PatternPipelineContext and CarrierUpdateInfo for Pattern 3 AST-based generalization.

Changes:
1. PatternPipelineContext:
   - Added loop_condition: Option<ASTNode>
   - Added loop_body: Option<Vec<ASTNode>>
   - Added loop_update_summary: Option<LoopUpdateSummary>
   - Updated build_pattern_context() for Pattern 3

2. CarrierUpdateInfo:
   - Added then_expr: Option<ASTNode>
   - Added else_expr: Option<ASTNode>
   - Updated analyze_loop_updates() with None defaults

Status: Phase 213-2 Steps 2-2 & 2-3 complete
Next: Create Pattern3IfAnalyzer to extract if statement and populate update summary
2025-12-10 00:01:53 +09:00

231 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# テスト実行ガイド
## 📁 **テストファイル配置ルール(超重要!)**
⚠️ **ルートディレクトリの汚染防止ルール** ⚠️
```bash
# ❌ 絶対ダメ:ルートで実行
./target/release/hakorune test.hako # ログがルートに散乱!
cargo test > test_output.txt # 出力ファイルがルートに!
# ✅ 正しい方法:必ずディレクトリを使う
cd local_tests && ../target/release/hakorune test.hako
./target/release/hakorune local_tests/test.hako
```
**必須ルール:**
- **テストファイル**: 必ず `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.hako
./target/debug/nyash local_tests/test_hello.hako
# 演算子統合テストlocal_testsから実行
./target/debug/nyash local_tests/test_comprehensive_operators.hako
# 実用アプリテスト
./target/debug/nyash app_dice_rpg.hako
# JIT 実行フラグCLI
./target/release/hakorune --backend vm \
--jit-exec --jit-stats --jit-dump --jit-threshold 1 \
--jit-phi-min --jit-hostcall --jit-handle-debug \
examples/jit_branch_demo.hako
# 既存の環境変数でも可:
# 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/hakorune --backend vm --jit-exec --jit-hostcall examples/jit_array_param_call.hako
./target/release/hakorune --backend vm --jit-exec --jit-hostcall examples/jit_map_param_call.hako
./target/release/hakorune --backend vm --jit-exec --jit-hostcall examples/jit_map_int_keys_param_call.hako
./target/release/hakorune --backend vm --jit-exec --jit-hostcall examples/jit_string_param_length.hako
./target/release/hakorune --backend vm --jit-exec --jit-hostcall examples/jit_string_is_empty.hako
```
## PHI ポリシーPhase15と検証トグル
- Phase15 では PHIonMIR14が既定だよ。MIR ビルダーがブロック先頭へ `Phi` を配置し、検証も SSA 前提で実施するよ。
- レガシー検証で edge-copy 互換が必要なら `NYASH_MIR_NO_PHI=1` を明示してね(`NYASH_VERIFY_ALLOW_NO_PHI=1` も忘れずに)。
- 詳細は `docs/reference/mir/phi_policy.md` を参照してね。
テスト時の環境(推奨)
```bash
# 既定: 何も設定しない → PHI-on
# レガシー PHI-off の再現が必要なときだけ明示的に切り替え
export NYASH_MIR_NO_PHI=1
export NYASH_VERIFY_ALLOW_NO_PHI=1
# さらに edge-copy 規約を厳格チェックしたい場合(任意)
export NYASH_VERIFY_EDGE_COPY_STRICT=1
```
PHI-on の補助トレース
- `NYASH_LLVM_TRACE_PHI=1``NYASH_LLVM_TRACE_OUT=tmp/phi.jsonl` を組み合わせると、PHI がどの predecessor から値を受け取っているかを確認できるよ。
## PHI 配線トレースJSONL
- 目的: LLVM 側の PHI 配線が、PHI-on で生成された SSA と legacy edge-copy (PHI-off) の両方に整合しているかを可視化・検証する。
- 出力: 1 行 JSONJSONL`NYASH_LLVM_TRACE_OUT=<path>` に追記出力。
- イベント: `finalize_begin/finalize_dst/add_incoming/wire_choose/snapshot` などpred→dst 整合が分かる)
クイック実行v2
```bash
# 代表サンプルを LLVM ハーネスで実行し PHI トレースを採取v2 スクリプト)
bash tools/smokes/phi_trace_local.sh
# 結果の検証(要: python3
python3 tools/phi_trace_check.py --file tmp/phi_trace.jsonl --summary
```
ショートカット
- `tools/smokes/phi_trace_local.sh`(ビルド→サンプル実行→チェックを一括)
- `tools/smokes/v2/run.sh --profile quick|integration` で代表スモークを実行
## MIR デバッグの入口まとめ
### 1. CLI レベルの MIR ダンプ
- ソースから直接 MIR を確認:
- `./target/release/hakorune --dump-mir path/to/program.hako`
- VM 実行経路で MIR を一緒に吐く:
- `NYASH_VM_DUMP_MIR=1 ./target/release/hakorune path/to/program.hako`
- JSON で詳細解析したい場合:
- `./target/release/hakorune --emit-mir-json mir.json path/to/program.hako`
- 例: `jq '.functions[0].blocks' mir.json` でブロック構造を確認。
### 2. Scope / Loop ヒントNYASH_MIR_HINTS
- 環境変数でヒント出力を制御:
- `NYASH_MIR_HINTS="<target>|<filters>..."`
- 例:
- `NYASH_MIR_HINTS="trace|all"`stderr へ全ヒント)
- `NYASH_MIR_HINTS="jsonl=tmp/hints.jsonl|loop"`(ループ関連のみ JSONL 出力)
- 詳細: `docs/guides/scopebox.md`, `src/mir/hints.rs`
### 3. __mir__ ロガー(.hako から仕込む MIR ログ)
- 目的:
- `.hako` 側のループや SSA まわりを「MIR レベル」で観測するための dev 専用フック。
- 実行意味論には影響しないEffect::DebugLog のみ)。
- 構文(.hako 内):
```hako
__mir__.log("label", v1, v2, ...)
__mir__.mark("label")
```
- 第1引数は String リテラル必須(それ以外は通常の呼び出し扱い)。
- `log` は第2引数以降の式を評価し、その ValueId 群を記録。
- `mark` はラベルだけのマーカー。
- 戻り値は Void 定数扱いのため、式コンテキストに書いても型崩れしない。
- 実行時の有効化:
- `NYASH_MIR_DEBUG_LOG=1 ./target/release/hakorune path/to/program.hako`
- VM の MIR interpreter が次のようなログを stderr に出力:
```text
[MIR-LOG] label: %10=123 %11="foo"
```
- 実装位置:
- lowering: `src/mir/builder/calls/build.rs` の `try_build_mir_debug_call`receiver が `__mir__` のときに `MirInstruction::DebugLog` を挿入)。
- 実行: `src/backend/mir_interpreter/handlers/mod.rs``NYASH_MIR_DEBUG_LOG=1` のときだけログを出す)。
- 利用例(ループ観測の定番パターン):
```hako
loop(i < n) {
__mir__.log("loop/head", i, n)
...
}
__mir__.mark("loop/exit")
```
- FuncScanner / StageB では、skip_whitespace や scan_all_boxes のループ頭・出口に挿入して、ValueId と値の流れを追跡する用途で使用している。
## 🔌 **プラグインテスター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/hakorune --debug-fuel 1000 program.hako # 1000回制限
./target/release/hakorune --debug-fuel unlimited program.hako # 無制限
./target/release/hakorune program.hako # デフォルト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())
```
## Macro-based Test Runner (MVP)
Nyash provides a macro-powered lightweight test runner in Phase 16 (MVP).
- Enable and run tests in a script file:
- `nyash --run-tests apps/tests/my_tests.hako`
- Discovers top-level `test_*` functions and Box `test_*` methods (static/instance).
- Filtering: `--test-filter NAME` (substring match) or env `NYASH_TEST_FILTER`.
- Entry policy when a main exists:
- `--test-entry wrap` → run tests then call original main
- `--test-entry override` → replace entry with test harness only
- Force apply: `NYASH_TEST_FORCE=1`
- Parameterized tests (MVP): `NYASH_TEST_ARGS_DEFAULTS=1` injects integer `0` for each parameter (static/instance tests).
- Exit code = number of failed tests (0 on success).
Notes
- The feature is behind the macro gate; CLI `--run-tests` enables it automatically.
- Future versions will add JSON-based per-test arguments and richer reporting.