A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax
Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md
Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
11 KiB
11 KiB
テスト実行ガイド
📁 テストファイル配置ルール(超重要!)
⚠️ ルートディレクトリの汚染防止ルール ⚠️
# ❌ 絶対ダメ:ルートで実行
./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/を使用
なぜ毎回ルートが散らかるのか:
- テスト実行時にカレントディレクトリにログ出力
- エラー時のデバッグファイルが自動削除されない
- VM統計やMIRダンプがデフォルトでカレントに出力
🧪 テスト実行
# 基本機能テスト
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 ポリシー(Phase‑15)と検証トグル
- Phase‑15 では PHI‑on(MIR14)が既定だよ。MIR ビルダーがブロック先頭へ
Phiを配置し、検証も SSA 前提で実施するよ。 - レガシー検証で edge-copy 互換が必要なら
NYASH_MIR_NO_PHI=1を明示してね(NYASH_VERIFY_ALLOW_NO_PHI=1も忘れずに)。 - 詳細は
docs/reference/mir/phi_policy.mdを参照してね。
テスト時の環境(推奨)
# 既定: 何も設定しない → 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 行 JSON(JSONL)。
NYASH_LLVM_TRACE_OUT=<path>に追記出力。 - イベント:
finalize_begin/finalize_dst/add_incoming/wire_choose/snapshotなど(pred→dst 整合が分かる)
クイック実行(v2)
# 代表サンプルを 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 ダンプ
- VM 実行経路(SSOT)で「実際に走るMIR」を一緒に吐く:
NYASH_VM_DUMP_MIR=1 ./target/release/hakorune --backend vm path/to/program.hako
- 参考: 実行せずにコンパイルだけで MIR を確認(入口確認用 / compile-only):
./target/release/hakorune --dump-mir 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 内):
__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 に出力:
[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のときだけログを出す)。
- lowering:
-
利用例(ループ観測の定番パターン):
loop(i < n) { __mir__.log("loop/head", i, n) ... } __mir__.mark("loop/exit")- FuncScanner / Stage‑B では、skip_whitespace や scan_all_boxes のループ頭・出口に挿入して、ValueId と値の流れを追跡する用途で使用している。
🔌 プラグインテスター(BID-FFI診断ツール)
# プラグインテスターのビルド
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実装)
# 🔥 デバッグ燃料でパーサー制御
./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"など問題のあるトークンも安全にエラー検出
アプリケーション デバッグ
// 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 Boxtest_*methods (static/instance).
- Filtering:
--test-filter NAME(substring match) or envNYASH_TEST_FILTER.
Phase 285: Lifecycle / WeakRef / Leak diagnostics(クロスバックエンド)
言語SSOT:
docs/reference/language/lifecycle.md(fini/ weak / cleanup / GC方針)docs/reference/language/types.md(truthiness とnull/void)
目的:
- Rust VM と LLVM(harness)で、weak と lifecycle の挙動が一致しているかを短い fixture で固定する。
- 強参照サイクル等で「終了時に強参照rootが残っている」状況を、default-off の診断で観測できるようにする(実装後)。
推奨の運用(ルート汚染防止):
- fixture は
local_tests/に置く。
例(weakが効いていること):
mkdir -p local_tests
$EDITOR local_tests/phase285_weak_basic.hako
./target/release/hakorune --backend vm local_tests/phase285_weak_basic.hako
NYASH_LLVM_USE_HARNESS=1 ./target/release/hakorune --backend llvm local_tests/phase285_weak_basic.hako
例(強参照サイクル + 終了時診断):
$EDITOR local_tests/phase285_cycle.hako
# 実装後: leak report をONにして終了時に root を表示
NYASH_LEAK_LOG=1 ./target/release/hakorune --backend vm local_tests/phase285_cycle.hako
NYASH_LLVM_USE_HARNESS=1 NYASH_LEAK_LOG=1 ./target/release/hakorune --backend llvm local_tests/phase285_cycle.hako
実装者向けの詳しい手順:
docs/development/current/main/phases/phase-285/CLAUDE_CODE_RUNBOOK.md- 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=1injects integer0for each parameter (static/instance tests). - Exit code = number of failed tests (0 on success).
Notes
- The feature is behind the macro gate; CLI
--run-testsenables it automatically. - Future versions will add JSON-based per-test arguments and richer reporting.