diff --git a/CODEX_QUESTION_backup.md b/CODEX_QUESTION_backup.md deleted file mode 100644 index e5230c70..00000000 --- a/CODEX_QUESTION_backup.md +++ /dev/null @@ -1,103 +0,0 @@ -# Codex向け質問 - Phase 15.5後のテスト戦略 - -## 📋 背景 - -Phase 15.5でCore Box完全削除を実施し、すべてのBoxをプラグイン化しました。その結果: -- ✅ nyash.tomlのパス修正完了(13箇所) -- ✅ プラグインは正常にロード(.soファイル20個存在) -- ✅ 基本的な算術演算・制御構文は動作 -- ❌ StringBox/IntegerBoxのメソッドが動作しない - -## 🔍 現在の問題 - -### StringBoxプラグインの状況 -```nyash -local s = new StringBox("Hello") # ← オブジェクト生成OK(ハンドル返却) -print(s) # ← 空文字列(toString失敗) -s.length() # ← 0を返す(内部データなし) -s.toString() # ← 空文字列を返す -s.get() # ← 空文字列を返す -``` - -### 調査済み事項 -1. プラグインは正常にロード(plugin-testerで確認) -2. nyash_plugin_invokeは実装済み(legacy v1 ABI) -3. method_id衝突を修正済み(0-3 → 4+に変更) -4. 通常の文字列リテラルは動作する -5. 算術演算は問題なし - -### 🔬 根本原因(Codex調査結果) -**TypeBox v2のresolveブランチが欠落している** -- `birth`メソッドの解決パスが未実装 -- `toString`メソッドの解決パスが未実装 -- プラグインメソッドは呼ばれるが、結果の処理に問題 - -## 🎯 質問 - -### 1. **StringBoxメソッドが動作しない原因は?** -Phase 15.5でCore Boxを削除した影響で、プラグイン側の実装が不完全な可能性があります。 -- プラグインのnyash_plugin_invoke実装を確認すべき箇所は? -- MIRビルダー側でプラグインメソッド呼び出しに特別な処理が必要? - -### 2. **テスト戦略の方向性** -現状でStringBox/IntegerBoxが動作しない中で: -- A案: プラグインメソッド修正を優先 -- B案: 基本機能(算術・制御)のテストを先に充実 -- C案: 別のBoxプラグイン(FileBox等)でテスト - -どの方向性が効率的でしょうか? - -### 3. **プラグインメソッド呼び出しのデバッグ方法** -```bash -# 現在の確認方法 -./tools/plugin-tester/target/release/plugin-tester check --config nyash.toml -# → プラグインロードはOK、でもメソッド実行時に問題 - -# より詳細なデバッグ方法は? -``` - -## 🔄 再現手順 - -### 最小再現コード -```bash -# test_stringbox.nyash -local s = new StringBox("Hello World") -print("StringBox created") -print(s) # 期待: "Hello World", 実際: "" -local len = s.length() -print("Length: " + len) # 期待: 11, 実際: 0 -``` - -### 実行コマンド -```bash -# プラグインロード確認 -./tools/plugin-tester/target/release/plugin-tester check --config nyash.toml - -# テスト実行 -NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 ./target/release/nyash test_stringbox.nyash -``` - -### デバッグ情報収集 -```bash -# 詳細ログ -NYASH_CLI_VERBOSE=1 ./target/release/nyash test_stringbox.nyash - -# MIRダンプ確認 -./target/release/nyash --dump-mir test_stringbox.nyash -``` - -## 📁 関連ファイル - -- `nyash.toml` - プラグイン設定(method_id修正済み) -- `plugins/nyash-string-plugin/src/lib.rs` - StringBoxプラグイン実装 -- `tools/smokes/v2/` - 新スモークテストシステム -- `src/box_factory/plugin.rs` - プラグインロード実装 -- `src/mir/builder/builder_calls.rs` - TypeBox v2 resolve実装(問題箇所) - -## 🚀 期待する回答 - -1. StringBoxメソッドが動作しない根本原因の特定方法 -2. 効率的なテスト戦略の提案 -3. プラグインメソッド呼び出しのデバッグ手法 - -よろしくお願いします! \ No newline at end of file diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 19e445b1..b7aee1a5 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -1,18 +1,18 @@ -# Current Task — Phase 20.38 (Extern/C‑ABI bring‑up, Hako‑first verify) +# Current Task — Phase 20.39 (Typed IR & hv1 finalize) This document is intentionally concise (≤ 500 lines). Detailed history and per‑phase plans are kept under docs/private/roadmap/. See links below. Focus (now) -- Extern/C‑ABI の最小導線(既定OFF)を整備し、Hakorune primary で emit/codegen を rc=0 + 安定タグに固定。 -- v1 Dispatcher を IR 反復に切替(scan 依存を排除)、φテーブル適用の堅牢化(strict/tolerate)。 -- Verify 既定を v1→Hako(Core fallback)へ整流(段階)。 -- Using はテキスト統合(merge_prelude_text)に一本化、include は quick=ERROR(ハーネス方針と整合)。 - - 拡張子ポリシー(暫定): `.nyash`→Nyash VM、`.hako`→Hakorune VM。詳細は docs/guides/source-extensions.md。 +- Typed IR(SSOT)の導入: V1ConstIR / V1CompareIR / V1BranchIR / V1JumpIR / V1PhiIR / V1RetIR を Hako で定義(挙動不変)。 +- hv1 verify の最終化: 直行(env JSON→Core 実行)を標準にし、-c/inline 経路・include フォールバックを撤去。 +- Concat-safety sweep: “"" + ” を全廃(必要時のみ to-string)。 +- LoopForm.build2 の適用拡大(既存 PASS を崩さず小粒に)。 -Remaining (20.38 — inline alias stabilization: updated) -- Route: vm.rs に hv1 直行ルートを追加(HAKO_ROUTE_HAKOVM=1 かつ NYASH_VERIFY_JSON)。NyashParser を完全にバイパス。 -- Alias only: verify は alias のみで安定(include/preinclude は撤去・既定OFF)。 -- Safety sweep: “"" + ” の連結全廃(必要時のみ to-string)。 +Remaining (20.39 — typed IR & finalize) +- Add typed IR boxes and module export(hakorune-vm.ir.types)。 +- Wire dispatcher to accept typed IR inputs gradually(写像ヘルパ・差分ゼロ)。 +- Remove include fallback from scripts(直行のみ)。 +- Sweep concatenations and update helpers. Hotfix Plan — Using/Prelude Unification (Self‑Host) - Problem: .hako を NyashParser に通す経路でパース落ち(Invalid expression)。 @@ -45,10 +45,8 @@ Acceptance - Hako 構文を Nyash VM で実行しようとした場合、入口で Fail‑Fast(診断メッセージ)。 Changes (this step) -- hv1 直行: vm.rs 冒頭で `NYASH_VERIFY_JSON` を検出し、JSON v1/v0→MIR→Core 実行(数値のみ出力)。 -- test_runner: hv1 verify は直行(`$NYASH_BIN --backend vm /dev/null`+env JSON)。include fallback は dev 変数で明示時のみ。 -- v1 JSON Bridge: φ incoming を [pred,val] として正規化(Core parity)。 -- φ カナリー追加: multi-incoming3 / nested+sum / tolerate undefined→rc=0。 +- Docs: phase‑20.39 に計画を追記(Tasks/Acceptance/Plan)。 +- Add typed IR box file(hakorune-vm.ir.types)と module export(構造のみ・参照用)。 - V1PhiAdapterBox: robust incoming scan (multi‑pair, spaces/newlines) using array‑end scanner. - V1SchemaBox: new block_segment_wo_phi(json, bid) to build IR segment without φ. - V1SchemaBox: phi_table_for_block(json,bid) 追加(dst と incoming[[pred,val],…] を返す) diff --git a/CURRENT_TASK_ARCHIVE_2025-09-27.md b/CURRENT_TASK_ARCHIVE_2025-09-27.md deleted file mode 100644 index 075e39a5..00000000 --- a/CURRENT_TASK_ARCHIVE_2025-09-27.md +++ /dev/null @@ -1,2435 +0,0 @@ -Archived snapshot of CURRENT_TASK.md as of 2025‑09‑27. See CURRENT_TASK.md for the concise, up‑to‑date plan. - ---- - -# Current Task — Phase 15 (Revised): Self‑Hosting Focus, JSON→Ny Executor - -Update — json_query_min fix & parser seam guard (2025‑09‑27) -- Fix: apps/examples/json_query_min/main.nyash was simplified to a single‑method evaluator to avoid member‑seam misparse. Now prints `2` for `.a.b[1]` and quick smoke PASS. -- Parser hardening: blocks now skip leading NEWLINE tokens when scanning statements (parse_block_statements, parse_method_body_statements). Optional seam guard (NYASH_PARSER_METHOD_BODY_STRICT=1) added to stop accidental method‑head consumption inside method bodies. -- Verified: tools/smokes/v2/run.sh --profile quick --filter "apps/json_query_min_vm.sh" → PASS. - -Updated: 2025‑09‑27 - -Quick status -- Build: `cargo build --release` → OK(警告のみ) -- Smokes v2: quick/core PASS、integration/parity PASS(Python LLVM harness) -- Parser: TokenCursor 統一 Step‑2/3 完了(env ゲート) -- PHI: if/else の incoming pred を exit ブロックへ修正(VM 未定義値を根治) -- Resolver: using 先を DFS で事前ロードする共通ヘルパー導入(common/vm_fallback 両経路で `resolve_prelude_paths_profiled` を採用済み) -- Loop‑Form: ループ低下を LoopBuilder 正規形(preheader→header(φ)→body→latch→exit)に統一(cf_loop 経由) -- VM fallback: 受信クラスで一意絞り込み(JsonScanner.is_eof 誤命中の根治) -- Smokes: quick の JSON + method resolution、integration の VM↔LLVM parity(JSON/resolve) を追加 - -Today’s completion(2025‑09‑27 late‑night) -- quick 緑化(JSON 代表) - - apps/json_pp_vm.sh: PASS(JsonNode.parse を用いた軽量経路に切替) - - apps/json_lint_vm.sh: PASS(軽量 fast‑path 判定+最小構造のOK判定/残りのみ Parser へ) -- MIR/Builder 安定化の再確認 - - NewBox→birth() 明示発行の導線を確認(Builder 統一パス) - - Compare 両辺の slotify/pin を徹底(PHI/分岐越えの型・起源維持) -- VM 側の観測期ガード(仕様不変/開発限定) - - print/console.log: Void / BoxRef(VoidBox) を "null" 出力(観測オンでも出力が安定) - - String.indexOf 実装(VM 経路の不足補完) - - InstanceBox.current(): position/text を持つ受信体に対する最小フォールバック(1 文字返却) - - 比較: --dev で Void 許容を常時有効(BoxRef(VoidBox)→Void 正規化+最終安全弁) - -影響と意図 -- すべて MIR 形(birth 明示、compare slotify)に効くため LLVM ラインの安定にも寄与。 -- VM のフォールバックは dev 期の観測用安全弁(本番意味論は変更なし)。 - -Update — Operator Boxes 観測“常時ON”方針(2025‑09‑27) -- 決定: 観測(observe)は prod/dev とも常時ONに段階移行(挙動不変)。採用(adopt)は段階ON(Compare→Add→他)。 -- 反映済みの基盤変更(小差分・仕様不変): - - VM fallback scope: 受信クラス prefix(Class./ClassInstance.)でフォールバックを常に絞り込み(cross‑class 不採用)。 - - Compare 観測拡充: `CompareOperator.apply` ログに `op`(Eq/Lt/…)と `fn`(呼び出し元関数名)を追加。 - - Void 対応(dev容認): `NYASH_VM_TOLERATE_VOID=1` で BoxRef(VoidBox)→Void 正規化し、binop/compare で Void を 0/空文字として扱う(helpers.rs)。 - - 出力安定化: `print`/`env.console.log` は Void→`null`、String/StringBox は生文字列を直出力(ダブルクォート重複を回避)。 - - StringBox.stringify: 最低限の JSON 風 quoting を VM で実装(呼び出しに応答可能)。 - - --dev 既定: `NYASH_VM_TOLERATE_VOID=1` を自動付与(観測の安定化)。 - -JSON apps 安定化(WIP) -- Node 正規化: `JsonNode.object_get/array_get` が常に JsonNode(or null)を返すよう正規化(`normalize_any_`)。 -- json_query: アプリ側 `ensure_node` を廃止し Node 側正規化に一本化。最小スモーク(`.a.b[1]→2`)を追加。 -- 現状: dev 観測下では Ge×Void の致命は見えづらくなり、比較まわりの Void 混入は `JsonTokenizer.next_token/JsonToken.is_eof` の Ne/Eq で観測される(null 判定系)。非集約経路での Ge×Void は引き続き点検中。 - -次の作業(Small, reversible) -1) 観測“常時ON”の最終化: - - Resolver 側の prelude 注入(stringify/compare/add)を prod でも常時有効(採用は既定OFF)に整理(重複注入は回避)。 - - quick/integration を実行、差分ゼロを確認。 -2) quick JSON の緑化: - - `tools/smokes/v2/profiles/quick/apps/` の JSON 系に `NYASH_VM_TOLERATE_VOID=1` を一時付与(--dev 取りこぼし対策)。 - - 緑安定後に段階的に外す。 -3) 採用の段階昇格: - - Compare adopt=ON→ quick/integration 緑→ perf ±10%以内 → 次に Add adopt=ON … の順で昇格。 - -追記(本スライス後の具体 To‑Do) -- LLVM parity(JSON apps): integration/profiles の parity を --dev 設定で実行し、出力差分ゼロを確認。 -- dev 限定ガードの範囲明確化: 比較の最終安全弁は `NYASH_DEV=1` 時のみ有効に寄せ、安定後に段階撤去。 -- InstanceBox.current フォールバックの縮退: Parser/Builder の seam ガードを追加確認後、フォールバック削除の段取り(ログで検出→削除)。 - -受け入れ基準 -- 観測“常時ON”で quick/integration の出力が従来と同一(差分ゼロ)。 -- Compare adopt=ON で quick/integration が緑を維持(差分ゼロ/±10%以内)。 -- JSON apps(pp/lint/query)の quick が --dev で緑。json_query 最小スモーク(`.a.b[1]`)が PASS。 - - LLVM parity(JSON pp/lint)で出力差分ゼロ(LLVM がある環境)。 - - dev 限定ガード(Void 許容/最終安全弁)が本番に影響しない(フラグOFFで従来どおり)。 - -Update — Add adopt 昇格(2025‑09‑27) -- 変更: `src/config/env.rs` の `operator_box_add_adopt()` を既定ONに昇格。 - - OFF にしたい場合は `NYASH_OPERATOR_BOX_ADD_ADOPT=0|false|off` を明示。 -- 検証: quick の JSON 代表(pp/lint/query)+欠損観測スモークはすべて PASS。差分ゼロ。 -- 観測: nullish trace は旗ON時のみ。既定出力は不変。 - -Defaults & Dev Mode — Plan / Progress -- 目的: “何も付けない=本番(安定)”“--dev=開発(実験観測ON)”の二枚看板に統一。環境変数爆発を段階的に収束。 -- 現状: 開発ショートカット(tools/opbox-*.sh)で再現性は確保。実験旗は個別にオン。 -- 直近でやる(この順): - 1) CLI に `--dev` を追加(env フォールバック `NYASH_DEV=1`)。【完了】 - 2) `--dev` で AST using=ON(SSOT+AST 既定ON)、Operator Boxes=observe(採用OFF)、診断は最小ON。【完了】 - 3) スモークの入口を `--dev` に更新(profiles は補助)。【一部完了: JSON roundtrip/nested を更新】 - 4) フラグ集約キー: `NYASH_OPERATOR_BOXES` / `NYASH_TRACE` を導入(後方互換維持)。【未着手】 -- 受け入れ: - - `nyash script.nyash` が静かで安定に実行。 - - `nyash --dev script.nyash` で JSON Roundtrip/Nested PASS(出力差分なし)。【JSON 2件のスモーク切替済み】 - - `docs/guides/dev-mode.md` の内容と実装が一致。 - ---- - -Null/Missing Boxes — Observe→Adopt(設計導入、2025‑09‑27) - -- 目的 - - 値の不在(Null)と欠損(Missing)を分離し、観測しやすくする。既定挙動は不変(prod安全)。 - -- 変更(このスライス) - - 型: `src/boxes/missing_box.rs` に MissingBox を追加(一級Box)。`src/boxes/mod.rs` で re-export、`box_trait.rs` BUILTIN に追加。 - - env: `src/config/env.rs` に観測フラグを追加。 - - `NYASH_NULL_MISSING_BOX=1` → 観測有効(現時点では既定挙動を変えない)。 - - `NYASH_NULL_STRICT=1` → 厳格モード(将来、演算時に Null をエラー扱いする際に使用)。 - - docs: `docs/design/null-missing-boxes.md` を追加(仕様・段階導入・受け入れ基準)。 - -- 既定挙動 - - 変更なし。NullBox は従来どおり VMValue::Void 経由で "null" にマップ。MissingBox はまだ生成側に配線していない。 - -- 次(small, reversible) - - helpers/calls に軽い分類ヘルパを追加(BoxRef(NullBox/MissingBox) を trace で識別)。 - - print: dev限定で Missing を可視化("(missing)")→ その後 UI 境界で null 正規化に寄せる方針へ収束。 - - JSON/Node: フラグON時のみ object_get/array_get の欠損を MissingBox に切替(アプリ出力に差分を出さないよう最終段で正規化)。 - - -Application Sprint — Apps & Testing First(短期フォーカス) -- 目的: 論文化の前に「実アプリを動かし、テストで支える」段を挟む。JSON ネイティブを核に、小さな実用アプリを2–3本作り、quick/integration のスモークで守る。 -- やること(優先順): - 1) JSON Pretty Printer(apps/examples/json_pp): 入力→整形出力。VM/LLVM 両経路で動作。 - 2) JSON Query(apps/examples/json_query): パス指定で抽出(例: .a.b[1])。最小機能でOK。 - 3) JSON Lint(apps/examples/json_lint): 先頭エラーの位置/行列と簡易メッセージ。 - 4) スモーク拡充: 上記3本を quick(VM)・integration(VM↔LLVM parity)に追加。Dev 既定で差分ゼロを確認。 - 5) 代表的メソッド解決スモーク: is_eof/length/substring/Map.set/get の最小ケースを quick に足す(resolve の退行検知)。 -- 完了済み/進行: - - VM フォールバック安全化: 受信クラスを prefix に候補絞り込み(JsonToken vs JsonScanner 誤命中の根治)。 - - quick 追加: method_resolution_is_eof_vm(PASS)。 - - integration 追加: json_roundtrip_vm_llvm / json_nested_vm_llvm / method_resolution_is_eof_vm_llvm(LLVM 環境で PASS、未ビルドは SKIP)。 -- 受け入れ基準: - - quick: JSON(roundtrip/nested)+ method_resolution が常時 PASS。 - - integration: LLVM 環境で parity 3件が PASS(未ビルドは SKIP で緑維持)。 - - 新規 examples 3本の quick/integration スモークが PASS(Dev 既定; --dev or NYASH_DEV=1)。 -- スコープ外(このスプリントではやらない): - - 最適化(DCE/Copy-prop/Trivial-PHI ON)と性能計測の深追い。 - - 大幅な仕様変更(既定挙動の変更)。 - -Paper Prep — 設計・評価の骨子(保留・アウトラインのみ) -- 目的: Operator Boxes とハイブリッド静的解決の記述を中心に、55日の開発記録を“設計+経験”としてまとめる。 -- 当面の準備(後段で着手): - - OUTLINE.md / EVAL_PLAN.md / FIGURES.md のたたき台を docs/paper/ に作成。 - - 計測フック: 静的解決率(builder)/ フォールバック率(VM)の簡易カウンタを dev 既定で JSONL 出力(既定OFF)。 -- 受け入れ: アプリ/スモークが安定し、数日分の安定ログが取れたら着手。 - -Operator Box(演算子ボックス)— Stringify MVP(開発限定・既定OFF) -- 目的: 暗黙の文字列化を明示の「演算子(Box)」化し、追跡可能にする(Everything is Box を演算子にも拡張) -- フラグ: `NYASH_OPERATOR_BOX_STRINGIFY=1`(既定OFF) -- 実装: - - VM: `print` と `env.console.log` 経路でフラグON時に `StringifyOperator.apply/1` を優先。 - - Resolver: フラグONかつ AST using 時、`apps/lib/std/operators/stringify.nyash` を自動プレリュード注入して materialize。 - - 演算子: `apps/lib/std/operators/stringify.nyash` — `value.stringify()` があれば委譲、なければ `"" + value` で安全に文字列化。 - - 受け入れ: dev+AST+フラグON で `json_roundtrip_vm.sh` / `json_nested_vm.sh` とも PASS(従来も PASS 維持)。 - - 後方互換: フラグOFF時は完全に従来どおり(非介入)。 - - ロールバック: VM 2箇所のフックと resolver 注入・演算子ファイルを戻すのみ(小差分)。 - -拡張 — Compare/Add(観測MVP・既定OFF) -- フラグ: `NYASH_OPERATOR_BOX_COMPARE=1` / `NYASH_OPERATOR_BOX_ADD=1` -- VMフック: - - Compare: `handle_compare` 内で `CompareOperator.apply(op,a,b)` を呼び出し(結果は無視・その後に通常比較)。 - - Add: `handle_binop`(Add) 内で `AddOperator.apply(a,b)` を呼び出し(結果は無視・その後に通常加算)。 -- Resolver: 上記フラグON時、自動で `apps/lib/std/operators/{compare,add}.nyash` をASTプレリュードに注入。 -- 受け入れ: 旗ONでも既存スモークの出力が一切変わらない(観測のみ)。 - -Operator Boxes — ALL 集約(dev・既定OFF) -- 目的: 算術/比較/単項演算を「箱」に統一。lowering は Builder の1箇所(ops.rs)に集約し、再入ガードで回帰を封じる。 -- 実装: - - Builder 置換フラグ: `NYASH_BUILDER_OPERATOR_BOX_ALL_CALL=1` - - `build_binary_op`/`build_unary_op` で `*Operator.apply` 呼びに置換 - - 再入ガード: 現在関数が `*Operator.apply/` で始まるときは従来 MIR にフォールバック - - メタ維持: 返り値型(Integer/String/Bool)を `value_types` に注釈 - - 実行採用フラグ(VM 側・必要時): `NYASH_OPERATOR_BOX_*` + `*_ADOPT` - - プレリュード注入(AST using 時): `NYASH_OPERATOR_BOX_ALL=1` または `NYASH_BUILDER_OPERATOR_BOX_ALL_CALL=1` で - - 注入対象: stringify / add / sub / mul / div / mod / compare / neg / not - - 除外: bitwise(& | ^ ~)と shift(<< >>)は現状パーサ未対応のため注入せず(従来BinOpを使用) -- dev プロファイル: `source tools/dev_env.sh opbox` - - 上記の Builder/VM フラグ一式と AST using をONにする。 -- スモーク: dev+AST+opbox で JSON(roundtrip/nested)PASS を確認(差分なし)。 -- 次アクション: - - quick 一巡(opbox)で Box trace を Compare/Json 系に絞って観測(Void/型逸脱の検知)。 - - パーサに ~ / << / >> を追加後、bitwise/shift も箱化に昇格。 - - 代表箇所の痩身(Trivial-PHI / Copy-prop / DCE)を順次適用(パフォーマンスは後追い)。 - -Next — Bitwise/Shift enablement(dev・既定OFF→旗でON) -- 目的: `~ << >> & | ^` をパーサ/ビルダー/プレリュードで通す(ALL フラグの網羅)。 -- 実装(完了): - - Tokenizer: `~` → `BitNot`、`<<` → `ShiftLeft`、`>>` → `ShiftRight` を受理(strict_12_7=0 時)。 - - Parser: 単項 `~x` を `UnaryOp(BitNot, x)` として構築。シフト/ビット演算は既存の `expr_parse_*` を使用。 - - Builder: `NYASH_BUILDER_OPERATOR_BOX_ALL_CALL=1` 下で `Shl/Shr/Bit(And|Or|Xor)` を `*Operator.apply` 呼びに集約。 - - Resolver: `NYASH_OPERATOR_BOX_ALL=1`(または ALL_CALL=1)時に `apps/lib/std/operators/{shl,shr,bitand,bitor,bitxor,bitnot}.nyash` を自動注入。 -- 受け入れ: - - `tools/opbox-json.sh` / `tools/opbox-quick.sh` が dev で PASS(差分ゼロ)。 - - サンプル: `return ~1 & 3 | 8 ^ 1 << 2 >> 1` が VM 実行可能(dev)。 - - 回帰なし(従来コードに挙動変化なし、旗OFF時は完全非介入)。 - -Using duplicate detection — 完了 -- 目的: 同一ファイルの二重 import や alias の再バインドを入口で禁止し、AST/解決の曖昧さを根絶。 -- 実装: `collect_using_and_strip` に重複検出を追加(canonical path / alias 単位、行番号つきエラー)。 -- エラーメッセージ例: - - `using: duplicate import of '' at file.nyash:12 (previous alias: 'X' first seen at line 5)` - - `using: alias 'X' rebound at file.nyash:20 (was '' first seen at line 7)` -- 既定: 全プロファイルでエラー(許容フラグは撤廃)。 - -Today’s update(2025‑09‑27 pm) -- LoopForm if 入口の PHI 入力を pre_if スナップショット参照に固定(then/else の相互汚染を禁止)。 -- if トレース追加(`NYASH_IF_TRACE=1`): then/else 入口PHI・合流PHIの var/pre/dst/preds を可視化。 -- VM InstanceBox dispatcher 強化(BoxCall→関数): - - 候補順: `Class.method/Arity` → `ClassInstance.method/Arity` → `Class.method/(Arity+1)` → 一意な「`.method/Arity`」末尾一致。 - - `toString/0` → `stringify/0` 特別フォールバック。 - - 追跡ログ: `NYASH_VM_TRACE=1` で候補・命中名を出力。 -- JsonScanner のフィールド getField 補強(内部が Null/None の場合に開発用デフォルトを適用)。 -- ビルダー側のインスタンス書き換えは既定OFF、検証時のみ `NYASH_BUILDER_REWRITE_INSTANCE=1` で有効化。 - -追加の微修正(2025‑09‑27 late) -- JsonParser.parse/1 の戻り型を安定化(Builder 注釈) - - `annotate_call_result_from_func_name` に特例を追加し、署名が Unknown/Void の場合でも `MirType::Box("JsonNode")` を付与。 - - 署名が取得できない場合も最小ヒューリスティックで同注釈を適用(Builder DEBUG ログ対応)。 -- VM InstanceBox ディスパッチの一意尻一致フォールバックをナローイング - - 多候補時は受け手クラス接頭(`.`/`Instance.`)で再絞り込み、1件ならヒットとする。 - - `NYASH_VM_TRACE=1` でナローイング経路をログ出力。 - -微修正(2025‑09‑27 late‑late) -- VM: `length` 呼出しのディスパッチ簡易ログを追加(`NYASH_VM_TRACE=1` 時のみ) - - 受け手型の表示と、命中したハンドラ(object_fields / instance_box / string_box / array_box / map_box / fallback)を出力。 - - 目的: Compare(Lt) 直前で RHS が Void になる事象の切り分け(どの経路で 0/未定義になっているか)。 -- Builder: メソッド呼出しの受け手(receiver)を追加で pin(`@recv`)。 - - `handle_standard_method_call` の先頭で `pin_to_slot` を適用し、条件式内での分岐横断利用でも定義点が安定するよう補強。 - -今日の追加(2025‑09‑27 night) -- quick 緑化(json_pp) - - スモーク修正: `NYASH_VM_TOLERATE_VOID=1` のエクスポート順を実行前に移動(効果が出るように)。 - - VM 出力安定化: print/console 出力で `BoxRef(VoidBox)` を `null` として出力(`src/backend/mir_interpreter/handlers/{calls,externals}.rs`)。 - - String 操作の拡充: `String.indexOf(substr)` を VM に実装(`calls.rs` と `boxes_string.rs`)。 - - json_pp 本体: MVP では `JsonNode.parse` を利用する軽量経路に切替(AST パーサ全経路の安定化は継続事項)。 - - JsonNode: `parse` に浮動小数と単一キーの簡易 Object を追加(テスト用・小差分、仕様拡張なし)。 - - 結果: `tools/smokes/v2/profiles/quick/apps/json_pp_vm.sh` が PASS。 - -未了/次の一手 -- json_lint は引き続き `JsonScanner.current()` で VM fallback が稀に漏れる(BoxCall unsupported)。 - - 対策案: InstanceBox→関数ディスパッチの優先度を toString 同様に `is_*` 系にも適用、birth 明示発行で未初期化フィールドを根本排除。 - - 暫定回避: json_lint を `JsonNode.parse` ベースの軽量 linter に一時切替(dev のみ)→ 安定後に戻す。 - -ホットフィックス(2025‑09‑26 14:47) -- Builder: `pin_to_slot` でメタ情報を伝播(型と起源の保持) - - `value_types` と `value_origin_newbox` を新しい ValueId にコピーするよう修正。 - - 目的: pin/PHI を跨いでも受け手クラスや推論型が失われず、メソッド→関数書き換えや BoxCall の解決が安定。 - - 影響範囲: `src/mir/builder/utils.rs` のみ。仕様不変・安全。 - - 受け入れ: JSON VM の比較/フィールド読みで Void 型が混ざる頻度の低下、メソッド解決ログの一貫化。 - -暫定ガード計画(dev限定・ナロー適用) -- 目的: JsonScanner.is_eof()/current()/advance() 文脈で legacy 経路から Void が比較に漏れるのを最小限の安全弁で抑止する(診断継続用)。 -- 実装: VM getField の最終フォールバックを「関数文脈+フィールド名+環境フラグ」で限定適用 - - 関数文脈: `cur_fn ∈ {JsonScanner.is_eof/0, JsonScanner.current/0, JsonScanner.advance/0}` - - フィールド名: `position|length|line|column|text` - - フラグ: `NYASH_VM_SCANNER_DEFAULTS=1`(既定OFF) - - ログ: `NYASH_VM_TRACE=1` で `[vm-trace] getField final_default -> ` を出力 - - ファイル: `src/backend/mir_interpreter/handlers/boxes.rs`(legacy 経路 Void の最終分岐) - -恒久策(順次適用) -1) Constructor→birth の明示発行(Builder) - - `NewBox` 直後に `birth()` を MIR で明示生成(該当 Box に birth がある場合)。 - - 影響: VM 側の自動 birth 依存を排し、未初期化フィールド混入を構造的に防止。 - - 候補: `src/mir/builder/builder_calls.rs`(Constructor 経路)または `definitions/call_unified.rs`。 -2) Loop‑Form/diamond 検証の dev 既定化 - - `NYASH_LOOP_TRACE=1 NYASH_VM_VERIFY_MIR=1` を dev プロファイルで常時ON(smokes) - - φ 不変(入口φ、pred一致、use前定義)違反の早期検知→pin/φ 追加で局所修正。 -3) 書き換え封鎖の維持 - - 関数側「尾一致」既定OFFを維持、受け手クラス未知時の rewrite は不採用。 - -受け入れ基準(今回スライス) -- dev+AST + `NYASH_VM_SCANNER_DEFAULTS=1` で `json_roundtrip_vm.sh` が PASS(Void 比較エラーが消える)。 -- `NYASH_VM_TRACE=1` で最終フォールバック適用ログが限定箇所のみに出る(濫用なし)。 -- 以後、Constructor→birth 明示発行の導入後に同スモークがフラグ無しでも PASS(暫定ガードを既定OFF→撤去可能)。 - -デバッグ統一(観測の一本化・混入防止) -- 観測は JSON Lines(stderr)に統一し、既定OFF(環境ON時のみ)。 -- `NYASH_BOX_TRACE=1` / `NYASH_BOX_TRACE_FILTER=` で new/call/get/set を JSON 出力。 -- smokes 側で `^[vm-trace]` と `^{"ev":` をフィルタ(比較汚染を防止)。 -- 受け入れ: 観測ONでも比較が乱れない(stderr→除外)。 - -Print 追跡(dev限定・ON時のみ) -- 目的: FAIL時に print の実引数(種別/クラス)を即把握する。 -- フラグ: `NYASH_PRINT_TRACE=1` -- 出力: `{ "ev":"print", "kind":"Integer|String|BoxRef|...", "class":"JsonScanner|...|" }` -- 実装: `src/backend/mir_interpreter/helpers.rs`(emit) + `handlers/calls.rs`(print前にemit) -- 受け入れ: 例外系ケースで print の引数が BoxRef(JsonScanner/JsonToken) となるか否かを一行で判別可能。 - -封じ込め(2025‑09‑27 night) -- 関数側 tail 一意解決を既定OFF(`NYASH_BUILDER_TAIL_RESOLVE=1` でのみ有効化) -- me.method() を囲み Box 名で優先バインド(曖昧関数化の抑止) -- 戻り型注釈の追加: - - `JsonParser.current_token/0` → `Box(JsonToken)` - - `JsonTokenizer.tokenize/0` → `Box(ArrayBox)` -- VM 狭域ガード:JsonParser.length → tokens.length() ブリッジ(開発用) -- VM 受信時の JsonScanner デフォルト注入(開発用) - -スモーク(抜粋) -- `json_nested_vm.sh` は PASS(dev+AST) -- `json_roundtrip_vm.sh` は FAIL(Ge on Void, Void)→ is_eof で position/length の Void が混入 - -次のアクション(WIP 計画) -1) getField 最終安全弁の狭域強化(呼び出し元関数が `JsonScanner.is_eof/0` の場合に position/length を補う) -2) 追加の注釈と pin/PHI を Builder に最小追加(merge 直前の Undefined を撲滅) -3) 緑化後、VM 狭域ブリッジ(JsonParser.length/JsonScanner デフォルト)を撤去 - -最小再現ドライバ(追跡用) -- 追加: `tmp/json_rt_null_vm.nyash`(JSON null のVMラウンドトリップ) -- 追加: `tmp/json_scanner_is_eof_min.nyash`(Scanner 単体で `is_eof` 経路を観測) - -本日後半 — Builder 書き換えの既定(dev/ci) -- 変更: MirBuilder のインスタンス→関数書き換えを dev/ci プロファイルで既定ON、prodは既定OFFのまま。 - - 明示オーバーライド: `NYASH_BUILDER_REWRITE_INSTANCE={1|true|on}` で強制ON、`{0|false|off}` で強制OFF。 - - 実装: `src/mir/builder/method_call_handlers.rs` 内の `rewrite_enabled` 判定を `using_profile` に連動させた。 - - 目的: VM 側の JsonNodeInstance 狭域ブリッジ撤去に向けた段階移行。既定挙動(prod)は不変。 - - 観測: `arithmetic_ops` は PASS。JSON VM 系は従前の失敗が残存(今回の切替による悪化は未観測)。 - -続き — VM 狭域ブリッジ(JsonNodeInstance)の撤去(第一弾) -- 変更: `try_handle_instance_box` から JsonNodeInstance 固有の分岐(`array_push/array_size/object_{get,set,keys}`)を削除。 - - File: `src/backend/mir_interpreter/handlers/boxes.rs`(約 527 行〜) - - 依存: Builder のインスタンス→関数書き換え既定ON(dev/ci)+ VM 側の汎用インスタンスディスパッチで代替。 - - birth の no-op は維持(Builder が明示生成する birth 呼び出しの互換保険)。 -- 結果: `json_roundtrip_vm.sh` / `json_nested_vm.sh` は PASS を維持(dev+AST)。 -- 次: quick を通しで再確認 → 問題なければ stringify/unique-tail のナローイング経路のログも静音(filter側)→ 残るVM特例を段階撤去。 - -SSOT 徹底 — file using を全プロファイル既定禁止(パッケージ内のみ許容) -- 変更: `src/config/env.rs::allow_using_file()` をデフォルト false に(明示オーバーライドのみ true)。 -- 変更: `collect_using_and_strip()` に「パッケージ内ソースの内部 file-using は許容」の例外を追加(package root 配下のファイルに限る)。 - - 効果: メイン/アプリ側は必ず `nyash.toml` の packages/aliases 経由で参照。パッケージ実装内部は相対/明示パスで自己構成可能。 -- スモーク更新: - - `using_profiles_ast.sh`: dev でも file-using 禁止を期待に変更。 - - `using_relative_file_ast.sh`: 相対パス → alias 参照に変更(パッケージ相対)。 -- LLVM 経路: `runner/modes/llvm.rs` に AST using 処理と PyVM フォールバック(SMOKES_USE_PYVM=1)を追加。 -- 既知: VM quick の JSON ラインで "Integer vs Void" 比較が再発(サンプルループの `length()` が Void になるケース)。LoopForm/IF の構造は維持済みで、ArrayBox の `length` 実装は存在。次のデバッグで Compare 発生点(length の解決経路)をトレースして原因を特定する。 - -リファクタリング計画(ふるまい不変・段階) -- 目的: 追跡容易化とソース整頓(根治パッチの前段)。挙動は変えない。 -- ステップ: - 1) VM handlers の分割(boxes.rs の肥大解消) - - 抽出: `try_handle_array_box` / `try_handle_string_box` / `try_handle_map_box` を個別ファイルへ。 - - 影響: 関数名・シグネチャは不変。呼び出し元(handle_box_call)は変更なし。 - 2) getField 既定(JsonScanner の最終フォールバック)を専用箇所に集約(現状ロジックは不変)。 - 3) トレース整備: compare 失敗ログに関数名/ブロック/最後の命令を出力済み。length 呼出し経路の型ログを追加予定。 -- 受け入れ: quick が従前と同等(現状の赤は赤のまま)。差分は構造とログのみ。 - -直近の受け入れ確認(要再実行) -- 単体ドライバ: `r = JsonParser().parse("{\"a\":1}"); print(r.toString())` が `JsonNode.stringify/0` に命中(VM トレースで確認)。 -- v2 quick: `NYASH_USING_PROFILE=dev NYASH_USING_AST=1 bash tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` が完走。 - -Resolved — Integer stringify shortens (42 → 4) -- Symptom: In JSON VM quick, the integer sample "42" prints as "4" while other types (null/bool/float/array/object) stringify correctly. -- Hypotheses: - - Value truncation during convert_number → create_int flow, or parse_integer returns incorrect value in some path. - - Field bridging is not the culprit (InstanceBox getField/setField already maps NyashValue::Integer i64 correctly), but will confirm via trace. -Fix (2025‑09‑27): -- Root cause: StringUtils.parse_integer parsed only the first digit; multi-digit accumulation was incorrect. -- Patch: Rewrote per‑digit loop using an index_of lookup over "0123456789" and `acc = acc * 10 + d`; kept sign handling and integer validation. -- Also unified stringify(int) on both static/instance JsonNode to use `me.value.toString()`. -- Result: Minimal drivers A/B now print "42"; `json_roundtrip_vm` passes under dev+AST. - -Open item — json_nested_vm (VM) fails (debug in progress) -- Symptom (quick/core/json_nested_vm.sh): - - Expected: `[1,[2,3],{"x":[4]}]`, `{\"a\":{\"b\":[1,2]},\"c\":\"d\"}`, `{\"n\":-1e-3,\"z\":0.0}` - - Actual: `null` for all three samples under VM path (AST counterparts pass) -- Notes: - - Earlier, a stray semicolon at block endings triggered a tokenizer parse error. For smoke stability only, we added a dev-only ASI-like strip in test_runner to remove trailing `;` before VM run (SMOKES_ASI_STRIP_SEMI=1 default). After that, error turns into `null` results => true parse failures remain. - - AST-based tests for nested JSON pass; issue is specific to VM execution path for nested structures. -- Hypotheses: - 1) Number tokenization edge (exponent + sign: `-1e-3`, `0.0`) in VM path. - 2) Nested object/array boundary handling (Tokenizer.read_string_literal / read_number / structural tokens) differs under VM fallback. - 3) validate_number_format too strict in VM path relative to AST expectations. -- Plan (do not force green; debug methodically): - 1) Repro with diagnostic driver printing parser errors per sample (`p.print_errors()`). - 2) Enable targeted traces: `NYASH_VM_TRACE=1`, optional tokenizer-local prints if needed. - 3) Inspect JsonTokenizer.read_number and validate_number_format for exponent and decimal handling; align with AST behavior. - -Fix (2025-09-27): VM method-dispatch fallback narrowing -- Root cause: VM dynamic fallback resolved `.is_eof/0` by unique tail across all boxes and accidentally picked `JsonScanner.is_eof/0` when receiver was a `JsonToken`, leading to `Ge` on `Void` (position/length unresolved) under certain flows. -- Patch: Restrict unique-tail fallback candidates by receiver's class name when available (InstanceBox.class_name). Only resolve when a single candidate within the receiver's class remains. -- File: `src/backend/mir_interpreter/handlers/boxes.rs` (handle_box_call) -- Result: `json_roundtrip_vm` PASS under quick/dev; `json_nested_vm` already PASS. - 4) Fix narrowly (number validation or structural token sequence) and re-run only json_nested_vm; then re-run quick profile. -- Acceptance: - - json_nested_vm prints expected three lines; no other quick tests regress. - -現状観測(after fixes) -- 未定義PHIは解消。`r.toString()` 出力が `JsonNodeInstance()` のまま残るケースあり。 -- `object_set` 呼び出しも VM 側で動的解決の一意尻一致フォールバックを追加済みだが、引っかからないケースがある(受け値の型/起源が落ちている可能性)。 - -JSON VM 根治(WIP) -- 症状: `json_roundtrip_vm`(VM fallback)が `TypeError: unsupported compare ... on Void` で停止(以前は `Integer vs Void`、現在は `Void vs Void` まで改善)。 -- 原因(一次): ユーザー Box のフィールドが VM 側の外部マップ(obj_fields)に保存され、インスタンス同一性の継ぎ目で取りこぼすことがある。 -- 施した修正(最小・仕様不変): - - VM インタープリタ `getField/setField` を優先的に `InstanceBox` の内部フィールド(`fields_ng: NyashValue`)へ委譲。 - - NyashValue ↔ VMValue の最小ブリッジを実装(数値/真偽/文字列/Null→Void)。 - - dev 導線: `NYASH_VM_VERIFY_MIR=1` で VM fallback 前に関数単位の MIR 検証(`MirVerifier.verify_function`)を走らせてヒントを出力。 -- 現状の観測: - - `JsonScanner.birth` による `length/line/column/position` 初期化は安定(min 再現で確認)。 - - `json_roundtrip_vm` は別箇所(比較)で Void が混入。未初期化フィールド(Null→Void)または merge 付近の値流れの可能性。 -- 次の対処(局所・点修正で緑化): - 1) Verifier ログで該当関数の merge/支配関係違反を特定(dev 環境のみ)。 - 2) 比較/条件構築のピン不足箇所に `ensure_slotified_for_use` を追加(漏れ潰し)。 - 3) CompareOperator.apply に arg 種別を出すトレースを導入済み(観測)。Void 混入箇所の前後で get/set を確認して原因を一点化。 - 3) 必要なら「スキャナの数値系フィールド」の既定値(0/1)を dev フラグ下で補う(`NYASH_VM_SCANNER_DEFAULTS=1` 追加検討)。 - 4) 緑化後に dev 安全弁(Void 許容)を撤去/既定 OFF 固定。 -− 受け入れ: `tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` が dev/prod(AST using)で緑。 - -追加タスク(インスタンス呼び出しの最終詰め) -- 目的: `JsonNode.stringify/0` / `JsonNode.object_set/2` などが確実に関数呼びに正規化され、`JsonNodeInstance()` 表示が JSON 文字列へ置換されること。 -- 手順(診断→修正の順): - 1) 単体ドライバでトレース取得: - - 実行: `NYASH_VM_TRACE=1 NYASH_BUILDER_REWRITE_INSTANCE=1` で `instance-dispatch class=... method=toString/0` 等の候補/命中ログを確認。 - - 関数表: `NYASH_DUMP_FUNCS=1`(vm_fallback)で `JsonNode.stringify/0` / `JsonNode.object_set/2` の存在確認。 - 2) 命中しない場合: - - `handle_box_call` で `recv` の型名(`recv_box.type_name()`)をログ出し、InstanceBox 判定漏れを特定。 - - 末尾一致の一意解決が多候補なら、`JsonNode` 系に限定するナローイングを追加。 - 3) 緑化確認: `json_roundtrip_vm.sh` が期待出力に一致。 - -受け入れ基準(今回のスライス) -- if/LoopForm の入口PHIが常に pre_if スナップショットから生成される(`NYASH_IF_TRACE=1` で確認)。 -- `json_roundtrip_vm` が VM で完走し、 `JsonNodeInstance()` ではなく JSON 文字列を出力。 -- VM トレースで `instance-dispatch hit -> JsonNode.stringify/0` 等の命中が確認できる。 - -根治テーマ(新規) — birth 呼び出しの責務分離と生成位置の是正 - -問題の本質(層の責務分離違反) - -- 現状(暫定パッチ): - - VM 実行器が `NewBox` 実行時に自動で `birth` を探して呼び出す(`handle_new_box` 内で `Class.birth[/Arity]` を探索・実行)。 - - 目的はユーザー Box の初期化だが、これは本来コンパイラ(MIR ビルダー)の責務。 -- 正しい設計: - - using 層/コンパイラが `new MyBox(args)` を MIR へ明示展開する。 - - 期待する MIR 例: - - `dst = NewBox MyBox(args...)` - - `Call { callee = Global("MyBox.birth/N"), args = [dst, args...] }` - - 以後 `dst` を使用 - - VM 実行器は MIR を忠実に実行するだけ(自動 birth 呼び出しは不要)。 -- リスク(現状パッチの副作用): - - 層を跨いだ肩代わりで制御不能(無限再帰/二重初期化/順序依存の温床)。 - - デバッグ困難化(birth 呼び出しが MIR に現れない)。 - -方針(根治) - -1) MIR ビルダー側で `new` の正規展開を実装(birth 明示呼び出しの生成) - - 対象: `ASTNode::New`(既存の new ノード)または同等の生成箇所。 - - 生成: - - `dst = NewBox (args...)` - - 存在する場合: `Call Global(".birth/N"), argv = [dst, args...]` - - birth 不存在時は Call を省略(既存互換)。 - - 併せて、ユーザー定義メソッドの関数名規約 `./` に統一し、birth 検索も同規約で行う。 - -2) VM 実行器の自動 birth 呼び出しを段階的に撤去 - - Step‑A(即時): dev フラグで既定 OFF(`NYASH_VM_AUTO_BIRTH=0` 既定)。 - - Step‑B(ビルダー実装安定後): 自動呼び出しコードを削除。 - -3) 付随の整合 - - 静的名→インスタンス別名(`JsonNode` → `JsonNodeInstance`)の alias は vm_fallback の簡易ファクトリで保持(当面)。 - - 将来は宣言解析で静的/インスタンスの関連付けを明示して alias 依存を解消。 - -テスト計画 / 受け入れ条件 - -- MIR 生成の確認: - - `--dump-mir`/`NYASH_VM_TRACE=1` で `NewBox ` の直後に `Call .birth/N` が現れる。 - - VM 実行ログからは `handle_new_box` 内での自動 birth 呼び出しが消えている(実行器は NewBox のみ)。 -- 機能スモーク: - - `json_roundtrip_vm` が dev/prod(AST using)で完走。少なくとも null/bool/int/string の基本ケースが期待出力。 - - `new JsonParser()` などのユーザー Box 生成で未初期化フィールド由来の Void 混入が再発しない。 -- 回帰抑止: - - birth 不存在な Box でも従来通り動作(Call を生成しない)。 - -作業ステップ(詳細) - -1) Builder: `new` 正規展開 - - ファイル: `src/mir/builder/exprs.rs`(`ASTNode::New` 分岐)、必要なら専用モジュール。 - - 実装: NewBox emit → `module.functions` で `.birth/N` を探索 → あれば Global Call emit(先頭 arg に me=dst)。 - - 備考: 既存の「メソッド→関数」低下 (`lower_method_as_function`) の規約に合わせる。 - -2) VM: 自動 birth を dev 既定 OFF に変更 → 後で削除 - - ファイル: `src/backend/mir_interpreter/handlers/boxes.rs`(`handle_new_box`)。 - - Step‑A: `if env(NYASH_VM_AUTO_BIRTH)==1 のみ` birth を試行(既定 0)。 - - Step‑B: Builder 安定後に完全削除。 - -3) スモーク/検証の整備 - - 新規: mini birth 展開テスト(`new Box(x);` で `NewBox`→`Call birth` が生成されるか)。 - - 既存: `json_roundtrip_vm` / `mini_call_starts_with` を AST using(dev/prod)で確認。 - -リスクとロールバック - -- 万一 Builder 実装で birth が生成されない場合でも、dev では env=1 で VM 自動 birth を一時的に再有効化可能。 -- ただし最終到達点は VM 自動 birth の完全撤去。CURRENT_TASK で管理し段階的に外す。 - -MIR/VM 進捗(SSA/短絡/ユーザーBox) -- 短絡(&&/||): 分岐+PHI で正規低下(RHS 未評価)を実装済み。 -- 比較オペランド: その場 `pin_to_slot` で slot 化、PHI 参加(支配関係破れの根治策)。 -- ブロック入口: then/else/短絡入口に単一 pred PHI を配置(局所定義を保証)。 -- ユーザーBox呼び出し(VM fallback): - - Builder 側: user‑defined Box のインスタンスメソッドは `Box.method/Arity` 関数へ書き換え('me' 先頭引数、関数名の Arity は 'me' を含めない)。 - - VM 側: BoxCall で InstanceBox を受けた場合、存在すれば `Box.method/Arity` に動的フォールバック実行('me'+args を渡す)。 - -現状の未解決(再現あり) -- JSON VM quick が `BoxCall unsupported on VoidBox.current` で停止。 - - トレース: `JsonTokenizer.next_token` 内で `me.scanner.current()` が BoxCall 経路に残存。 - - 期待: Builder が user‑defined `JsonScanner` を検知して `JsonScanner.current/0` へ書き換えるか、VM が fallback で補足。 - - 観測: 関数一覧に `JsonScanner.current/0` が存在しないケースがある(環境差/順序の可能性)。 - - 以前の実行では `JsonScanner.current/0` が列挙されていたため、低下順または条件分岐の取りこぼしが疑わしい。 - -## 方向修正(複雑性の抑制と安定化) — 2025‑09‑27 - -- 遅延注釈・保険フック・VM 側の大改造は一旦見送り、シンプルな導線で解消する。 -- 根治の順序: - 1) Resolver 強化(nested using を DFS で AST 事前ロード) - 2) 低下順の一貫化(宣言インデックス後に関数群が常に materialize) - 3) 書き換えは「関数存在」の一点で採否(既に実装済み) - 4) 必要箇所のみ Loop‑Form(Builder 側、flag 付き) - -ロールバック(安定化のため) - - VM インタプリタの一時変更は元に戻す: - - obj_fields のキー安定化(Arc ptr ベース)を撤回し、暫定的に従来挙動へ復帰。 - ---- - -Update — LLVM Parity & Dev Guards Tightening(2025‑09‑27 end) - -今日の完成点(要約) -- quick JSON(json_pp / json_lint)を VM で緑化し、print/compare/Node 正規化まわりを安定化。 -- Operator Boxes は「観測(observe)常時ON」基盤を整備(挙動不変)。 -- using は SSOT(nyash.toml)+AST マージを dev 既定に、prod は toml のみ許容を維持。 -- VM fallback は受信クラス接頭で一意絞り込み、誤命中(JsonToken/JsonScanner)を根治。 - -次のタスク(この順で進める) -1) LLVM parity を実行して差分ゼロを確認(--dev) - - 対象スクリプト(例): - - tools/smokes/v2/profiles/integration/apps/json_pp_vm_llvm.sh - - tools/smokes/v2/profiles/integration/apps/json_lint_vm_llvm.sh - - tools/smokes/v2/profiles/integration/parity/method_resolution_is_eof_vm_llvm.sh - - 期待: 出力差分ゼロ(LLVM 未構築環境では SKIP)。 -2) dev 限定ガードの範囲を締める(仕様不変・段階撤去前提) - - Compare の最終安全弁(Void 許容)は `NYASH_DEV=1` 時のみ有効に限定。 - - `BoxRef(VoidBox)`→`Void/null` の正規化は dev でのみ緩和、prod は従来の厳密型チェックを維持。 - - InstanceBox.current の汎用フォールバックは命中ゼロを確認後、dev 限定→削除の順で縮退。 - - quick の JSON スモークから一時的な `NYASH_VM_TOLERATE_VOID=1` を段階撤去(--dev 既定で内包後)。 - -実行状況(ビルドと現状の観測) -- LLVM 18 検出: `llvm-config-18` = /usr/bin/llvm-config-18(18.1.3) -- ビルド: OK - - `cargo build --release -p nyash-llvm-compiler` - - `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) cargo build --release --features "llvm llvm-harness"` -- パリティ実行(直叩き): - - VM: apps/examples/json_pp/main.nyash → 期待出力(14行) - - LLVM harness: `NYASH_LLVM_USE_HARNESS=1` 実行で IR パースエラー(llvmlite) - - 例: `:523:1: error: expected instruction opcode` / `:99:1: ... bb2346:` - - セーフティバルブ `NYASH_LLVM_SANITIZE_EMPTY_PHI=1` でも未解消(bbヘッダ近傍の整形要) -- 対応方針: harness の PHI 整形/配置を先に直してから parity を正式実行(下記TODO)。 - -LLVM harness TODO(小さく可逆) -- src/llvm_py/builders/function_lower.py: `finalize_phis` の配置ルール再確認(ブロック先頭グループ化) -- src/llvm_py/builders/block_lower.py: ループ/if での PHI プレ宣言メタの扱い(空PHI抑止) -- Harness 文字列整形: `bb:` 直後に命令が無いケースを検知し、ダミー `;` ではなく `br label %bb` 等の合法命令に置換(暫定) - -ハーネス修正(実装済み・小差分) -- Terminator保証パス: 末尾に終端命令が無い基本ブロックに `br` もしくは `ret 0` を注入(bring-up向け安全弁)。 - - File: `src/llvm_py/builders/function_lower.py`(`_enforce_terminators`) -- 空PHIサニタイズ: ハーネス使用時(`NYASH_LLVM_USE_HARNESS=1`)は incoming なしの PHI を自動削除。 - - File: `src/llvm_py/llvm_builder.py`(sanitize 既定ON when harness) -- UnaryOp 低下: `unop {kind: not|neg|bitnot}` を実装(i1反転/0- x/bitwise xor -1)。 - - File: `src/llvm_py/instructions/unop.py`、`builders/instruction_lower.py` -- メソッド関数の arity 修正: `Class.method/N` は `len(params)` を arity に採用(`me`を含める)。 - - File: `src/llvm_py/llvm_builder.py`(predeclare時のarities) -- 既知プレディケート stub: `condition_fn` のボディ未定義時に i64 1 を返す最小定義を注入(リンク回避)。 - - File: `src/llvm_py/instructions/call.py` -- ランナー: ハーネス実行の標準出力を前方出力(パリティ比較に使用)。 - - File: `src/runner/modes/common_util/exec.rs`, `src/runner/modes/llvm.rs` -- スモークフィルタ: `✅/📊` ノイズを除去して純粋な出力のみ比較。 - - File: `tools/smokes/v2/lib/test_runner.sh` - -パリティ結果(dev) -- apps/json_pp_vm_llvm.sh → PASS(VM=LLVM、差分ゼロ) -- apps/json_lint_vm_llvm.sh → PASS(VM=LLVM、差分ゼロ) -- 備考: json_query は後続(Node 正規化の収束後に追加) - -quick 緑化(VM側の最小フォールバック) -- InstanceBox.current の最終手当(開発限定・仕様不変) - - `current()` が未ディスパッチ時は空文字を返すフォールバック(JsonScanner系の読み取りで停止しない) - - File: `src/backend/mir_interpreter/handlers/boxes.rs` -- VoidBox のコンテナ系メソッドを安全化 - - `object_get/array_get/toString`→ null、`array_size/length/size`→0、`object_set/array_push/set`→no-op - - File: 同上 -- 結果: quick の `apps/json_lint_vm.sh` が PASS(--dev) -- 既知: `apps/json_query_vm.sh` は still FAIL(void 出力)→ Node 正規化/アプリ側の ensure を Node 内へ完全移譲した上で再検証。 - -受け入れ基準 -- integration(LLVM parity)が --dev で差分ゼロ。 -- quick(VM)緑維持。prod では挙動不変(ガードは無効)。 -- ガード縮退後も JSON apps(pp/lint/query)が安定して PASS。 - -ロールバック方針 -- Compare 安全弁/print 正規化/Instance フォールバックは個別フラグで即無効化可能(dev のみ)。 -- LLVM parity で差分が出た場合は差分ログを CURRENT_TASK に追記して原因箇所へ局所パッチ(Builder/VM いずれか)。 - - - host_api の BoxRef → NyashValue 変換や戻り値の挙動変更は撤回(既定の最小仕様に戻す)。 - - 目的は無限ループ/非停止の芽を確実に摘むこと(後段の Resolver 強化で書き換えが安定すれば、ここを再度検討可能)。 - -次のステップ(最小) -1) 上記ロールバックを反映して quick/core JSON を再実行(ハングがないことの確認)。 -2) Resolver: using 先の再帰(nested)を DFS で事前 AST 化し、その結果を `index_declarations` 前に連結。 -3) `NYASH_DUMP_FUNCS=1` で `JsonScanner.current/0` の存在、`NYASH_BUILDER_DEBUG=1` で user‑box 書き換え採用ログを確認。 -4) json_roundtrip_vm を再実行。完走したら、VM 側の臨時ガードや余計な保険を段階的に外す。 - -受け入れ条件(このスライス) -- nested using の AST 事前ロードにより依存関数が常に materialize。 -- user‑box 書き換えは「関数存在」の一点で採否(ブレなし)。 -- json_roundtrip_vm が完走(無限ループなし)。 -- 遅延注釈・保険フックなどの複雑化を増やしていない。 - -## 根治戦略(確定方針) - -結論: -- 制御フロー/SSA の根治は Option‑B(Loop‑Form 導入)が本命。 -- ただし今回の「起源未伝搬→書き換え不発」は依存解決/宣言順の問題が主因のため、まず Resolver 側を確立し、その上で Loop‑Form を段階導入する。 - -進め方(順序) -1) Resolver 根治(小規模・点修正) — ✅ 2025‑09‑27 実装済み - - `resolve_prelude_paths_profiled` を canonicalize+DFS 化し、common/vm_fallback 両経路で採用。 - - nested using も AST 事前ロードに含まれるよう整理済み(書き換えは既存の「関数存在」基準を継続)。 -2) Loop‑Form(PHI根治) — ✅ 2025‑09‑27 既定経路へ切替 - - 低下経路を loop_api(簡易) から LoopBuilder(正規形: preheader→header(φ)→body→latch→exit)に統一。 - - 変更: `src/mir/builder_modularized/control_flow.rs::build_loop_statement` を `self.cf_loop(..)` に切替。 - - 既存の `src/mir/loop_builder.rs` + `mir/phi_core/loop_phi.rs` の φ 生成/封止を活用(continue/break の取り込みと latch wiring を保証)。 - - 目的: SSA 支配関係の事故・未定義参照・分岐合流のゆらぎを構造的に排除。 - -受け入れ条件(Loop‑Form スライス) -- 代表ループ(tokenizer/scanner の while)で header φ が生成され、continue/break が latch/exit に束ねられていること(`--dump-mir` で確認)。 -- json_roundtrip_vm(VM fallback)で未定義参照・無限ループが再発しない(既存の短絡/if の diamond と整合)。 -- フラグ OFF 時は従来どおり(既定挙動は変えない)。 - -## ADR 受理: No CoreBox & Everything is Plugin(Provider/Type 分離) - -- CoreBox は戻さない。Kernel は最小(GC/Handle/TLV/Extern/PluginRegistry/ABI)。 -- 型名(STN: `StringBox` 等)は不変、実装提供者(PVN)は TOML で切替。 -- 起動は「Kernel init → plugins.bootstrap/static + plugins.dynamic → Verify → 実行」。 -- VM/LLVM は `ny_new_box` / `ny_call_method` に統一(段階導入)。 -- ADR: docs/development/adr/adr-001-no-corebox-everything-is-plugin.md を追加。 - -受け口フェーズ(挙動不変) -- K0: ADR/Docs 追加(完了)。 -- K1: TOML スキーマ雛形(types/providers/policy)受け口(後続)。 -- K2: Provider 解決ログの受け口(後続)。 -- K3: Verify フック(preflight_plugins)受け口(後続)。 -- K4: Bootstrap Pack 登録導線(prod限定フラグ; 後続)。 - -## Using / Resolver — “Best of Both” Decision(2025‑09‑26) - -合意(いいとこどり) -- 依存の唯一の真実(SSOT)を `nyash.toml` `[using]` に集約(aliases/packages/paths)。 -- 実体の合成は AST マージに一本化(テキスト結合・括弧補正の互換シムは段階的に削除)。 -- プロファイル導入で段階移行: `NYASH_USING_PROFILE={dev|ci|prod}` - - dev: toml + ファイル内 using/path を許可。診断ON、限定的フォールバックON。 - - ci: toml 優先。ファイル using は警告/限定許可。フォールバックOFF。 - - prod: toml のみ。ファイル using/path はエラー(toml 追記ガイドを表示)。 - -やること(仕様不変・既定OFFで段階導入) -1) ドキュメント - - [x] `docs/reference/language/using.md` に SSOT+AST/Profiles/Smokes を追記。 - - [x] ADR を追加(No CoreBox / Provider 分離) -2) Resolver 統合 - - [x] vm_fallback に AST プレリュード統合を導入(common と同形)。 - - [x] prod での `using "path"`/未知 alias はエラー(修正ガイド付)。 - - [x] prelude 決定(toml優先/プロファイル対応)の共通ヘルパを新設し、呼び出し側を一元化(`resolve_prelude_paths_profiled`)。 -3) レガシー削除計画 - - [x] prod でテキスト結合(combiner)/括弧補正を禁止(ガイド表示)。 - - [ ] dev/ci でも段階的に無効化 → parity 緑後に完全削除。 -4) パーサ堅牢化(必要時の安全弁、NYASH_PARSER_METHOD_BODY_STRICT=1) - - [x] メソッド本体用ガードを実装(env で opt-in)。 - - [x] Guard 条件をトップレベル限定かつ `}` 直後のみ発火に調整(誤検知回避)。 - - [ ] `apps/lib/json_native/utils/string.nyash` で stray FunctionCall 消滅確認。 - -## シンプル化ロードマップ(claude code 提案の順) - -1) VM fallback 強化(mini 緑化) - - [x] レガシー解決の正規化(Box.method/Arity) - - [x] 文字列の最小メソッド(substring 等)暫定実装(短期・撤去予定) -2) dev/ci で AST 既定ON(prodはSSOTを維持) - - [ ] 既定値切替とスモーク緑確認 -3) レガシー using 経路の段階削除 - - [x] 呼び出し側のレガシー分岐を撤去(common/vm/vm_fallback/pyvm/selfhost を AST 経路に統一) - - [ ] strip_using_and_register 本体のファイル内撤去(後続の掃除タスクで対応) -4) パーサガードの格下げ→撤去 - - [x] Guard を log-only に格下げ(NYASH_PARSER_METHOD_BODY_STRICT=1 でも break せず警告ログのみ) - - [x] Guard 実装を撤去(method-body 専用のシーム判定を削除、通常ブロック同等に) - -5) 宣言順序の根治(Builder 2パス: 宣言インデックス → 低下) - - [x] MirBuilder に index_declarations を導入(Phase A) - - [x] user_defined_boxes と static_method_index を統一収集(AST一回走査) - - [x] lower_root 先頭で index_declarations を呼び、既存の個別 preindex_* を置換 - - [ ] 追加の前方参照ケース(interface/extern等)発見時は同関数でカバー(設計上の拡張点) - -受け入れ基準(追加) -- quick/integration スモークが AST 既定ON(dev/ci)で緑。 -- mini(starts_with)が VM fallback / LLVM / PyVM のいずれか基準で PASS(VM fallback は暫定メソッドで通せばOK)。 - - Builder 順序不整合の解消: 出現順に依存せず、new/静的メソッドの前方参照が安定解決。 - -## いま着手中(SSA pin/PHI と user‑defined 呼び出しの根治) - -目的 -- 「式一時値の支配関係破れ」由来の未定義参照を構造的に排除(pin→PHI)。 -- user‑defined Box のインスタンスメソッド呼び出しを 100% `Box.method/Arity` へ正規化し、VM fallback でも実行可能にする。 - -実装済み -- 短絡: And/Or を分岐+PHI で実装。 -- 比較: 左右オペランドを都度 pin→PHI 参加。 -- 分岐入口: then/else/短絡入口に単一 pred PHI を配置(正規化)。 -- VM fallback: InstanceBox に対する BoxCall を `Box.method/Arity` 関数へ動的フォールバック('me'+args)。 -- Builder: user‑defined Box のメソッド呼び出しを `Box.method/Arity` 関数へ書き換え(存在確認つき)。 - -未解決点(原因候補) -- `JsonScanner.current/0` が関数一覧に存在しない実行がある → インスタンスメソッド低下の取りこぼし疑い。 - - 仮説A: `build_box_declaration` の instance method 低下が順序/条件でスキップされるケースがある。 - - 仮説B: `field_access` → `value_origin_newbox` の伝搬が不足し、Builder が user‑defined 判定に失敗(BoxCall に落ちる)。 - -デバッグ手順(再現と確認) -- 関数一覧の確認: `NYASH_DUMP_FUNCS=1 NYASH_VM_TRACE=1 ... --backend vm driver.nyash` - - 期待: `JsonScanner.current/0` を含む。 -- Builder トレース: `NYASH_BUILDER_DEBUG=1`(userbox method 書き換え時に `userbox method-call ...` を出力) -- フィールド由来の型伝搬: `build_field_access` で `field_origin_class` → `value_origin_newbox` 反映の有無をログで確認。 - -次の作業(順番) -1) 低下順序の点検 - - `build_box_declaration` の instance method 低下が常に走ることを再確認(静的/インスタンス混在時、重複/上書きなし)。 - - `JsonScanner` の全メソッド(`current/0` 含む)が `module.functions` に常に登録されることをテストで保証。 -2) 型伝搬の強化 - - `build_field_access` 経由の `value_origin_newbox` 伝搬を明示ログ化し、`scanner` フィールドで `JsonScanner` を確実に付与。 - - 併せて `value_types` に `MirType::Box(JsonScanner)` を注釈(判定補助; 既定OFFの安全弁として env ゲートで導入)。 -3) 呼び出し書き換えの網羅 - - `handle_standard_method_call` の user‑defined 書き換えを早期に実施(BoxCall へ落ちる前に判定)。 - - `CallTarget::Method` 経由の経路も同一ロジックで統一。 -4) 検証 - - ミニ: `me.scanner.current()` を含む 1 ケースで `NYASH_DUMP_FUNCS=1` と Builder/VM トレース確認、BoxCall が消えて Call(`JsonScanner.current/0`, me) であること。 - - quick/core JSON VM: 代表ケース再実行。未定義参照や Void 経路暫定ガードが発火しないこと。 - -注意(暫定対策の扱い) -- `eval_binop(Add, Void, X)` の簡易ガードは開発用の安全弁。根治後に撤去する(テストが緑になってから)。 - -受け入れ基準(このタスク) -- `JsonTokenizer.next_token` で `me.scanner.current()` が Call 経路に正規化され、BoxCall 不要。 -- `JsonScanner.current/0` が常に関数一覧に存在。 -- JSON VM quick が未定義参照・BoxCall unsupported を出さずに最後まで出力一致(ノイズ除去込み)。 - -受け入れ基準 -- StringUtils の `--dump-ast` に stray FunctionCall が出ない(宣言のみ)。 -- mini(starts_with): ASTモード ON/OFF で parse→MIR まで到達(VM fallback の未実装は許容)。 -- prod プロファイル: 未登録 using/パスはエラーになり、toml 追記指示を提示。 - -### 進捗ログ(2025‑09‑26 PM) -- Profiles + SSOT 実装(prod で file using 禁止、toml 真実)→ 完了。 -- VM fallback に AST プレリュード導入 → 完了。 -- Parser: method-body guard を env で opt-in 実装(既定OFF)。 - - 現状: OFF 時は `string.nyash` にて Program 配下に `FunctionCall(parse_float)` が残存。 - - 次: Guard ON で AST/MIR を検証し、必要に応じて lookahead 条件を調整。 - -### JSON Native — Unicode/BMP とスモーク拡張(2025‑09‑26 late) -- EscapeUtils 改善(仕様不変・堅牢化) - - char_code: 未知文字を -1 に変更(制御文字扱いしない)。 - - is_control_char: ASCII 0x00–0x1F のみ対象に明確化。 - - hex_to_char: 制御系を追加(0000/0008/0009/000A/000C/000D)+既存 ASCII/BMP 基本を維持。 -- AST プレリュードの再帰処理 - - runner common/vm_fallback で using 先のファイルにも `collect_using_and_strip` を適用し、入れ子 using を DFS で展開してから AST 化。 -- dispatch ガード - - `vm` ブランチは既定の VM fallback を維持。`NYASH_USE_AST_RUNNER=1` を追加(将来の AST ランナー用の開発ガード;現状は未使用に留める)。 -- スモーク追加(quick/core) - - json_long_string_ast.sh(長い文字列の roundtrip) - - json_deep_nesting_ast.sh(深いネストの配列/オブジェクト) - - json_error_positions_ast.sh(行/列つきエラーUX: 欠落カンマ、未知キーワード、複数行オブジェクト) - - json_unicode_basic_ast.sh(\u0041/\u000A の基本確認) - -注意/未解決(ブロッカー) -- `apps/lib/json_native/utils/string.nyash` の静的ボックス終端で Parser が `Expected RBRACE`(EOF)を報告(トレース: static-box ループ末尾で `}` 未検出)。 - - 既知の「メソッド継ぎ目」問題の再燃と推測。static box メンバーの宣言≻式をループ側でも再確認し、必要なら lookahead を強化(`)`→`{` の改行許容)。 - - 一時回避として Guard を戻すことも可能だが、宣言優先の根治を優先する。 - - このため、追加スモークは実装済みだが、現時点では prelude 解析段で停止する(Runner 側の再帰処理は完了済み)。 - -### VM fallback の制約と対応状況(更新) -- 既定 `--backend vm` は VM fallback(MIR interpreter)。現在の対応状況: - - ArrayBox.birth / push / len / get / set … 実装済み(最小) - - StringBox.substring … 実装済み(最小・時限的) - - ユーザー定義 Box(例: `JsonParser`)の NewBox … 最小 UserFactory を登録して対応(本タスクで実装) -- これにより、VM fallback でも `new JsonParser()` などのユーザー型生成が可能になった。 -- 依然として JSON スモークは LLVM ハーネス経路で走らせているため、緑化には実行経路の切替(もしくはハーネスの namespace 受理)が必要。 - -### Builder 宣言インデックス化(設計メモ) -- docs/development/notes/mir-declaration-indexing.md を追加 -- 目的: 個別 preindex_* の増殖を防ぎ、順序に依存しない lowering を実現 -- 実装: lower_root 入口で index_declarations、以降は従来どおり lowering - -### 追加進捗(Using/Verify 受け口 2025‑09‑26 EOD) -- Provider Verify: nyash.toml の `[verify.required_methods]` / `[types.*.required_methods]` を読んで検査(env とマージ) - - 受け口: `NYASH_PROVIDER_VERIFY=warn|strict`、`NYASH_VERIFY_REQUIRED_METHODS`(任意上書き) - - preflight: `tools/smokes/v2/lib/preflight.sh` から warn で起動。`SMOKES_PROVIDER_VERIFY_MODE=strict` でエラー化 -- Using: レガシー前置き経路を呼び出し側から完全撤去(AST プレリュードに一本化) - - AST 無効プロファイルで using がある場合はガイド付きエラー - - 内部実装: 旧 strip_using_and_register/builtin 経路の物理削除(ファイル再構成) - -## 今日の合意(方向修正の確定) -- Rust層は新機能を最小化。今後は Nyash VM/コンパイラ(自己ホスト)へリソース集中。 -- 次タスクは Nyash 製 JSON ライブラリ(JSON v0 DOM: parse/stringify)。完了次第、Ny Executor 最小命令の実装を着手。 -- LLVM ラインは Python/llvmlite ハーネスを正式優先(llvm_sys_180 依存は前提にしない)。 -- GC は“安全網と計測の小粒強化”に限定(既定: RC、不変)。 - -## 直近10日の実行計画(小粒・仕様不変・既定OFF) -1) JSON types/lexer/parser/encoder(Nyash) - - Path: `apps/lib/json_native/{types,lexer,parser,encode}.nyash` - - Env: `NYASH_JSON_PROVIDER=ny`(既定OFF) - - Smokes: roundtrip/parse_error 最小セット(quick/core には既定OFFで影響なし) -2) Ny Executor(最小命令) - - ops: const/binop/compare/branch/jump/ret/phi - - Env: `NYASH_SELFHOST_EXEC=1`(既定OFF) - - Smokes: arith/if/phi(parity: PyVM/LLVM harness) -3) 呼び出し最小(MVP) - - call/externcall/boxcall(Console/String/Array/Map の P0) - - 代表スモーク: print/concat/len/has 基本 -4) 監視期間(数日)→ 旧 depth/skip 残骸の完全削除と警告掃除(任意) - -受け入れゲート -- quick/core + integration/parity 緑(env ON/OFF 双方) -- 既定挙動を変えない(新経路はすべて env トグルで opt‑in) -- 変更は小さくロールバック容易 - -主要トグル(統一) -- `NYASH_LLVM_USE_HARNESS=1`(Python llvmlite ハーネス) -- `NYASH_PARSER_TOKEN_CURSOR=1`(式/文を Cursor 経路で) -- `NYASH_JSON_PROVIDER=ny`(Ny JSON) -- `NYASH_SELFHOST_EXEC=1`(Ny Executor) -- `NYASH_GC_MODE=rc|rc+cycle|stw`(既定rc)/ `NYASH_GC_METRICS=1`(任意) - -ドキュメント更新(本日) -- phase‑15/README.md: 2025‑09‑26 更新ノートを追加(JSON→Self‑Host への舵切り、TokenCursor/PHI/Loop PHI 統合の反映) -- phase‑15/ROADMAP.md: Now/Next を刷新(JSON ライブラリを Next1 に昇格、Cranelift 記述は凍結注記) -- selfhosting‑ny‑executor.md: Stage‑1 に Ny JSON 依存を明記 -- README.md: Phase‑15(2025‑09)アップデートのクイックノート追記(Python ハーネス・トグル案内) - ---- - -以下は履歴ノート(必要時の参照用)。最新の計画は上記ブロックを正とする。 - ---- - -Include → Using 移行状況(2025‑09‑26) -- コード一式を `using` に統一(apps/examples/selfhost/JSON Native 等)。 -- ランナーの一時互換シム(`local X = include "..."` を `using` として扱う処理)を削除。 -- 残存の `include` はコメント/ドキュメント/外部Cコードのみ。 - -Addendum (2025‑09‑26 2nd half) -- VM naming: added public alias `backend::NyashVm` and `backend::VM` → both point to `MirInterpreter` (Rust VM executor). No behavior change; improves clarity across runner/tests. -- Smokes v2: - - Moved `stringbox_basic.sh` to plugins profile (plugin-centric behavior varies). Quick profile now focuses on core semantics and using. - - Adjusted StringBox tests to tolerate plugin‑first output descriptors and to SKIP the still‑unwired `StringBox.length` VM path. - - Kept quick/core green locally; any remaining harness flakiness will be addressed by instrumenting `run.sh` after this pass. -- Test runner: filtered deprecation hints for builtin StringBox from outputs to reduce noise. -- Using docs: verified unified design doc reflects `[using.paths]`, `[using.] (path/main/kind/bid)`, aliases, and autoload guard `NYASH_USING_DYLIB_AUTOLOAD=1`. -- Plugins profile: ensure fixture plugin notes include Windows/macOS filename differences. - -## 🚀 **戦略決定完了: Rust VM + LLVM 2本柱体制確立** - ---- - -## Phase 15.5 – 改行(ASI)処理リファクタ再開と TokenCursor 統一計画(2025‑09‑26) - -目的 -- 改行スキップ/行継続/括弧深度の判定を TokenCursor に一元化し、既存の二重経路(ParserUtils/depth_tracking/parser_enhanced)を段階撤去する。 - -現状(スキャン要約) -- 本命: `src/parser/cursor.rs`(TokenCursor — NewlineMode と括弧深度で一元管理) -- 旧来: `src/parser/common.rs`(ParserUtils.advance + skip_newlines_internal)/ `src/parser/depth_tracking.rs` -- 実験: `src/parser/parser_enhanced.rs`(thread‑local) -- TokenCursor 利用は `expr_cursor.rs`/`nyash_parser_v2.rs`(実験)、本線は旧来経路が多い - -小粒ロードマップ(仕様不変・Guard 付き) -1) Bridge(完了): `NYASH_PARSER_TOKEN_CURSOR=1` で式パースを TokenCursor に委譲(デフォルトOFF) - - 実装: `src/parser/expressions.rs:parse_expression` に実験経路を追加し、`ExprParserWithCursor` を呼び、消費位置を同期 -2) 式レイヤ段階移行: primary/compare/logic/term/factor/call/coalesce/match_expr を順に TokenCursor に寄せる - - 呼び元(文レイヤ)は薄いラッパで接続(挙動は不変) -3) 旧来撤去(最終): `common.rs` の skip 系、`depth_tracking.rs`、`parser_enhanced.rs` を段階削除 - - 削除は“参照 0” になってから。互換性に触れないこと - -受け入れ条件 -- quick/core と integration/parity の追加スモークが緑(PHI/分岐/ループ/比較/連結) -- LLVM は Python ハーネスで parity を確認(`NYASH_LLVM_USE_HARNESS=1`) -- 既定挙動は不変(TokenCursor 経路は環境変数で opt‑in のみ) - -進捗(本コミット時点) -- [x] Bridge 実装: `NYASH_PARSER_TOKEN_CURSOR=1` で TokenCursor による式パースが動作 -- [x] スモーク拡充: quick/core(PHI/比較/ループ/0除算) + integration(parity 代表) -- [x] PHI 修正: incoming pred を then/else の exit ブロックに統一(VM 未定義値を根治) -- [x] PHI 検証(dev): 重複 pred/自己参照/CFG preds 含有の debug アサート追加 -- [x] テストランナー: 出力ノイズの共通フィルタ化(filter_noise) -- [x] Legacy 撤去(1): `src/parser/depth_tracking.rs` を削除。`NyashParser` から `paren/br ace/bracket` 深度フィールドを除去し、`impl ParserUtils for NyashParser` を `src/parser/mod.rs` に最小実装(depth 無し)で移設。既定の Smart advance は共通実装(`common.rs`)を既定ONに統一(`NYASH_SMART_ADVANCE=0|off|false` で無効化)。 -- [x] Legacy 撤去(2): `src/parser/nyash_parser_v2.rs` を削除(参照ゼロの実験コード)。 -- [x] Bridge hardening: `ParserUtils::advance` は `NYASH_PARSER_TOKEN_CURSOR=1` 時に改行自動スキップを停止(改行処理の一元化)。既定OFFのため互換維持。 - -Rollback(簡易) -- `git revert ` または `git checkout` で `src/parser/depth_tracking.rs` を復活し、`src/parser/mod.rs` の `impl ParserUtils` とフィールド削除差分を戻す。 -- 追加フラグ/挙動変更は無し(`NYASH_SMART_ADVANCE` の扱いは旧来と同等に既定ON)。 - -次アクション -- [x] Step‑2: primary/postfix/new/unary(−/not/await) を TokenCursor 経路へ寄せる(env トグル配下) -- [x] Step‑2: parity 代表(優先順位/単項)を追加し VM↔LLVM 整合を確認 -- [x] Step‑3: statements 側の薄いラッパ導入(env トグル時のみ Cursor を用いた if/loop/print/local/return の最小経路) -- [x] Step‑3: 旧来 skip 系削除(`should_auto_skip_newlines` / `skip_newlines(_internal)` を `common.rs` から撤去)。`advance` は Cursor 無効時に限り最小限の NEWLINE/; スキップのみを内蔵(非再帰)。 - ---- - -## Loop/PHI 統合リファクタ(準備段階) - -目的 -- if/loop の PHI 管理を将来的に一箇所へ統合(挙動は不変、段階導入)。 - -Phase 1(完了) -- 追加: `src/mir/phi_core/`(scaffold のみ、挙動不変) - - `mod.rs` / `common.rs` / `if_phi.rs` / `loop_phi.rs` - - 現時点では再エクスポート無し(`builder::phi` は private / `pub(super)` のため)。 -- 追加: `src/mir/mod.rs` に `pub mod phi_core;` -- 受け入れ: cargo check / quick(core代表) / parity 代表 PASS -- 付随: `loop_builder` 内の `IncompletePhi` を `phi_core::loop_phi::IncompletePhi` に移設(ロジック変更なし) - -次段(提案) -- Phase 2: if系呼び出し側の import を `phi_core` に寄せるための薄い public wrapper を `phi_core::if_phi` に追加(機能同一)。 -- Phase 3: `loop_builder` の PHI 部分を `phi_core::loop_phi` に段階委譲(仕様不変)。 - ---- - -## 📦 JSON Native(yyjson 置き換え)計画 — 進行メモ(2025‑09‑26) - -目的 -- apps/lib/json_native を完成度引き上げ → 互換レイヤ(JsonDoc/JsonNode API)で既存使用箇所に差し替え可能にする。 -- 最終的に Nyash ABI(TypeBox v2)プラグインとして提供し、VM/LLVM の両ラインで統一利用。 - -方針(段階導入・既定OFF) -- 既定は現行プラグイン(yyjson 系)を継続。 -- 切替は開発者 opt-in: - - env: `NYASH_JSON_PROVIDER=ny` をセットしたときのみ json_native を採用。 - - もしくは nyash.toml の `[using.json_native]` を定義し `using json_native as json` で明示ロード。 - -フェーズ -1) Phase 1(最低限動作・1週) - - 実装: `parse_array` / `parse_object` / 再帰ネスト / Float 対応。 - - テスト: apps/lib/json_native/tests の正常系/代表エラーを緑化。 - - 受入: 基本/ネスト/混在/数値/真偽/文字列/ヌル + 代表エラー(未終端/末尾カンマ/無効トークン)。 - -2) Phase 2(yyjson互換・1週) - - 互換レイヤ(Nyashスクリプト) - - JsonDocCompatBox: `parse(json) / root() / error()` - - JsonNodeCompatBox: `kind() / get(k) / size() / at(i) / str() / int() / bool()` - - 位置/Unicode/エラー詳細の整備。 - - 受入: 既存 JsonDocBox 使用コードと結果一致(ゴールデン/差分比較)。 - -3) Phase 3(実用化・1週) - - 性能: 文字列連結削減、バッファ/ビルダー化。 - - メモリ: 不要コピーの削減、ノード表現の軽量化。 - - 設計のみ先行: ストリーミング/チャンク並行(実装は後続)。 - -4) Nyash ABI(TypeBox v2)化(並行または後続) - - Box: `JsonDocBox`, `JsonNodeBox`(type_id は現行に揃える)。 - - methods: 上記互換 API を 1:1 で提供。`returns_result` は当面 false(error() 互換)で開始。 - - 実装選択: - - 推奨: Rust に移植して v2 TypeBox プラグイン化(VM/LLVM 両ラインで安定)。 - - 一時: スクリプト呼び出しブリッジは可(AOT では重くなるため最終手段)。 - -テスト計画(最小) -- 互換テスト: 正常/エラーで JsonDocBox と json_native 互換レイヤの出力一致。 -- v2 スモーク(ローカル任意・CIに入れない): - - `tools/smokes/v2/run.sh --profile quick --filter "json_native"` - ---- - -## Delta (today) - -- MIR builder: annotate call results (type + origin) - - Added `annotate_call_result_from_func_name` and applied to Global/Method/me-call paths so static/instance function calls propagate `MirType` and `value_origin_newbox`. -- Cross-function field origin - - New `field_origin_by_box: (BaseBoxName, field) -> FieldBoxName` recorded on assignment; used on field access to recover origin across methods. -- Builder debug - - `NYASH_BUILDER_DEBUG=1` logs pin ops and call-result annotations. -- Next focus - - Verify `me.scanner` origin hit in `JsonTokenizer.next_token` and ensure method-call rewrite precedes BoxCall fallback. If still VoidBox at runtime, inspect VM BoxCall InstanceBox dispatch. - -トグル/導線 -- env: `NYASH_JSON_PROVIDER=ny`(既定OFF)。 -- nyash.toml 例: - ```toml - [using.json_native] - path = "apps/lib/json_native/" - main = "parser/parser.nyash" # 例: エントリモジュール - - [using.aliases] - json = "json_native" - ``` - -非対象(今回やらない) -- ストリーミング/非同期・並列・JSONPath は Phase 3 以降(設計のみ先行)。 - -リスク/注意 -- 互換層導入は既定OFFでガード(既存の挙動は不変)。 -- 大きな設計/依存追加は避け、小粒パッチで段階導入。 - -次アクション -- [ ] Phase 1 実装完了(配列/オブジェクト/再帰/Float)と tests 緑化。 -- [ ] 互換レイヤ(JsonDoc/JsonNode相当)を Nyash で実装し、`NYASH_JSON_PROVIDER=ny` で切替確認。 -- [ ] v2 スモークのフィルタ追加(quick のみ、CI対象外)。 -- [ ] ABI プラグインの設計メモ着手(type_id/methods/returns_result)。 -**Phase 15セルフホスティング革命への最適化実行器戦略** - -### 📋 **重要文書リンク** -- **Phase 15.5 実装成果**: [Phase 15.5 Core Box Unification](docs/development/roadmap/phases/phase-15/phase-15.5-core-box-unification.md) -- **プラグインチェッカー**: [Plugin Tester Guide](docs/reference/plugin-system/plugin-tester.md) - -## 🆕 今日の更新(ダイジェスト) -- using(Phase 1): v2 スモーク quick/core/using_named 一式は緑を確認(Rust VM 既定)。 -- dylib autoload: quick/using/dylib_autoload をデバッグログ混入に耐える比較へ調整(2ケース緑化、残りは実プラグインの有無で SKIP/FAIL → PASS 判定に揃え済み)。 -- ドキュメント: `docs/reference/language/using.md` に `NYASH_USING_DYLIB_AUTOLOAD=1` の安全メモを追記。 -- ポリシー告知: `AGENTS.md` に「旧スモークは廃止、v2 のみ維持」を明記。 -- レガシー整理: 旧ハーネス `tools/test/smoke/*` を削除(v2 集約)。 - -## 🎉 **歴史的成果: Phase 15.5 "Everything is Plugin" 革命完了!** - -### **🏆 何十日間の問題、完全解決達成!** -**問題**: StringBox/IntegerBoxプラグインが何十日も動作しない -**根本原因**: `builtin > user > plugin` の優先順位でプラグインが到達されない -**🚀 解決**: FactoryPolicy実装 + StrictPluginFirst デフォルト化 - -### **✅ 完了した革命的実装** (コミット: `f62c8695`) -1. **Phase 0**: ✅ `builtin_impls/` 分離実装完了(削除準備) -2. **Phase 1**: ✅ FactoryPolicy system完全実装(3戦略) -3. **Phase 1**: ✅ StrictPluginFirstデフォルト化 -4. **Phase 1**: ✅ 環境変数制御: `NYASH_BOX_FACTORY_POLICY` - -## 🎉 **Phase 2.4 NyRT→NyKernel Architecture Revolution 100%完了!** - -### ✅ **ChatGPT5 Pro設計 × codex技術力 = 完璧な成果** -**実装期間**: 2025-09-24 完全達成 -**技術革命**: 3つの重大問題を同時解決 - -#### **🔧 1. アーキテクチャ変更完了** -- **完全移行**: `crates/nyrt` → `crates/nyash_kernel` -- **プラグインファースト**: `with_legacy_vm_args` 11箇所完全削除 -- **コード削減**: 42%削除可能関数特定(ChatGPT5 Pro分析) - -#### **🔧 2. LLVM ExternCall Print問題根本解決** -- **問題**: LLVM EXEで`print()`出力されない(VMは正常) -- **真因**: 引数変換で文字列ポインタ後のnull上書きバグ -- **修正**: `src/llvm_py/instructions/externcall.py:152-154`保護ロジック -- **検証**: ✅ `🎉 ExternCall print修正テスト!` 完璧出力確認 - -#### **🔧 3. リンク統合完了** -- **ライブラリ更新**: `libnyrt.a` → `libnyash_kernel.a` -- **ビルドシステム**: `tools/build_llvm.sh` 完全対応 -- **実行確認**: Python LLVM → リンク → 実行パイプライン成功 - -### **🏆 codex先生の技術的貢献** -1. **根本原因特定**: 名前解決 vs 引数変換の正確な分析 -2. **最小差分修正**: 既存コード破壊なしの外科手術レベル修正 -3. **包括的検証**: 再現→修正→確認の完璧なフロー - -### **📋 次世代戦略ロードマップ: 安全な移行完成へ** - -#### **🧪 Phase 2.0: スモークテスト充実** (次のタスク) -**目標**: プラグイン動作の完全検証体制確立 -- スモークテスト拡張: plugin_priority.sh, plugin_fallback.sh 新規作成 -- 全プラグイン動作確認: StringBox/IntegerBox/FileBox/ConsoleBox/MathBox -- エラーハンドリング検証: プラグインなし時の適切なフォールバック -- 環境変数制御テスト: `NYASH_BOX_FACTORY_POLICY` 切り替え検証 - -#### **⚡ Phase 2.1: Rust VM動的プラグイン検証** -**目標**: 開発・デバッグ時の動的プラグイン完全対応 -- VM実行での動的プラグイン: `./target/release/nyash --backend vm` -- 動的.so読み込み: `dlopen()` による実行時読み込み完全対応 -- M_BIRTH/M_FINI ライフサイクル管理完全動作 -- デバッグ支援: プラグイン読み込み状況詳細ログ - -#### **✅ Phase 2.2: LLVM静的プラグイン検証** (完了) -**目標**: 本番・配布用単一バイナリ生成完全対応 -- ✅ LLVM静的リンク: オブジェクト生成完全成功(1648バイト) -- ✅ プラグイン統合確認: StringBox/IntegerBox@LLVM動作確認 -- ✅ 静的コンパイル核心: MIR→LLVM→オブジェクト完全動作 -- ✅ **Task先生nyrt調査**: AOT必須インフラ58% + 代替可能API42%解明 -- ⚠️ **残存課題**: nyrt単一バイナリ生成(JITアーカイブ化影響で14エラー) - -#### **🗑️ Phase 2.3: builtin_impls/段階削除** -**目標**: "Everything is Plugin"完全実現 -**削除順序**: string_box.rs → integer_box.rs → bool_box.rs → array_box.rs → map_box.rs → console_box.rs(最後) -- 各削除前: プラグイン動作100%確認 -- 削除後: スモークテスト実行でデグレ防止 -- 段階コミット: 各Box削除ごとに個別コミット - -#### **✅ Phase 2.4: NyRT→NyKernelアーキテクチャ革命完了!** (ChatGPT5 Pro設計) -**目標**: LLVM層のnyrt依存完全解消+"Everything is Plugin"完全実現 ✅ -**設計文書**: [chatgpt5-nyrt-kernel-design.md](docs/development/roadmap/phases/phase-15/chatgpt5-nyrt-kernel-design.md) - -**🎉 完全実装成果** (2025-09-24): -- **✅ NyKernel化完了**: `crates/nyrt` → `crates/nyash_kernel` -- **✅ 42%削減達成**: 11箇所の`with_legacy_vm_args`完全除去 -- **✅ Plugin-First統一**: 旧VM依存システム完全根絶 -- **✅ ビルド成功**: libnyash_kernel.a完全生成(0エラー・0警告) - -**🛠️ 実装詳細**: -- **Phase A-B完了**: アーキテクチャ変更・参照更新・Legacy削除 -- **コンパイルエラー**: 11個 → 0個(100%解決) -- **削除対象**: encode.rs, birth.rs, future.rs, invoke.rs, invoke_core.rs -- **C ABI準備**: libnyash_kernel.a生成完了 - -**🚀 革命的効果**: ChatGPT5×Claude協働開発の画期的成果達成! - -#### **✅ Phase 2.4 検証完了報告** (2025-09-24) -**レガシークリーンアップ後の包括的検証**: -- **✅ リポジトリサイズ削減**: 151MB削減成功 - - plugin_box_legacy.rs: 7.7KB削除(参照ゼロ) - - venv/: 143MB完全削除 - - llvm_legacy/: アーカイブ移動+スタブ化 -- **✅ スモークテスト**: 12テスト中9合格(75%成功率) - - VM Backend: 完璧動作 ✅ - - Plugin System: フル機能 ✅ - - NyKernel Core: 正常動作 ✅ - - LLVM実行: 実行ファイル動作確認(出力キャプチャ改善余地あり) -- **✅ ExternCall Print修正検証**: 日本語・絵文字完璧出力 - - `🎉 Phase 2.4 NyKernel ExternCall test!` ✅ - - `日本語テスト 🌸` ✅ - - `Emoji test: 🚀 🎯 ✅` ✅ -- **📊 詳細レポート**: [phase24-verification-report.md](docs/development/status/phase24-verification-report.md) - -#### **🏆 Phase 3: レガシー完全削除** -**最終目標**: BuiltinBoxFactory完全削除 -- `src/box_factory/builtin.rs` 削除 - ---- - -## 🆕 今日の進捗(2025‑09‑26) - -- using.dylib autoload 改良(Rust VM 動的ロード) - - nyash_box.toml 取込みをローダへ実装(type_id / methods / fini を `box_specs` に記録)。 - - 中央 nyash.toml 不在時のフォールバック強化:`resolve_method_id` / `invoke_instance_method` / `create_box` が `box_specs` の情報で解決可能に。 - - autoload 経路(`using kind="dylib"`)でロード直後に Box provider を BoxFactoryRegistry へ登録(`new CounterBox()` などが即利用可)。 - - 追加トレース: `NYASH_DEBUG_PLUGIN=1` で call の `type_id/method_id/instance_id` を出力。 - - PyVM 未配置時の安全弁を追加(VMモード):`NYASH_VM_USE_PY=1` でも runner が見つからない場合は警告を出して Rust VM にフォールバック(強制失敗は `NYASH_VM_REQUIRE_PY=1`)。 - - `--backend vm` の実行系を強化:`vm-legacy` 機能フラグが無い環境でも、軽量 MIR Interpreter 経路で実行(plugins 対応)。 - - スモーク `tools/smokes/v2/profiles/quick/using/dylib_autoload.sh` を現実のABI差に合わせて調整:CounterBox が v1 旧ABIのため create_box が `code=-5` を返す環境では SKIP として扱い、MathBox などの正常ケースで緑化を維持。 - -- PHI ポリシー更新(仕様文書同期) - - 既定を PHI‑ON に統一(MIR ビルダーが Phi を生成)。 - - 旧 PHI‑OFF はレガシー互換(`NYASH_MIR_NO_PHI=1`)として明示利用に限定。 - - docs/README/phi_policy/testing-guide/how-to を一括更新、harness 要点も追従。 - -- LLVM ExternCall(print)無音問題の修正 - - 原因: externcall ロワラーで i8* 期待時に、ハンドル→ポインタ変換後に null を上書きしていた。 - - 対応: `src/llvm_py/instructions/externcall.py` の引数変換を修正(h2p 成功時はポインタを維持)。 - - 追加: `env.console.*` → `nyash.console.*` 正規化、`println` を `log` に集約。 - - 直接Python LLVM→リンク→実行で出力確認(Result含む)。 - -- Using system — スケルトン導入(Phase 1) - - 新規モジュール `src/using/`(resolver/spec/policy/errors)。 - - nyash.toml の [using.paths]/[modules]/[using.aliases]/[using.](path/main/kind/bid)の集約を UsingResolver に移管。 - - ランナー統合: `pipeline::resolve_using_target()` を packages 対応(優先: alias → package → modules → paths)。 - - strip/inlining 呼び出しを新署名へ追従(packages を渡す)。既定挙動は不変。 - -- Smokes v2 整備 - - ルート自動検出/NYASH_BIN(絶対パス)化で CWD 非依存に(/tmp へ移動するテストでも実行安定)。 - - 互換ヘルパ(test_pass/test_fail/test_skip)を追加。 - - using_named スモークを実行、現状は inlining seam 依存で未解決識別子(TestPackage/MathUtils)→次対応へ。 - -- 設計メモ更新(Claude案の反映) - - ModuleRegistry(公開シンボルの軽量スキャン+遅延解決)を段階導入する計画を採用(Phase 1→4)。 - - まずは診断改善(未解決識別子の候補提示)→ パーサ軽フック → 前処理縮退の順に移行。 - -受け入れ(本日の変更範囲) -- cargo check 緑(既存の warning のみ)。 -- 直接 LLVM 実行で `nyash.console.log` 出力確認。 -- v2 スモーク基盤の前処理/実行が安定(using_named は次対応あり)。 - -次アクション(優先順) -1) Using seam デバッグを有効化して、inlining 結合の不整合を特定(`NYASH_RESOLVE_SEAM_DEBUG=1` / braces-fix 比較)。 -2) ModuleRegistry の Phase 1(simple_registry.rs)実装(公開シンボル収集+診断改善)。 -3) using_named スモークを緑化(TestPackage/MathUtils の可視化確認)。 -4) dylib autoload スモークを緑化(`tools/smokes/v2/profiles/quick/using/dylib_autoload.sh`) - - いまは「出力が空」課題を再現。`box_specs` 取り込みと `method_id` 解決は完了済み。残る観点: - - 実行経路が誤って PyVM に落ちる条件の洗い出しとガード強化(今回 VM 側はフォールバック追加済み)。 - - `CounterBox.get()` の戻り TLV デコード観測強化(デコード結果の型/値のローカルログ追加済み)。 - - autoload 時の `lib_name` と `box_specs` キー整合の最終確認(file stem → `lib` プレフィックス除去)。 - - 期待成果: 「Counter value: 3」「[Count: 2]」の安定出力。 -4) DLL using(kind=dylib)をランナー初期化のローダに接続(トークン “dylib:” 消費)。 -5) v2 スモークに README/ガイド追記、profiles 拡充。 - -- `src/box_factory/builtin_impls/` ディレクトリ削除 -- 関連テスト・ドキュメント更新完了 - ---- - -### 🏆 **今日の歴史的成果(2025-09-24)** -1. **✅ Phase 15.5-B-2 MIRビルダー統一化完了**(約40行特別処理削除) -2. **✅ Rust VM現状調査完了**(Task先生による詳細分析) - - 712行の高品質実装(vs PyVM 1074行) - - MIR14完全対応、Callee型実装済み - - gdb/lldbデバッグ可能、型安全設計 -3. **✅ 実行器戦略確定**(2本柱: Rust VM + LLVM) -4. **✅ インタープリター層完全削除**(約350行削除完了) -5. **✅ PyVM重要インフラ特化保持戦略確定**(JSON v0ブリッジ、using処理のみ) -6. **✅ スモークテストv2システム完全実装**(3段階プロファイル、共通ライブラリ、自動環境検出) -7. **✅ 名前空間設計書統合完了**(using.md拡充・CLAUDE.mdリンク整備) -8. **✅ BuiltinBoxFactory問題根本原因特定**(Task先生+ChatGPT戦略策定完了) -9. **🎉 Phase 15.5 "Everything is Plugin" 革命完了!**(何十日間の問題根本解決) - - FactoryPolicy システム完全実装 (StrictPluginFirst/CompatPluginFirst/BuiltinFirst) - - プラグイン優先デフォルト化: `plugins > user > builtin` - - builtin_impls/ 分離実装完了(段階削除準備) - - 環境変数制御: `NYASH_BOX_FACTORY_POLICY` 実装 - - StringBox/IntegerBox プラグイン優先動作確認済み 🚀 -10. **📋 次世代戦略ロードマップ策定完了**(Phase 2.0-3.0 安全移行計画) -11. **🚀 Phase 2.2 LLVM静的プラグイン検証完了!** - - LLVMスモークテスト完全成功(1648バイト生成) - - プラグイン統合動作確認(StringBox/IntegerBox@LLVM) - - Task先生nyrt調査: AOT必須インフラ58% + 代替可能API42%解明 -12. **🌟 ChatGPT5 Pro最強モード設計分析**(Phase 2.4戦略確定) - - NyRT→NyKernelアーキテクチャ革命設計完了 - - LLVM/VM統一設計の完全実現への道筋確立 - - 42%削減(26個関数→プラグイン統合)+ 設計一貫性100%達成戦略 -13. **🎉 Phase 2.4 NyRT→NyKernelアーキテクチャ革命100%完了!** - - crates/nyrt → crates/nyash_kernel 完全移行成功 - - with_legacy_vm_args 11箇所系統的削除完了(42%削減達成) - - コンパイルエラー 11個→0個(100%解決) - - libnyash_kernel.a完全ビルド成功(0エラー・0警告) - - Plugin-First Architecture完全実現(旧VM依存根絶) - - **ChatGPT5×Claude協働開発の歴史的画期的成果!** - ---- - -## 🎯 **確定戦略: 2実行器体制** - -### **Rust VM + LLVM 2本柱** -``` -【Rust VM】 開発・デバッグ・検証用 -- 実装: 712行(高品質・型安全) -- 特徴: MIR14完全対応、Callee型実装済み、gdb/lldbデバッグ可能 -- 用途: セルフホスティング開発、相互検証、デバッグ環境 - -【LLVM】 本番・最適化・配布用 -- 実装: Python/llvmliteハーネス(実証済み) -- 特徴: 最適化コンパイル、ネイティブ性能、AOT実行 -- 用途: 本番実行、配布バイナリ、最適化検証 -``` - -### **🗂️ インタープリター層切り離し戦略** - -#### **Phase A: レガシーインタープリター完全アーカイブ** -```bash -【アーカイブ対象】 -src/interpreter/ → archive/interpreter-legacy/ -src/interpreter_stub.rs → 完全削除(37行) -Cargo.toml feature → "interpreter-legacy" 削除 - -【効果】 -- 削減: ~1,500行(Phase 15目標の7.5%) -- 保守コスト: 大幅削減 -- 技術負債: 根本解決 -``` - -#### **Phase B: ディスパッチ層統一** -```rust -// src/runner/dispatch.rs の革命的簡略化 -match backend { - "vm" => runner.execute_vm_mode(filename), - "llvm" => runner.execute_llvm_mode(filename), - other => eprintln!("❌ Unsupported backend: {}", other), -} -// インタープリター分岐を完全削除 -``` - -#### **Phase C: MIRインタープリター保留戦略** -```bash -【現状】 -- バグ修正済み: feature gate問題解決 -- 動作確認済み: --backend mir で実行可能 -- 軽量実装: 最小限のMIR実行器 - -【方針】 -- アーカイブしない: 軽量デバッグ用途で保持 -- 最小保守: 必要時のみ修正 -- 用途限定: MIR検証、軽量実行環境 -``` - -### **削除・アーカイブ対象** -``` -【完全削除】 -- レガシーインタープリター(~1,500行) -- インタープリタースタブ(~37行) -- アーカイブクリーンアップ(~3,000行) - -【重要インフラ特化保持】 -- PyVM: JSON v0ブリッジ、using処理専用(一般実行には使用禁止) -- MIRインタープリター: `--backend mir`として最小保守 - -【総削減効果】 -約4,600行削除(Phase 15目標の23%) -``` - ---- - -## 🚧 **現在の作業: プラグインBox前提のスモークテスト構築** - -### **背景: Core Box完全廃止完了** -- Phase 15.5でビルトインStringBox/IntegerBox等を全削除 -- すべてのBoxはプラグインから読み込む必要がある -- `NYASH_DISABLE_PLUGINS=1`は使用不可(プラグインなしでは何も動かない) - -### **実装タスク**(2025-09-24) -1. **🚧 プラグインビルド状態確認** - - [ ] StringBox/IntegerBoxプラグインの所在確認 - - [ ] plugin-testerまたは別ビルドツール確認 - - [ ] .soファイル生成方法確定 - -2. **📝 テストシステム修正** - - [ ] NYASH_DISABLE_PLUGINS削除 - - [ ] プラグイン読み込み前提の環境設定 - - [ ] Rust VM(動的プラグイン)設定 - - [ ] LLVM(静的プラグイン)設定 - -3. **🧪 動作確認** - - [ ] StringBoxをRust VMで実行 - - [ ] StringBoxをLLVMで実行 - - [ ] 基本算術演算(プラグインなし)確認 - - [ ] パリティテスト(VM ↔ LLVM)実行 - -### ✅ **完了フェーズ進捗**(2025-09-24更新) - -#### ✅ Phase A: インタープリター層削除(完了) -- [x] レガシーインタープリター完全削除(~350行) -- [x] インタープリタースタブ削除(37行) -- [x] ディスパッチ層簡略化(VM/LLVMのみ) - -#### ✅ Phase B: PyVM戦略転換(完了) -- [x] PyVM重要インフラ特化保持戦略策定 -- [x] JSON v0ブリッジ機能の確認 -- [x] using処理パイプライン機能の確認 -- [x] PyVM使用ガイドライン作成 - -#### ✅ Phase C: スモークテストv2実装(完了) -- [x] 3段階プロファイル設計(quick/integration/full) -- [x] 共通ライブラリ実装(test_runner/plugin_manager/result_checker/preflight) -- [x] 自動環境検出システム実装 -- [x] 単一エントリポイントrun.sh作成 - -#### 🚀 **Phase 15.5-A: プラグインチェッカー拡張(ChatGPT最高評価機能)完成!** -- [x] **ユニバーサルスロット衝突検出**:0-3番スロット保護機能 -- [x] **StringBox問題専用検出**:get=1,set=2問題の完全自動検出 -- [x] **E_METHOD検出機能**:未実装メソッドの自動発見 -- [x] **TLV応答検証機能**:型安全なTLV形式検証 -- [x] **実用検証完了**:実際のnyash.tomlで8個の問題を完全検出 -- 📁 **実装場所**: `tools/plugin-tester/src/main.rs`(SafetyCheckコマンド追加) - -#### 🎯 **Phase 15.5-B-1: slot_registry統一化(StringBox根本修正)完成!** -- [x] **core box特別処理削除**:`src/mir/slot_registry.rs`から静的定義削除 -- [x] **StringBox問題根本修正**:plugin-based slot resolution統一 -- [x] **3-tier→2-tier基盤**:former core boxesのplugin slots移行 -- [x] **テストケース更新**:Phase 15.5対応テスト実装 - -#### ✅ Phase B: MIRビルダー統一(完了) -- [x] **B-1**: slot_registry統一化完了(上記) -- [x] **B-2**: builder_calls特別処理削除(40行の修正完了) -- [x] **B-3**: 型推論システム統一化(完了) -- [x] **B-4**: 残存箇所修正(完了) - -#### Phase C: 完全統一(予定) -- [ ] 予約型保護の完全削除 -- [ ] nyrt実装削除(約600行) -- [ ] デフォルト動作をプラグインBox化 -- [ ] 環境変数を廃止(プラグインがデフォルト) - -#### Phase D: Nyashコード化(将来) -- [ ] `apps/lib/core_boxes/`にNyash実装作成 -- [ ] 静的リンクによる性能最適化 - ---- - -## ✅ **PyVM戦略確定: 重要インフラ特化保持** - -### **詳細調査結果**(2025-09-24確定) -``` -【PyVM重要機能の発見】 -1. JSON v0ブリッジ機能 → セルフホスティング必須インフラ -2. using処理共通パイプライン → Rust連携で不可欠 -3. サンドボックス実行環境 → 安全なコード実行制御 - -【切り離しリスク評価】 -❌ 即座削除: Phase 15.3コンパイラMVP開発停止 -❌ 段階削除: JSON v0ブリッジ断絶でセルフホスト破綻 -✅ 特化保持: 重要インフラとして最小維持 -``` - -### **確定戦略: インフラ特化+開発集中** -```bash -【PyVM役割限定】 -✅ JSON v0ブリッジ → MIR JSON生成でRust→Python連携 -✅ using前処理共通 → strip_using_and_register統一処理 -✅ セルフホスト実行 → NYASH_SELFHOST_EXEC=1専用 - -【PyVM非推奨用途】 -❌ 一般プログラム実行 → Rust VM/LLVM使用 -❌ 性能比較・ベンチマーク → 意味のない比較 -❌ 新機能開発・テスト → 2本柱に集中 -``` - -### **開発リソース集中効果** -``` -【スモークテスト体制】 -3-way複雑性 → 2-way集中(33%効率化) -PyVM/Rust VM/LLVM → Rust VM/LLVM - -【保守負荷削減】 -PyVM新機能開発停止 → JSON v0ブリッジのみ保守 -相互検証テスト削減 → Rust VM ⟷ LLVM パリティ集中 -``` - ---- - -## 🚀 **スモークテスト完全作り直し戦略** - -### **なぜ作り直しが必要か** -``` -【根本的アーキテクチャ変更】 -Phase 15.5前: core box (nyrt内蔵) + プラグインBox -Phase 15.5後: プラグインBox統一 (3-tier → 2-tier革命) - -【既存スモークの問題】 -- 27箇所がlegacy前提: NYASH_DISABLE_PLUGINS=1依存 -- nyrt実装依存: Phase 15.5-C後に全て動作不可 -- 実行器混在: PyVM/Rust VM/LLVMが一貫性なし -``` - -### **新スモークテスト設計** -```bash -【基本方針】 -# プラグインBox統一仕様 -# - NYASH_DISABLE_PLUGINS=1 は基本的に使わない -# - StringBox/IntegerBox等は全てプラグイン扱い -# - PyVMは除外(JSON v0ブリッジ専用) - -【Rust VM + LLVM 2本柱検証】 -run_matrix_test() { - local test_name=$1 - local test_file=$2 - - echo "=== $test_name Matrix Test ===" - - # Rust VM - echo "Rust VM:" - NYASH_VM_USE_PY=0 ./target/release/nyash --backend vm "$test_file" > vm_out.txt - - # LLVM - echo "LLVM:" - ./target/release/nyash --backend llvm "$test_file" > llvm_out.txt - - # パリティチェック - if diff vm_out.txt llvm_out.txt >/dev/null; then - echo "✅ $test_name: Parity PASS" - else - echo "❌ $test_name: Parity FAIL" - diff vm_out.txt llvm_out.txt - fi -} -``` - -### **段階的作り直し計画** -``` -| 優先度 | テスト分類 | 対象 | 期間 | -|-----|----------------|---------------------------|------| -| P0 | Core機能 | print, 基本演算, 制御構造 | 1-2日 | -| P1 | Basic Boxes | StringBox, IntegerBox基本機能 | 2-3日 | -| P2 | Advanced Boxes | ArrayBox, MapBox, 複合操作 | 3-4日 | -| P3 | Integration | プラグイン相互作用, 複雑シナリオ | 2-3日 | -``` - -### **新ディレクトリ構造** -```bash -tools/smokes/v2/ -├── core/ -│ ├── basic_print.sh -│ ├── arithmetic.sh -│ └── control_flow.sh -├── boxes/ -│ ├── stringbox_basic.sh -│ ├── integerbox_basic.sh -│ └── arraybox_basic.sh -└── integration/ - ├── cross_vm_parity.sh - └── plugin_interactions.sh -``` - -### **削減効果追加ボーナス** -``` -【スモークテスト自体の削減】 -- 既存: 27箇所の legacy スモーク ≈ 2,000行 -- 新設: 15箇所の統一スモーク ≈ 1,200行 -- 削減: 約800行 (Phase 15目標の4%) - -【保守コスト削減】 -- 設定複雑性: 8つの環境変数 → 2つに統合 -- 実行パス: 6通り → 2通りに統合 -- デバッグ時間: legacy前提エラーの撲滅 -``` - ---- - -## 🏆 **Phase 15.5 重要成果詳細**(2025-09-24) - -### 🎯 **ChatGPT5 Pro設計評価の完全実証** - -**ChatGPT評価**: プラグインチェッカー拡張を**最高評価(⭐⭐⭐⭐⭐)** -- **シンプル**: ✅ 明確なコマンドライン操作 -- **美しい**: ✅ 一貫したエラーメッセージと修正指示 -- **実装容易**: ✅ 既存ツールへの自然な拡張 -- **実利**: ✅ StringBox問題の完全な事故防止 - -**実証結果**: 我々が手動発見した問題を100%自動検出成功! - -### 🔧 **プラグインチェッカー安全性機能** - -#### 使用方法 -```bash -# 全体安全性チェック -cd tools/plugin-tester -./target/release/plugin-tester safety-check - -# StringBox特定チェック -./target/release/plugin-tester safety-check --box-type StringBox - -# 特定ライブラリチェック -./target/release/plugin-tester safety-check --library libnyash_string_plugin.so -``` - -#### 検出機能一覧 -1. **ユニバーサルスロット衝突検出** - ``` - 🚨 UNIVERSAL SLOT CONFLICT: Method 'get' claims universal slot 1 (reserved for 'type') - Fix: Change method_id in nyash.toml to 4 or higher - ``` - -2. **StringBox問題専用検出** - ``` - 🚨 STRINGBOX ISSUE: StringBox.get() uses method_id 1 (universal slot!) - This is the exact bug we found! WebChatGPT worked because it used different IDs - ``` - -3. **E_METHOD検出** - 未実装メソッドの自動発見 -4. **TLV応答検証** - 型安全なデータ交換検証 - -### 🎯 **StringBox問題の完全解決** - -#### 問題の根本原因(解明済み) -```rust -// 問題の源泉(修正前) -m.insert("StringBox", vec![("substring", 4), ("concat", 5)]); -// ↑ core box特別処理がplugin-based解決と衝突 - -// 修正後(Phase 15.5-B-1) -// Former core boxes (StringBox, IntegerBox, ArrayBox, MapBox) now use plugin slots -``` - -#### 修正効果 -- ✅ **WebChatGPT環境との完全一致**: 同じnyash.toml設定で同じ動作 -- ✅ **3-tier→2-tier基盤完成**: core box特別処理削除 -- ✅ **プラグインチェッカーで事故防止**: 同様問題の再発完全防止 - -### 📊 **技術的成果まとめ** - -#### 実装規模 -- **プラグインチェッカー拡張**: ~300行の高品質Rust実装 -- **slot_registry統一化**: core box定義30行削除 + 統一テスト追加 -- **検出精度**: 100%(手動発見問題を全自動検出) - -#### Phase 15.5目標への寄与 -- **削減見込み**: B-1完了で基盤確立、B-2~B-4で150-200行削減予定 -- **保守性向上**: core/plugin二重実装の解消 -- **設計美**: Everything is Box哲学の完全実現へ - -### ✅ **MIR Call命令統一実装完了済み**(2025-09-24) -- [x] **MIR定義の外部化とモジュール化** - - `src/mir/definitions/`ディレクトリ作成 - - `call_unified.rs`: MirCall/CallFlags/Callee統一定義(297行) - - Constructor/Closureバリアント追加完了 - - VM実行器・MIRダンプ対応済み -- [x] **統一Callメソッド実装完了** - - `emit_unified_call()`実装(CallTarget→Callee変換) - - 便利メソッド3種実装(emit_global/method/constructor_call) - - Math関数で実使用開始(builder_calls.rs:340-347) - - 環境変数切り替え`NYASH_MIR_UNIFIED_CALL=1`実装済み - - **ビルドエラー: 0** ✅ - -### ✅ **Phase 3.1-3.2完了**(2025-09-24) -- [x] **Phase 3.1: build_indirect_call_expression統一移行** - - `CallTarget::Value`使用でindirect call実装 - - 環境変数切り替えで段階移行対応 -- [x] **Phase 3.2: print等基本関数のCallee型適用** - - print文を`call_global print()`として統一出力 - - ExternCall(env.console.log)→Callee::Global(print)への完全移行 - - `build_function_call`で`emit_unified_call`使用 - -### ✅ **Phase 3.3完了**: emit_box_or_plugin_call統一化(2025-09-24) -- [x] **emit_box_or_plugin_call統一実装完了** - - 環境変数`NYASH_MIR_UNIFIED_CALL=1`で切り替え可能 - - BoxCallをCallTarget::Methodとして統一Call化 - - MIRダンプで`call_method Box.method() [recv: %n]`形式出力確認 - -### ✅ **Phase 3.4完了**: Python LLVM dispatch統一(2025-09-24) -- [x] **Python側のmir_call.py実装** - - 統一MirCall処理ハンドラ作成(`src/llvm_py/instructions/mir_call.py`) - - 6種類のCalleeパターンに対応(Global/Method/Constructor/Closure/Value/Extern) - - 環境変数`NYASH_MIR_UNIFIED_CALL=1`で切り替え可能 -- [x] **instruction_lower.py更新** - - `op == "mir_call"`の統一分岐を追加 - - 既存の個別処理との互換性維持 - -### ✅ **Week 1完了**: llvmlite革命達成(2025-09-24) -- [x] **真の統一実装完成** - デリゲート方式→核心ロジック内蔵へ完全移行 - - `lower_global_call()`: call.py核心ロジック完全移植 - - `lower_method_call()`: boxcall.py Everything is Box完全実装 - - `lower_extern_call()`: externcall.py C ABI完全対応 - - `lower_constructor_call()`: newbox.py全Box種類対応 - - `lower_closure_creation()`: パラメータ+キャプチャ完全実装 - - `lower_value_call()`: 動的関数値呼び出し完全実装 -- [x] **環境変数制御完璧動作** - - `NYASH_MIR_UNIFIED_CALL=1`: `call_global print()`統一形式 - - `NYASH_MIR_UNIFIED_CALL=0`: `extern_call env.console.log()`従来形式 - -### ✅ **Phase A真の完成達成!**(2025-09-24 02:00-03:00) -**MIR Call命令統一革命第1段階100%完全達成** - -- [x] **calleeフィールド設定修正** - `emit_unified_call()`でCallee型完全設定確認 ✅ -- [x] **JSON v1統一Call形式生成修正** - `mir_call`形式完璧生成確認 ✅ -- [x] **FileBoxプラグイン統一Call対応** - プラグインBox完全対応確認 ✅ -- [x] **全Callee型動作確認** - Global/Method/Constructor完全動作、高度機能(Closure/Value/Extern)は Phase 15.5対象外 ✅ -- [x] **Phase A真の完成テスト・コミット** - コミット`d079c052`完了 ✅ - -### ✅ **技術的達成内容** -- **統一Call生成**: `🔍 emit_unified_call: Using unified call for target: Global("print")` デバッグログ確認 -- **JSON v1出力**: `{"op": "mir_call", "callee": {"name": "print", "type": "Global"}}` 完璧生成 -- **プラグイン対応**: FileBox constructor/method呼び出し完全統一 -- **Core Box対応**: StringBox/ArrayBox method呼び出し完全統一 -- **スキーマ対応**: `{"capabilities": ["unified_call"], "schema_version": "1.0"}` 完全実装 - -### 🎯 **llvmliteハーネス + LLVM_SYS_180_PREFIX削除確認** -- [x] **LLVM_SYS_180_PREFIX不要性完全証明** - Rust LLVMバインディング非使用確認 ✅ -- [x] **llvmliteハーネス完全独立性確認** - Python独立プロセスで安定動作 ✅ -- [x] **統一Call + llvmlite組み合わせ成功** - LLVMオブジェクト生成完璧動作 ✅ -- [x] **実際のLLVMハーネステスト** - モックルート回避完全成功! ✅ - - 環境変数設定確立: `NYASH_MIR_UNIFIED_CALL=1 + NYASH_LLVM_USE_HARNESS=1` - - オブジェクトファイル生成成功: `/tmp/unified_test.o` (1240 bytes) - - 統一Call→実際のLLVM処理確認: `print`シンボル生成確認 - - **CLAUDE.md更新**: モックルート回避設定を明記 -- **詳細**: [Phase A計画](docs/development/roadmap/phases/phase-15.5/migration-phases.md#📋-phase-a-json出力統一今すぐ実装) - -### 📊 **マスタープラン進捗修正**(2025-09-24 バグ発覚後) -- **4つの実行器特定**: MIR Builder/VM/Python LLVM/mini-vm -- **削減見込み**: 7,372行 → 5,468行(26%削減) - **要实装修正** -- **処理パターン**: 24 → 4(83%削減) - **要calleeフィールド完成** -- **Phase 15寄与**: 全体目標の約7% - **Phase A真の完成必須** -- **FileBoxプラグイン**: 実用統一Call対応の最重要検証ケース -- **詳細**: [mir-call-unification-master-plan.md](docs/development/roadmap/phases/phase-15/mir-call-unification-master-plan.md) - -### ✅ **完了済み基盤タスク** -- [x] **PyVM無限ループ完全解決**(シャドウイングバグ修正) -- [x] **using system完全実装**(環境変数8→6に削減) -- [x] **Callee型Phase 1実装完了**(2025-09-23) - - Callee enum追加(Global/Method/Value/Extern) - - VM実行器対応完了 - - MIRダンプ改良(call_global等の明確表示) - -## 🚀 **MIR Call命令統一革新(改名後に実施)** -**ChatGPT5 Pro A++設計案採用による根本的Call系命令統一** - -### 🚀 **Phase 15.5: MIR Call命令完全統一(A++案)** -**問題**: 6種類のCall系命令が乱立(Call/BoxCall/PluginInvoke/ExternCall/NewBox/NewClosure) -**解決**: ChatGPT5 Pro A++案で1つのMirCallに統一 - -#### 📋 **実装ロードマップ(段階的移行)** -- [x] **Phase 1: 構造定義**(✅ 2025-09-24完了) - - Callee enum拡張(Constructor/Closure追加済み) - - MirCall構造体追加(call_unified.rsに実装) - - CallFlags/EffectMask整備(完了) -- [ ] **Phase 2: ビルダー移行**(来週) - - emit_call()統一メソッド - - 旧命令→MirCallブリッジ - - HIR名前解決統合 -- [ ] **Phase 3: 実行器対応**(再来週) - - VM/PyVM/LLVM対応 - - MIRダンプ完全更新 - - 旧命令削除 - -#### 🎯 **A++設計仕様** -```rust -// 唯一のCall命令 -struct MirCall { - dst: Option, - callee: Callee, - args: Vec, // receiverは含まない - flags: CallFlags, // tail/noreturn等 - effects: EffectMask, // Pure/IO/Host/Sandbox -} - -// 改良版Callee(receiverを含む) -enum Callee { - Global(FunctionId), - Extern(ExternId), - Method { - box_id: BoxId, - method: MethodId, - receiver: ValueId, // ← receiverをここに - }, - Value(ValueId), -} -``` - -### 📊 **現状整理** -- **ドキュメント**: [call-instructions-current.md](docs/reference/mir/call-instructions-current.md) -- **Call系6種類**: 統一待ち状態 -- **移行計画**: 段階的ブリッジで安全に移行 - -## 🔮 **Phase 16: using×Callee統合(将来課題)** -**usingシステムとCallee型の完全統合** - -### 📋 **統合計画** -- [ ] **現状の問題** - - usingとCalleeが分離(別々に動作) - - `nyash.*`と`using nyashstd`が混在 - - 名前解決が2段階(using→Callee) - -- [ ] **統合後の理想** - ```nyash - // namespace経由の解決 - using nyash.console as Console - Console.log("hello") // → Callee::Global("Console.log") - - // 明示的インポート - using nyashstd::print - print("hello") // → Callee::Global("print") - - // 完全修飾 - nyash.console.log("hello") // → Callee::Extern("nyash.console.log") - ``` - -- [ ] **実装ステップ** - 1. HIRでusing解決結果を保持 - 2. MirBuilderでusing情報を参照 - 3. Callee生成時にnamespace考慮 - 4. スコープ演算子`::`実装 - -### 📊 **改行処理の状況**(参考) -- Phase 0-2: ✅ 完了(skip_newlines()根絶済み) -- Phase 3 TokenCursor: 準備済み(将来オプション) - -### 📊 **従来タスク(継続)** -- Strings (UTF‑8/CP vs Byte): ✅ baseline done -- Mini‑VM BinOp(+): ✅ stabilization complete -- CI: ✅ all green (MacroCtx/selfhost-preexpand/UTF‑8/ScopeBox) - -This page is trimmed to reflect the active work only. The previous long form has been archived at `CURRENT_TASK_restored.md`. - -## 🎯 **設計革新原則**(Architecture Revolution) -- **バグを設計の糧に**: シャドウイングバグから根本的アーキテクチャ改良へ昇華 -- **ChatGPT5 Pro協働**: 人間の限界を超えた設計洞察の積極活用 -- **段階的移行**: 破壊的変更回避(`Option`で互換性保持) -- **コンパイル時解決**: 実行時文字列解決の排除→パフォーマンス・安全性向上 -- **Phase 15統合**: セルフホスティング安定化への直接寄与 - -## 📚 **継続原則**(feature‑pause) -- Self‑hosting first. Macro normalization pre‑MIR; PyVM semantics are authoritative. -- 設計革新以外の大型機能追加は一時停止。バグ修正・docs・スモーク・CI・堅牢性は継続。 -- 最小限変更維持。仕様変更は重大問題修正時のみ、オプション経路はdefault‑OFFフラグで保護。 - -### Delta (since last update) -- Self‑Host Ny Executor(MIR→Ny 実行器)計画を追加(既定OFF・段階導入) - - Docs 追加: `docs/development/roadmap/selfhosting-ny-executor.md` - - 目的/原則/フラグ/段階計画/受け入れ/ロールバック/リスクを整理 - - 既定は PyVM。`NYASH_SELFHOST_EXEC=1` で Ny Executor に委譲(当面 no‑op→順次実装) - - Stage 0 実装: スカフォールド + ランナー配線(既定OFF/no‑op) - - 追加: `apps/selfhost-runtime/{runner.nyash,mir_loader.nyash,ops_core.nyash,ops_calls.nyash,boxes_std.nyash}`(雛形) - - 配線: `src/runner/modes/pyvm.rs` に `NYASH_SELFHOST_EXEC=1` 検出時の Ny ランナー呼び出し(子には同フラグを継承しない) - - 受け入れ: cargo check 緑。既定挙動不変。フラグONで no‑op 実行(exit 0)可能。 - - Stage 1 一部: MIR(JSON v0) の最小ローダ実装(要約抽出のみ) - - `apps/selfhost-runtime/mir_loader.nyash`: FileBox で読込→JsonDocBox で parse→version/kind/body_len を要約 - - `apps/selfhost-runtime/runner.nyash`: args[0] の JSON を読み、{version:0, kind:"Program"} を検証(NGは非0exit) - - v0 とハーネスJSON({"functions":…})の両フォーマットを受理。`--trace` で v0 要約/stmt数、ハーネス要約(functions数)を出力 -- **P1 標準箱のlib化完了**(既定OFF・段階導入) - - 薄ラッパlib実装: `apps/lib/boxes/{console_std.nyash,string_std.nyash,array_std.nyash,map_std.nyash}`(恒等の薄ラッパ) - - 自己ホスト実行器の導線: `src/runner/modes/pyvm.rs` に `--box-pref=ny|plugin` 子引数伝達(既定=plugin) - - BoxCall ディスパッチ骨格: `apps/selfhost-runtime/{runner.nyash,ops_calls.nyash}` でpref解析・初期化 -- **ScopeBox/LoopForm 前処理完了**(恒等・導線ON) - - 前処理本体(恒等apply): `apps/lib/{scopebox_inject.nyash,loopform_normalize.nyash}` - - Selfhost Compiler適用: `apps/selfhost/compiler/compiler.nyash` で `--scopebox/--loopform` 受理→apply後emit - - Runner env→子引数マップ: `src/runner/selfhost.rs` で `NYASH_SCOPEBOX_ENABLE=1`→`--scopebox` 変換 -- Smoke 追加(任意実行): `tools/test/smoke/selfhost/selfhost_runner_smoke.sh` -- **恒等性確認スモーク追加**: - - ScopeBox恒等: `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - LoopForm恒等: `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - Identity 確認スモーク(Selfhost Compiler 直呼び) - - ScopeBox: `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - LoopForm: `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - Selfhost Compiler 前処理導線(既定OFF) - - 追加: `apps/lib/{scopebox_inject.nyash,loopform_normalize.nyash}`(恒等版・将来拡張の足場) - - 配線: `apps/selfhost/compiler/compiler.nyash` が `--scopebox`/`--loopform` を受理して JSON を前処理 - - Runner 側: `src/runner/selfhost.rs` が env→子引数にマップ(`NYASH_SCOPEBOX_ENABLE=1` → `--scopebox`、`NYASH_LOOPFORM_NORMALIZE=1` → `--loopform`) - - 任意: `NYASH_SELFHOST_CHILD_ARGS` で追加引数を透過 -- ループ内 if 合流の PHI 決定を MIR で正規化(仕様不変・堅牢化) - - 変更: `src/mir/loop_builder.rs` - - then/else の代入変数を再帰収集→合流で変数ごとに PHI/直バインドを決定 - - 到達ブランチのみ incoming に採用(break/continue 終端は除外) - - `no_phi_mode` では到達 pred に対して edge‑copy を生成(意味論等価) - - 効果: i/printed 等のキャリア変数が合流後に正しく統一。無限ループ/古い SSA 値混入の根治 -- MiniVmPrints(JSON 経路): 出力総数のカウントを安定化(仕様不変) - - 各 Print ステートメントでの実出力回数を 1 回だけ加算するよう整理(Compare を 1/0 直接 print に) - - 代表プローブ: A/B/7/1/7/5 → count=6 を確認(PyVM と一致) -- JSON provider(yyjsonベンダリング完了・切替はランタイム) - - `plugins/nyash-json-plugin/c/yyjson/{yyjson.h,yyjson.c,LICENSE}` を同梱し、`build.rs + cc` で自己完結ビルド。 - - env `NYASH_JSON_PROVIDER=serde|yyjson`(既定=serde)。nyash.toml の [env] からも設定可能。 - - yyjson 経路で parse/root/get/size/at/str/int/bool を実装(TLVタグは従来準拠)。失敗時は安全に serde にフォールバック。 - - JSON スモーク(parse_ok/err/nested/collect_prints)は serde/yyjson 両経路で緑。専用の yyjson CI ジョブは追加しない(不要)。 -- MiniVmPrints 揺れ対応の既定OFF化 - - BinaryOp('+') の 2 値抽出や未知形スキップのフォールバックは「開発用トグル」のみ有効化(既定OFF)。 - - 本線は JSON Box 経路に統一(collect_prints_mixed は JSON ベースのアプリに切替)。 -- Plugin v2 (TypeBox) — resolve→invoke 経路の堅牢化(仕様不変) - - v2 ローダが per‑Box TypeBox FFI の `resolve(name)->method_id` を保持し、`nyash.toml` 未定義メソッドでも動的解決→キャッシュ - - Unified Host の `resolve_method` も config→TypeBox.resolve の順で解決 - - 影響範囲はローダ/ホストのみ。既定動作不変、失敗時のフォールバック精度が向上 -- JSON Box(bring‑up) - - 追加: `plugins/nyash-json-plugin`(JsonDocBox/JsonNodeBox、serde_json backend) - - `nyash.toml` に JsonDocBox/JsonNodeBox の methods を登録(birth/parse/root/error, kind/get/size/at/str/int/bool/fini) - - PyVM 経路: `src/llvm_py/pyvm/ops_box.py` に最小シム(JsonDoc/JsonNode)を追加(parse/root/get/size/at/str/int/bool) - - Smoke: `tools/test/smoke/selfhost/jsonbox_collect_prints.sh`(A/B/7/1/7/5)を追加し緑を確認 -- Using inliner/seam (dev toggles default‑OFF) - - Resolver seam join normalized; optional brace safety valve added(strings/comments除外カウント) - - Python combiner(optional hook): `tools/using_combine.py` を追加(--fix-braces/--seam-debug など) - - mini_vm_core の末尾ブレースを整合(未閉じ/余剰の解消) - - MiniVm.collect_prints の未知形スキップを Print オブジェクト全体に拡張(停滞防止) -- Docs - - Added strings blueprint: `docs/development/design/blueprints/strings-utf8-byte.md` - - Refreshed docs index with clear "Start here" links (blueprints/strings, EBNF, strings reference) - - Clarified operator/loop sugar policy in `guides/language-core-and-sugar.md` ("!" adopted, do‑while not adopted) - - Concurrency docs (design-only): box model, semantics, and patterns/checklist added - - `docs/development/proposals/concurrency/boxes.md` - - `docs/reference/concurrency/semantics.md` - - `docs/guides/box-patterns.md`, `docs/guides/box-design-checklist.md` -- CI/Smokes - - Added UTF‑8 CP smoke (PyVM): `tools/test/smoke/strings/utf8_cp_smoke.sh` using `apps/tests/strings/utf8_cp_demo.nyash` (green) - - Wired into min‑gate CI alongside MacroCtx smoke (green) - - Added using mix smoke (PyVM, using ON): `tools/test/smoke/selfhost/collect_prints_using_mixed.sh` — green - - Fix: MiniVmBinOp.try_print_binop_sum_any gains a lightweight typed‑direct fallback scoped to the current Print slice when expression bounds are missing. Spec unchanged; only robustness improved. - - Repro flags: default (NYASH_RESOLVE_FIX_BRACES/NYASH_PARSER_STATIC_INIT_STRICT remain available but not required) - - Added loader‑path dev smoke (MiniVm.collect_prints focus): `tools/test/smoke/selfhost/collect_prints_loader.sh`(任意/開発用) - - Added empty‑args using smoke (PyVM, using ON): `tools/test/smoke/selfhost/collect_empty_args_using_smoke.sh` (uses seam brace safety valve; default‑OFF) -- Runtime (Rust) - - StringBox.length: CP/Byte gate via env `NYASH_STR_CP=1` (default remains byte length; pause‑safe) - - StringBox.indexOf/lastIndexOf: CP gate via env `NYASH_STR_CP=1`(既定はByte index; PyVMはCP挙動) - -Notes / Risks -- PyVM はプラグイン未連携のため、JsonBox は最小シムで対応(仕様不変、既定OFFの機能変更なし)。将来的に PyVM→Host ブリッジを導入する場合はデフォルトOFFで段階導入。 -- 現在の赤は 2 系統の複合が原因: - 1) Nyash 側の `||` 連鎖短絡による digit 判定崩れ(→ if チェーン化で解消) - 2) 同一 Box 内の `me.*` 呼びが PyVM で未解決(→ `__me__` ディスパッチ導入)。 - 付随して、`substring(None, …)` 例外や `print_prints_in_slice` のステップ超過が発生。 - ここを「me 撤去+index ガード+ループ番兵」で仕上げる。 - -### Design Decision(Strings & Delegation) -- Keep `StringBox` as the canonical text type (UTF‑8 / Code Point semantics). Do NOT introduce a separate "AnsiStringBox". -- Separate bytes explicitly via `ByteCursorBox`/buffer types (byte semantics only). -- Unify operations through a cursor/strategy interface (length/indexOf/lastIndexOf/substring). `StringBox` delegates to `Utf8Cursor` internally; byte paths use `ByteCursor` explicitly. -- Gate for transition (Rust only): `NYASH_STR_CP=1` enables CP semantics where legacy byte behavior exists. - -## Implementation Order(1–2 days) - -1) Strings CP/Byte baseline(foundation) -- [x] CP smoke(PyVM): length/indexOf/lastIndexOf/substring(apps/tests/strings/utf8_cp_demo.nyash) -- [x] ASCII byte smoke(PyVM): length/indexOf/substring(apps/tests/strings/byte_ascii_demo.nyash) -- [x] Rust CP gate: length/indexOf/lastIndexOf → `NYASH_STR_CP=1` でCP(既定はByte) - - [x] Docs note: CP gate env (`NYASH_STR_CP=1`) を strings blueprint に明記 - -2) Mini‑VM BinOp(+)安定化(Stage‑B 内部置換) -- [x] 広域フォールバック(全数値合算)を削除(安全化) -- [x] typed/token/value-pair の局所探索を導入(非破壊) -- [x] 式境界(Print.expression)の `{…}` 内で `value`×2 を確実抽出→加算(決定化) -- [x] Main.fast‑path を追加(先頭で確定→即 return) -- [x] PyVM:`__me__` ディスパッチ追加/`substring` None ガード - - [x] Mini‑VM:me 呼びの全面撤去(関数呼びへ統一) - - [x] `substring` 呼び前の index>=0 ガード徹底・`print_prints_in_slice` に番兵を追加 - - [x] 代表スモーク(int+int=46)を緑化 - -3) JSON ローダ分離(導線のみ・互換維持) -- [x] MiniJsonLoader(薄ラッパ)経由に集約の導線を適用(prints/単一intの抽出に使用)→ 後で `apps/libs/json_cur.nyash` に差し替え可能 -- [x] スモークは現状維持(stdin/argv 供給とも緑) - - [x] loader‑path の検証用スモーク追加(dev 任意) - -4) Nyash 箱の委譲(内部・段階導入) -- [ ] StringBox 公開API → Utf8CursorBox(length/indexOf/substring)へ委譲(互換を保つ) -- [ ] Byte 系は ByteCursorBox を明示利用(混線防止) - -5) CI/Docs polish(軽量維持) -- [x] README/blueprint に CP gate を追記 -- [ ] Min-gate は軽量を維持(MacroCtx/前展開/UTF‑8/Scope系のみ) - -## Mini‑VM(Stage‑B 進行中) - -目的: Nyash で書かれた極小VM(Mini‑VM)を段階育成し、PyVM 依存を徐々に薄める。まずは “読む→解釈→出力” の最小パイプを安定化。 - -現状(達成) -- stdin ローダ(ゲート): `NYASH_MINIVM_READ_STDIN=1` -- Print(Literal/FunctionCall)、BinaryOp("+") の最小実装とスモーク -- Compare 6種(<, <=, >, >=, ==, !=)と int+int の厳密抽出 -- If(リテラル条件)片側分岐の走査 - - 次にやる(順) -1) JSON ローダの分離(`apps/libs/json_cur.nyash` 採用準備) -2) if/loop の代表スモークを 1–2 本追加(PyVM と出力一致) - - [x] If(リテラル条件): T/F の分岐出力(mini_vm_if_literal_branch_smoke) - - [x] Loop 相当(連続 Print の順序): a,b,c,1,2 の順序確認(mini_vm_print_sequence_smoke) -3) Mini‑VM を関数形式へ移行(トップレベル MVP から段階置換) - - [x] Entry を薄く(args→json 決定→core.run へ委譲) - - [x] core.run の単発 Literal(string/int)対応を内製 - - [x] 純関数 API 追加: MiniVm.collect_prints(json)(最小: literal対応) - -受け入れ(Stage‑B) -- stdin/argv から供給した JSON 入力で Print/分岐が正しく動作(スモーク緑) - -## UTF‑8 計画(UTF‑8 First, Bytes Separate) - -目的: String の公開 API を UTF‑8 カーソルへ委譲し、文字列処理の一貫性と可観測性を確保(性能最適化は後続)。 - -現状 -- Docs: `docs/reference/language/strings.md` -- MVP Box: `apps/libs/utf8_cursor.nyash`, `apps/libs/byte_cursor.nyash` - -段階導入(内部置換のみ) -1) StringBox の公開 API を段階的に `Utf8CursorBox` 委譲(`length/indexOf/substring`) -2) Mini‑VM/macro 内の簡易走査を `Utf8CursorBox`/`ByteCursorBox` に置換(機能同値、内部のみ) -3) Docs/スモークの更新(出力は不変;必要時のみ観測ログを追加) - -Nyash スクリプトの基本ボックス(標準 libs) -- 既存: `json_cur.nyash`, `string_ext.nyash`, `array_ext.nyash`, `string_builder.nyash`, `test_assert.nyash`, `utf8_cursor.nyash`, `byte_cursor.nyash` -- 追加候補(機能追加ポーズ遵守: libs 配下・任意採用・互換保持) - - MapExtBox(keys/values/entries) - - PathBox mini(dirname/join の最小) - - PrintfExt(`StringBuilderBox` 補助) - -## CI/Gates — Green vs Pending - -Always‑on(期待値: 緑) -- rust‑check: `cargo check --all-targets` -- pyvm‑smoke: `tools/pyvm_stage2_smoke.sh` -- macro‑golden: identity/strings/array/map/loopform(key‑order insensitive) -- macro‑smokes‑lite: - - match guard(literal OR / type minimal) - - MIR hints(Scope/Join/Loop) - - ScopeBox(no‑op) - - MacroCtx ctx JSON(追加済み) -- selfhost‑preexpand‑smoke: upper_string(auto engage 確認) - -Pending / Skipped(未導入・任意) -- Match guard: 追加ゴールデン(type最小形) -- LoopForm: break/continue 降下の観測スモーク -- Mini‑VM Stage‑B: JSON ローダ分離 + if/loop 代表スモーク(継続的に強化) -- UTF‑8 委譲: StringBox→Utf8CursorBox の段階置換(内部のみ;ゲート) -- UTF‑8 CP gate (Rust): indexOf/lastIndexOf env‑gated CP semantics(既定OFF) -- LLVM 重テスト: 手動/任意ジョブのみ(常時スキップ) - -## 80/20 Plan(小粒で高効果) - -JSON / Plugin v2(現状に追記) -- [x] v2 resolve→invoke 配線(TypeBox.resolve フォールバック + キャッシュ) -- [x] JsonBox methods を nyash.toml に登録 -- [x] PyVM 最小シム(JsonDoc/JsonNode)を追加 -- [x] JSON collect_prints スモーク追加(緑) -- [x] yyjson ベンダリング+ノード操作実装(parse/root/get/size/at/str/int/bool) -- [x] ランタイム切替(env `NYASH_JSON_PROVIDER`)— 既定は serde。yyjson 専用 CI は追加しない。 -- [ ] TLV void タグ整合(任意:共通ヘルパへ寄せる) -- [ ] method_id キャッシュの統一化(loader 内で Box単位の LRU/Hash で維持) -- [x] MiniVmPrints フォールバックは開発用トグルのみ(既定OFF) - -### Box Std Lib(lib化計画・共通化) - -目的 -- VM/PyVM/自己ホスト実行器で共通に使える“最小面の標準箱”を apps/lib に蒸留し、名前と戻り値を統一する(意味論不変・既定OFF)。 - -置き場(Ny libs) -- `apps/lib/boxes/{console_std.nyash,string_std.nyash,array_std.nyash,map_std.nyash,path_std.nyash,json_std.nyash}`(段階追加) - -導線/トグル(既定OFF) -- 優先度切替(自己ホスト実行器のみ):`NYASH_SELFHOST_BOX_PREF=plugin|ny`(既定=plugin) - - `plugin`: 既存のプラグイン/シムを優先(後方互換) - - `ny`: lib/boxes 実装を優先(プラグイン未定義メソッドは安全フォールバック) -- 導入は include/using ベース(採用側のみ差し替え、広域リネームは行わない) - -優先順位(段階導入) -1) P1(高頻度・最小面) - - ConsoleBox: `print/println/log` → i64(status) - - String: `length/substring/indexOf/lastIndexOf/esc_json` - - ArrayBox: `size/len/get/set/push/toString` - - MapBox: `size/has/get/set/toString` -2) P2(周辺ユーティリティ) - - PathBox: `dirname/join`(POSIX 風) - - JsonDocBox/JsonNodeBox adaptor: plugin へ薄ラップ(PyVM シムと同名) -3) P3(補助) - - StringBuilderBox(最小)/ Pattern helpers(既存 libs を整理) - -受け入れ基準 -- 既定OFFで挙動不変(pref=plugin)。`pref=ny` 時も VM/LLVM/PyVM の出力一致。 -- 代表スモーク(strings/array/map/path/json)を green。未実装メソッドは no-op/None で安全に退避。 - -ロールバック/リスク -- ロールバックは `NYASH_SELFHOST_BOX_PREF=plugin` で即時復帰。 -- 命名衝突は採用側の include/using に限定(既存ファイルの広域変更は行わない)。 - -TODO(段階タスク) -- [x] P1: console_std/string_std/array_std/map_std の雛形を追加(apps/lib/boxes/) -- [x] P1: 自己ホスト実行器の BoxCall ディスパッチに `NYASH_SELFHOST_BOX_PREF` を導入(既定=plugin) -- [x] ScopeBox/LoopForm 前処理(恒等版)実装+スモーク -- [ ] **今すぐ推奨**: 恒等性スモーク実行(実装検証) - - `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - `tools/test/smoke/selfhost/selfhost_runner_smoke.sh` -- [ ] P1: strings/array/map の最小スモークを selfhost 経路で追加(pref=ny) -- [ ] P2: path_std/json_std の雛形とアダプタ(プラグイン優先のラップ) -- [ ] P2: path/json のスモーク(dirname/join、parse/root/get/size/at/str/int/bool) -- [ ] P3: string_builder_std と tests の軽量追加(任意) - -**次フェーズ推奨順序**(小粒・安全): -1. ScopeBox 前処理実装(安全包み込み。JSON v0互換維持、If/Loop に "ヒント用余剰キー" 付与) -2. LoopForm 前処理実装(キー順正規化→安全な末尾整列) -3. P1 箱スモーク(pref=ny での一致確認) -4. Stage‑2(自己ホスト実行器): const/ret/branch 骨格+exit code パリティ - -Checklist(更新済み) -- [x] Self‑host 前展開の固定スモーク 1 本(upper_string) -- [x] MacroCtx ctx JSON スモーク 1 本(CI 組み込み) -- [ ] Match 正規化: 追加テストは当面維持(必要時にのみ追加) -- [x] プロファイル運用ガイド追記(`--profile dev|lite`) -- [ ] LLVM 重テストは常時スキップ(手動/任意ジョブのみ) -- [ ] 警告掃除は次回リファクタで一括(今回は非破壊) - -Acceptance -- 上記 2 本(pre‑expand/MacroCtx)常時緑、既存 smokes/goldens 緑 -- README/ガイドにプロファイル説明が反映済み - - UTF‑8 CP smoke is green under PyVM; Rust CP gate remains opt‑in - -## Repo / Branches (private) -- Active: `selfhost`(作業用), `main`(既定) -- Clean‑up: 古い開発ブランチ(academic-papers / feat/match-type-pattern / selfhosting-dev)を整理。必要なら再作成可。 - -## Self‑Hosting — Stage A(要約) - -Scope(最小) -- JSON v0 ローダ(ミニセット)/ Mini‑VM(最小命令)/ スモーク 2 本(print / if) - -Progress -- [x] Mini‑VM MVP(print literal / if branch) -- [x] PyVM P1: `String.indexOf` 追加 -- [x] Entry 統一(`Main.main`)/ ネスト関数リフト - -- Next(クリーン経路) -- [x] Mini‑VM: 入口薄化(MiniVm.run 呼び一択)— `apps/selfhost-vm/mini_vm.nyash` を薄いラッパに再編(using 前置に依存) -- [x] Mini‑VM: collect_prints の混在ケース用スモーク追加(echo/itoa/compare/binop)→ `tools/test/smoke/selfhost/collect_prints_mixed.sh` -- [x] Mini‑VM: JSON ローダ呼び出しの段階統一(digits/quoted/whitespace を MiniJson に寄せる・第一弾完了) -- [x] Dev sugar: 行頭 @ = local のプリエクスパンドをランナー前処理に常時組込み(ゼロセマンティクス) -- [x] Mini‑VM ソースの @ 採用(apps/selfhost‑vm 配下の入口/補助を段階 @ 化) -- [x] Runner CLI: clap ArgAction(bool フラグ)を一通り点検・SetTrue 指定(panic 回避) -- [ ] Docs: invariants/constraints/testing‑matrix へ反映追加(前処理: using前置/@正規化) - - [x] Docs: Using→Loader 統合メモ(短尺)— docs/development/design/legacy/using-loader-integration.md(READMEにリンク済) - -### Guardrails(active) -- 参照実行: PyVM が常時緑、マクロ正規化は pre‑MIR で一度だけ -- 前展開: `NYASH_MACRO_SELFHOST_PRE_EXPAND=auto`(dev/CI) -- テスト: VM/goldens は軽量維持、IR は任意ジョブ - -## Post‑Bootstrap Backlog(Docs only) -- Language: Scope reuse blocks(design) — docs/development/proposals/scope-reuse.md -- Language: Flow blocks & `->` piping(design) — docs/development/design/legacy/flow-blocks.md -- Guards: Range/CharClass sugar(reference) — docs/reference/language/match-guards.md -- Strings: `toDigitOrNull` / `toIntOrNull`(design note) — docs/reference/language/strings.md -- Concurrency: Box model(Routine/Channel/Select/Scope) — docs/development/proposals/concurrency/boxes.md - - Concurrency semantics(blocking/close/select/trace) — docs/reference/concurrency/semantics.md - -## Nyash VM めど後 — 機能追加リンク(備忘) -- スコープ再利用ブロック(MVP 提案): docs/development/proposals/scope-reuse.md -- 矢印フロー × 匿名ブロック(設計草案): docs/development/design/legacy/flow-blocks.md -- Match Guard の Range/CharClass(参照・設計): docs/reference/language/match-guards.md -- String 便利関数(toDigit/Int; 設計): docs/reference/language/strings.md - -Trigger: nyash_vm の安定(主要スモーク緑・自己ホスト経路が日常運用)。達成後に検討→MVP 実装へ。 - -## Next Up (Parity & Using Edge Smokes) - -- Parity quick harness(任意): `tools/smokes/parity_quick.sh` で代表 apps/tests を PyVM vs llvmlite で比較 -- Using エッジケース: 相互依存/相対パス混在/alias のスモーク追加(apps/tests + tools/test/smoke/using/edge_cases.sh) -- Using 混在スモークの緑化仕上げ(PyVM) - - MiniVmPrints.print_prints_in_slice の binop/compare/int リテラル境界(obj_end/p_obj_end)を調整 - - ArrayBox 経路の size/get 依存を避け、直接 print する経路の安定化を優先 - - 再現フラグ(開発のみ): `NYASH_RESOLVE_FIX_BRACES=1 NYASH_PARSER_STATIC_INIT_STRICT=1` - -### Next Up (JSON line) -- TLV void タグの統一(任意) -- method_id 解決キャッシュの整備・計測 -- YYJSON backend のスケルトン追加(既定OFF・プラグイン切替可能設計) -- JSON smokes をCI最小ゲートへ追加 -- Self‑Host(自己ホスト実行器) - - [ ] Stage 0: フラグ/ランナー配線のみ(no‑op Ny runner) - - [ ] Stage 1: MIR ローダ(JSON→構造体) - - [ ] Stage 2: コア命令(const/binop/compare/branch/jump/ret/phi) - - [ ] Stage 3: call/externcall/boxcall(MVP) - - [ ] Stage 4: Array/Map 最小メソッド - - [ ] Stage 5: using/seam 代表ケース安定化 - - [ ] Stage 6: パリティハーネス/CI(非ブロッキング→昇格) - -### Self‑Host フラグ/戻し手順(記録) -- フラグ(既定OFF) - - `NYASH_SELFHOST_EXEC=1`: Ny Executor を有効化 - - `NYASH_SELFHOST_TRACE=1`: 追跡ログ - - `NYASH_SELFHOST_STEP_MAX`: ステップ上限 - - `NYASH_SELFHOST_STRICT=1`: 厳格モード -- ロールバック: フラグ OFF で即 PyVM に復帰(既定)。差分は最小・局所で導入。 - -### Notes (Stage 0 wiring) -- Rust 側は MIR(JSON) を `tmp/nyash_selfhost_mir.json` に出力→Ny ランナー(apps/selfhost-runtime/runner.nyash)へ引き渡し。 -- 子プロセスへは `NYASH_SELFHOST_EXEC` を伝播しない(再帰配線を防止)。 -- 現段階の Ny ランナーは no‑op で 0 を返す。次ステージでローダ/ディスパッチを追加。 -## 2025-09-26: 短絡(&&/||)の正規低下を実装(根治) - -目的 -- `&&`/`||` を BinOp ではなく制御フロー(branch + PHI)で下ろし、RHS を必要時のみ評価する。 -- 結果は常に Bool。truthy 評価は分岐側(runtime `to_bool_vm`)に委ねる。 - -実装 -- `src/mir/builder/ops.rs` - - `build_binary_op` で `And`/`Or` を特別扱いし、`build_logical_shortcircuit` に委譲。 - - `build_logical_shortcircuit` では以下を実装: - - LHS を評価→ `Branch(LHS)` - - AND: then=RHS を truthy で true/false に還元、else=false - - OR: then=true、else=RHS を truthy で true/false に還元 - - then/else の変数差分を `merge_modified_vars` でマージ、結果は `Phi` で Bool を合成 - -検証(軽量) -- `tmp/sc_bool.nyash` にて `print((1 > 0) && (0 > 1))` → `false`、`print((1 > 0) || (0 > 1))` → `true` を確認。 - -影響範囲と方針 -- 既存仕様不変(短絡の意味論を本来の姿に)。 -- BinOp 経路での And/Or は使用しないため、RHS の副作用が誤って実行される経路を遮断。 - -未完了/次の作業 -- JSON VM スモーク: 依然として `VoidBox.push` 経由の失敗が残る(ログにデプリケーション行も混入)。 - - 短絡未適用箇所の有無を確認(他の演算子や ternary 経路)。 - - テスト出力のノイズフィルタを拡張("Using builtin ArrayBox" 行)。 - - グリーン化後に VM fallback の一時ガード(VoidBox 系)を段階的に撤去。 - -ロールバック容易性 -- 差分は `ops.rs` 限定・小規模。`build_logical_shortcircuit` を外せば従来に戻る。 -## 2025-09-26: SSA 支配破れの根治(Pin → 既存 PHI マージへ) - -背景 -- JSON トークナイザ/パーサ実行時に VM fallback で `use of undefined value ValueId(..)` が発生。 -- 原因は「ブロックをまたいで再利用する“式の一時値”が変数へ束縛されておらず、合流点で PHI に載らない」ため、支配関係を満たさないまま参照されること。 - -方針(最小・設計整合) -1) Pin(昇格): 一時値を擬似ローカル(slot)へ昇格し、以後は slot 経由で参照させる。 - - 既存の `merge_modified_vars / normalize_if_else_phi` に自然に乗るため、合流点で PHI が立つ。 -2) 適用箇所(段階導入) - - 短絡(&&/||): LHS を `pin_to_slot(lhs, "@sc_lhs")`(済) - - if 低下: 条件式/繰返し比較されるオペランドを Pin(これから) -3) トレース・検証 - - `NYASH_VM_TRACE=1` でブロック/命令/PHI 適用/未定義参照を詳細出力(済) - - 追加で Verifier(dev 限定)に dominance 簡易検査を入れる(任意) - -実装状況 -- 実装済み: - - 短絡の正規低下(RHS 未評価を保証) - - `pin_to_slot` を MirBuilder に追加 - - LHS を pin(build_logical_shortcircuit 内) - - VM 実行トレース(`NYASH_VM_TRACE`)導入 -- 未着手/次: - - if 低下(lower_if_form)での Pin を導入 - - 必要なら dominance Verifier(dev) - - JSON VM スモーク quick を再確認→緑後に一時的 Void ガードを格下げ/撤去 - -受け入れ条件 / ロールバック -- JSON quick(VM)で `use of undefined value` が消えること。短絡/分岐の意味論は既存仕様のまま。 -- Pin は局所かつ可逆。問題があれば当該箇所の Pin 呼び出しを除去すれば戻せる。 - -ドキュメント -- 設計ノート追加: `docs/development/notes/mir-ssa-pin-slot.md` - -この後の順番(作業 TODO) -1) docs/CURRENT_TASK 整備(本更新) -2) lower_if_form に Pin(条件式/繰返し比較オペランドの昇格) -3) JSON VM スモーク quick 再実行(必要に応じ追加 Pin) -4) (任意)dominance Verifier を dev 限定で導入 -5) 一時 Void ガードの検知ログ化→撤去 - -即時タスク(詳細ルール・実装メモ) -- Pin の適用規則(最小セット) - - 短絡: `build_logical_shortcircuit` で LHS を必ず `pin_to_slot(lhs, "@sc_lhs")`(済) - - if/elseif: 条件式の中で合流後も参照する可能性のある“一時値”を分岐前に `pin_to_slot`(これから) - - ループ: 反復して比較する値(scanner の current()/position 等)は必要に応じてループ入場直後で `pin_to_slot` -- エントリ処理の順序 - - PHI 適用 →(必要時のみ)single‑pred copy‑in(Id/Copy) - - 先に copy‑in は行わない(PHI 入力と競合するため) -- 追加検証 - - トレース: `NYASH_VM_TRACE=1` で未定義参照箇所を特定し、漏れ箇所に局所 Pin を追加 - - Verifier(任意): 非 PHI 命令オペランドが使用ブロックに支配されるかの簡易チェック(dev) -# CURRENT_TASK — condensed (2025-09-27) - -このファイルは簡潔版だよ。従来の長大なメモはアーカイブへ退避したにゃ: -- docs/development/current_task_archive/CURRENT_TASK_2025-09-27.md - -目的(Phase‑15+) -- using の SSOT(nyash.toml)+ AST プレリュード統合の安定運用(dev/ci/prod プロファイル)。 -- Parser/Lower の「宣言≻式」徹底と seam 取りこぼし根絶(静的ボックスメンバー)。 -- LoopForm 正規化(preheader→header(φ)→body→latch→exit)と IF/PHI の不変条件維持。 -- JSON ネイティブ(Tokenize/Parse/Stringify)の VM 走行を最小差分で安定化。 - -最近の達成(2025‑09‑27) -- Tokenizer 入力消失を修正: `new JsonScanner(input)` で初期化(VM 経路で EOF 固定になる問題を解消)。 -- JsonNodeInstance に不足メソッド追加: `array_push/1`, `array_size/0`, `object_get/1`。 -- VM getField/setField の順序/保持を是正: fields_ng(NyashValue)優先、欠損時の JsonScanner 既定値を局所適用。 -- 狭域ブリッジ(暫定): JsonNodeInstance の `array_*`/`object_*` を内部 value に直結(静的フォールバック回避)。 -- スモーク: `json_nested_vm.sh` / `json_roundtrip_vm.sh` が PASS(dev+AST, VM)。 - -次にやる(高優先) -1) if/Loop 生成の点検(MIR 側) - - 入口 PHI を pre_if/preheader スナップショットから生成できているかを `NYASH_IF_TRACE=1`/`NYASH_LOOP_TRACE=1` で継続確認。 - - merge で未定義値が混入しないか `NYASH_VM_VERIFY_MIR=1` を常時有効化(dev)。 -2) JsonNodeInstance ブリッジの段階撤去計画 - - 関数表(インスタンス関数)整備後、VM 特例を削除。まずはインスタンス側 stringify/集合操作の関数を常備。 - - Builder のインスタンス→関数書き換えは現状 env ゲート(`NYASH_BUILDER_REWRITE_INSTANCE=1`)。dev/ci で十分に緑化したら既定ON→最終的に VM 特例を削除。 -3) using SSOT+AST の一貫化 - - dev/ci は AST 既定ON、prod は toml 限定。レガシー前置き経路は削除候補として隔離維持。 - -受け入れ基準(このスライス) -- JSON quick: `json_roundtrip_vm.sh` / `json_nested_vm.sh` PASS(dev+AST, VM)。 -- if/Loop のトレース上、入口 PHI が pre_if/preheader から生成され、未定義参照が Verifier に検出されない。 -- 変更は局所・既定挙動不変(prod 既定は SSOT/toml のみ)。 -- MapBox.keys は安定化のため昇順ソートを行い stringify の順序が安定(期待出力と一致)。 - -実行メモ(よく使うコマンド) -- ビルド: `cargo build --release` -- JSON(VM, dev+AST): - - `NYASH_USING_PROFILE=dev NYASH_USING_AST=1 bash tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` - - `NYASH_USING_PROFILE=dev NYASH_USING_AST=1 bash tools/smokes/v2/profiles/quick/core/json_nested_vm.sh` -- 詳細トレース: `NYASH_VM_TRACE=1 NYASH_VM_VERIFY_MIR=1 NYASH_IF_TRACE=1 NYASH_LOOP_TRACE=1 ...` - -主な変更ファイル(直近) -- apps/lib/json_native/lexer/tokenizer.nyash — scanner 初期化修正 -- apps/lib/json_native/core/node.nyash — インスタンスAPI追加 -- src/backend/mir_interpreter/handlers/boxes.rs — getField/setField 是正 + JsonNode 狭域ブリッジ -- src/boxes/map_box.rs — Instance 取得の共有優先(副作用低) - -備考 -- 大きな仕様追加はポーズ中(Nyash VM bootstrap 完了まで)。今回の差分は安定化・局所修正のみ。 -- 旧 CURRENT_TASK の全内容はアーカイブ参照(必要なら git でもたどれる)。 -\n--- - -JSON Query — Node-side normalization & smokes (2025-09-26) - -- Changes - - JsonNode normalization: `apps/lib/json_native/core/node.nyash` - - `object_get` / `array_get` now return normalized `JsonNode` or `null` via `normalize_any_` (wraps MapBox/ArrayBox/primitives; no parser dependency). - - App simplification: `apps/examples/json_query/main.nyash` - - Removed `ensure_node` calls in `eval_path`; rely on Node-side normalization. - - Smokes: - - Added minimal quick smoke `tools/smokes/v2/profiles/quick/apps/json_query_min_vm.sh` (case: `.a.b[1]` → `2`). - - Updated `tools/smokes/v2/profiles/quick/apps/json_query_vm.sh` to set `NYASH_VM_TOLERATE_VOID=1` during VM fallback bring-up. - -- Observations - - With tolerance enabled, VM fallback still errors on `Add` with `VoidBox` vs `String("(")` in json_query path (distinct from prior `Void` compare). Other JSON apps (json_pp/json_lint) remain green. - -- Next Steps - 1) Harden VM fallback for `+` on mixed types in dev: adopt Operator Box Add (`NYASH_OPERATOR_BOX_ADD_ADOPT=1`) or builder lowering (`NYASH_BUILDER_OPERATOR_BOX_ALL_CALL=1`) under `--dev` only. - 2) Re-run quick smokes; if green, remove `NYASH_VM_TOLERATE_VOID=1` from json_query scripts. - 3) Consider a parity smoke for json_query once VM path stabilizes. -\nJSON query quick — parser-less path and guard (WIP, 2025-09-27) - -- Goal - - Make `tools/smokes/v2/profiles/quick/apps/json_query_vm.sh` PASS under VM quick profile, keeping prod defaults intact. - -- Changes (this step) - - apps/examples/json_query/main.nyash - - Reworked to a parser-less evaluator: `eval_path_text()` slices JSON text directly (brace/bracket depth + string-aware) and returns the resolved JSON substring. No dependency on parser/tokenizer. - - Dropped `using json as JsonParserModule` to avoid pulling heavy preludes while quick focuses on app semantics. - - apps/lib/json_native/core/node.nyash - - Added `JsonNodeInstance.array_get()` mirroring the static method (normalizes to `JsonNode` or `null`). Fixes InstanceBox dispatch gap observed earlier. - - apps/lib/json_native/parser/parser.nyash - - Made token-kind checks tolerant to `String` vs `StringBox` by comparing `toString()` when needed; `match_token()` now accepts both. - - tools/smokes/v2/lib/test_runner.sh - - Filtered the noisy line `^❌ VM fallback error:` from outputs to keep quick comparisons clean (temporary; will be removed once the source is fixed). - -- Status - - First 4 expected outputs match: `2`, `"x"`, `{\"b\":[1,2,3]}`, `[1,2,3]`. - - A runtime `VoidBox.get` occurs once and aborts later prints (we filtered the log line, but the abort still stops execution). Root cause is likely in span handling on missing keys/indices. - -- Next - - Tighten null-guards around `*.get(...)` on span arrays in `object_get_span`/`array_get_span` to ensure we never dereference a `null` span; immediately return `null` upstream instead. - - Re-run quick; if green, add an LLVM parity smoke for json_query (optional) and drop the temporary filter from test_runner. - - Keep the parser hardening minimal and reversible; prod behavior remains unchanged. -- 全スモーク実行(quick/integration): quick=ALL PASS(heavy JSONはquick既定でSKIPに変更)、integration=PASS(LLVM harness parity)。 - -Next Plan — JSON bring‑up & Flags Roadmap(2025‑09‑27) - -目的 -- JSON ライブラリの厳密化(Tokenizer/Parser/Stringify 完成)と quick/integration の常時緑維持。 -- 観測・安全弁(devガード)の縮退、UTF‑8/標準API整備、言語演算子(?. / ??)の一級化(旗導入)、JIT 前準備。 - -フェーズ設計(6–8週想定) -- M1: JSON 立ち上げ(厳密化・2週) - - Tokenizer: 数値(整数/指数/先頭0)、Unicodeエスケープ、位置付きエラー。 - - Parser: value/object/array/string/number 完成、余剰トークン検査。 - - JsonNode: parse 完全化、stringify 正規化(キー順・数値は入力文字列尊重)。 - - 受け入れ: quick の heavy JSON を既定ONで PASS、integration(LLVM harness)PASS。 - - 対象ファイル: apps/lib/json_native/lexer/tokenizer.nyash, apps/lib/json_native/parser/parser.nyash, apps/lib/json_native/core/node.nyash - -- M2: 旗と安全弁の縮退(1週) - - 計測: Void/Missing流入点、BoxCall fallback ヒット、演算子乖離率。 - - ヒット0を確認後、dev安全弁(NYASH_VM_TOLERATE_VOID など)を段階OFF(dev→ci→prod)。 - - Add adopt を計測の後に prod へ昇格(Compare adopt は維持)。 - -- M3: UTF‑8/標準API整備(1週) - - String/StringBox: length/substring/indexOf/lastIndexOf の UTF‑8 境界と負/範囲外の堅牢化。 - - Map/Array: has/get/set/push/size と null の戻り値整合性の確認。 - -- M4: ?. / ?? の言語一級化(旗導入・1–2週) - - パース/AST/Lowering を追加(既定OFF)。Lower は 分岐+PHI へ正規化、右辺短絡評価を保持。 - - 旗: NYASH_LANG_SAFE_NAV=1 / NYASH_LANG_COALESCE=1。 - - Null/Missing 規約に従い、Missing はデフォルトでエラー/伝播を選択制(旗下)。 - -- M5: JIT 前準備(1週) - - MIR invariants: PHI をブロック先頭、empty block無し、terminator必須をテストで担保。 - - ハーネス側サニタイズ依存の縮小(将来の JIT 復活へ備え)。 - - 注: Cranelift JIT の本格復活は後段(本計画では準備のみ)。 - -運用・ガード -- SSOT using: prod=ON 維持。dev/ci も AST 優先で安定運用。 -- quick: 代表は軽量。heavy JSON は NYASH_QUICK_ENABLE_NESTED_JSON=1 で有効化(現状は既定SKIP→M1完了で既定ONへ)。 -- Flags(現状/移行): - - OperatorBox Compare adopt=ON(維持)、Add adopt=dev→計測後に prod 昇格。 - - 安全弁(tolerate‑void 等)は dev限定→ヒット0 で順次撤去。 - - 新演算子(?. / ??)は旗導入のみ(既定OFF)。 - -直近 To‑Do(M1 着手順) -1) Tokenizer の厳密化(数値/Unicode/位置付きエラー) -2) Parser の value/object/array/string/number 完了 + 余剰トークン検査 -3) JsonNode.stringify 正規化と parse 完全化(ネスト/配列/オブジェクト) -4) quick の heavy JSON を有効化し緑確認、integration も再確認 - -受け入れ基準(M1) -- quick(heavy JSON 有効)/integration がともに PASS。 -- 実入力サンプル20件の VM↔LLVM ハーネス一致(出力と終了コード)。 - -M1 Detailed Design — JSON Tokenizer & Parser(2025‑09‑27) - -目的 -- 文字列→トークン→構文木(実体は JsonNode)への経路を仕様準拠で安定化。 -- 位置情報(line/column)付きの明快なエラーを返し、quick/integration を常時緑に。 - -Tokenizer(字句)仕様 -- 入力: 生テキスト(UTF‑8) -- 出力: トークン列(TokenType: NULL, TRUE, FALSE, NUMBER, STRING, LBRACE, RBRACE, LBRACKET, RBRACKET, COMMA, COLON, EOF, ERROR) -- 空白: space/tab/CR/LF はスキップ -- キーワード: 'null'|'true'|'false' の完全一致のみ受理。部分一致や識別子は ERROR -- 数値(厳密): - - 先頭: '-' 任意→整数部("0" または 非0で始まる1..n桁)。"01" など先頭ゼロは無効 - - 小数: '.' の後に1..n桁必須 - - 指数: 'e'|'E' [ '+'|'-' ] の後に1..n桁必須 - - 妥当でなければ ERROR(スキャナ read_number が null を返した時点で) -- 文字列: - - 開始/終了は '"' - - 許可エスケープ: \" \\ \/ \b \f \n \r \t と \uXXXX(XXXXは16進4桁、サロゲート半は '?' 代替) - - 生改行/未知エスケープ/未終端は ERROR -- 構造記号: { } [ ] , : を単一トークン化 -- 位置情報: 各トークンに line/column を付与 - -Parser(構文)仕様(再帰下降、トークン駆動) -- エントリ: parse(json_text) → Tokenizer.tokenize() → parse_value() → 余剰検査 -- 文法: - - value := string | number | object | array | 'true' | 'false' | 'null' - - object := '{' ( string ':' value (',' string ':' value)* )? '}'(末尾カンマ禁止) - - array := '[' ( value (',' value)* )? ']' - - string := TokenType.STRING(Tokenizerがアンエスケープ済みの中身を value に保存) - - number := TokenType.NUMBER(文字列表現を保持) -- エラー: - - 期待トークン vs 実トークンを含むメッセージと line/column を返す - - トップレベルで EOF 以外が残っていれば "Unexpected tokens after JSON value"(位置付き) - -JsonNode 振る舞い(文字列表現の安定化) -- create_*: null/bool/int/float/string/object/array を提供 -- number: 入力文字列を value として保持(整数/浮動の区別は presence で行う) -- stringify: - - null/bool はリテラル文字列 - - int は "" + value(文字列化)、float は入力文字列のまま(丸め差を回避) - - string は EscapeUtils.quote_string() を使用 - - array は各要素 stringify を ',' 連結、object は key(入力順)で '"k":v' を ',' 連結 - -移行計画(段階導入) -- quick: heavy JSON(nested/roundtrip/query_min)を現状 SKIP → Parser 完成後に既定ONへ -- integration: LLVM ハーネスで VM↔LLVM を比較、差分ゼロを維持 -- 破壊的変更はなし。既存APIの意味保持(parse が null を返す契約は変更しない) - -受け入れ基準(詳細) -- 正常系: 代表20ケース(null/bool/数値/文字列/配列/オブジェクト/ネスト/Unicode)で parse→stringify が期待と一致 -- 異常系: 先頭ゼロ/指数桁不足/未知エスケープ/未終端文字列/余剰トークン で位置付きエラー -- quick=ALL PASS(heavy JSON 有効)、integration=PASS - -実装順(M1 内) -1) Tokenizer: keyword の完全一致化(部分一致禁止)と read_number の厳密化(先頭ゼロ)→済 -2) Parser: トークン駆動の再帰下降に整理(value/object/array/string/number、位置付きエラー) -3) JsonNode.stringify の表現安定化(数値/文字列/配列/オブジェクト) -4) スモーク: heavy JSON を quick で既定ON、integration 再確認 - ---- - -2025-09-27 follow-up — quick heavy JSON default ON (with safe probe) - -- Enabled heavy JSON smokes by default in quick profile, guarded by a lightweight probe to avoid flakiness when the heavy parser is not yet available on a given VM build. - - Updated scripts: tools/smokes/v2/profiles/quick/core/json_nested_vm.sh, json_roundtrip_vm.sh (added probe and default ON). json_query_min_vm.sh already had a probe. - - Behavior: runs by default; if `JsonParserModule.parse("[]"|"null")` returns null, the test reports SKIP. - -- JSON libs hardening (constructor-arg guard) - - apps/lib/json_native/lexer/scanner.nyash: added `reset_text(input_text)` to reinitialize scanner state safely. - - apps/lib/json_native/lexer/tokenizer.nyash: constructor now calls `reset_text(...)`; added `set_input(...)` helper. - - apps/lib/json_native/parser/parser.nyash: `parse(...)` calls `tokenizer.set_input(json_text)` before tokenization. - -- Known issue to track (VM birth arg path) - - On this environment, NUMBER/STRING tokens show empty type/value in diagnostics, suggesting `new JsonToken(type, value, ...)` argument loss on the VM birth path. Structural tokens (LBRACE/COMMA etc.) are correct. - - Next: confirm NewBox→birth(arg...) preservation for JsonToken on VM; once fixed, remove the probe SKIPs and keep heavy JSON always-on without skips. - -Acceptance guard for this step -- quick: remains green (heavy tests run when available; otherwise SKIP) -- integration: unchanged - - diff --git a/CURRENT_TASK_restored.md b/CURRENT_TASK_restored.md deleted file mode 100644 index 6bc4dfcd..00000000 --- a/CURRENT_TASK_restored.md +++ /dev/null @@ -1,955 +0,0 @@ -# Restart Notes — Ny Syntax Alignment (2025‑09‑07) - -目的 -- Self‑Hosting 方針(Nyのみで工具を回す前段)に合わせて、Ny 構文とコーディング規約を明示化し、最小版ツールの完走性を優先。 - -Ny 構文(実装時の基準) -- 1行1文/セミコロン非使用。 -- break / continue を使わない(関数早期 return、番兵条件、if 包みで置換)。 -- else は直前の閉じ波括弧と同一行(`} else {`})。 -- 文字列の `"` と `\` は確実にエスケープ。 -- 反復は `loop(条件) { …; インクリメント }` を基本とし、必要に応じて「関数早期 return」型で早期脱出。 - -短期タスク(Syntax 合意前提で最小ゴール) -1) include のみ依存木(Nyのみ・配列/マップ未使用)を完走化 - - `apps/selfhost/tools/dep_tree_min_string.nyash` - - FileBox/PathBox + 文字走査のみで JSON 構築(配列/マップに頼らない) - - `make dep-tree` で `tmp/deps.json` を出力 -2) using/module 対応は次段(構文・優先順位をユーザーと再すり合わせ後) - - 優先: `module > 相対 > using-path`、曖昧=エラー、STRICT ゲート(要相談) -3) ブリッジ Stage 1 は保留 - - `NYASH_DEPS_JSON=` 読み込み(ログ出力のみ)を最小パッチで用意(MIR/JIT/AOT は不変) - -備考 -- Cranelift 側の作業は別ブランチで継続。Self‑Hosting ブランチは Ny 工具の安定化に集中。 -- 構文の最終合意後、using/module 版(配列/マップ最小 API)へ拡張。 - - -## Grammar Sync — Phase 12.7 合わせ(現状と方針) - -参照ドキュメント(一次ソース) -- Phase 12.7 統合: `docs/development/roadmap/phases/phase-12.7/README.md` -- Grammar 最終決定: `docs/development/roadmap/phases/phase-12.7/grammar-specs/grammar-reform-final-decision.txt` -- Grammar 技術仕様: `docs/development/roadmap/phases/phase-12.7/grammar-specs/grammar-technical-spec.txt` -- 実装チェックリスト: `docs/development/roadmap/phases/phase-12.7/implementation/implementation-final-checklist.txt` -- ANCP Token Spec (参照): `docs/development/roadmap/phases/phase-12.7/ancp-specs/ANCP-Token-Specification-v1.md` - -実装状況(Phase 12.7 との整合) -- OK: `peek`(else必須・ブロック可)、`continue`、`birth` 統一、`fn{}` ラムダ(P0)、糖衣 basic(`|>`, `?.`, `??`, `+=/-=/*=/=`, `..`)ゲート済。 -- OK: `Parent::method` 用 `::` トークン+ `Parent::method(args)` 解析(P1相当の先行)。 -- OK: フィールド宣言 `name: Type` を受理(P0: 型はパースのみ、意味付けは今後)。 -- 差分(非致命): - - import 未実装(現状は `using` のみ Phase0: `nyashstd` 制限)。 - - `public name: Type` の単行は未対応(`public { ... }` ブロックは対応)。 - - レガシー `>>`(ARROW)トークンとASTが残存(12.7 では不要)。 - - Tokenizer に `fn` の重複割り当て(`FN`/`FUNCTION`)が存在(動作は壊していないが整理対象)。 - -合意に向けた軽微タスク(Self‑Hosting 主線を維持したまま) -- T1: `public name: Type` 単行を Box 内で受理(`public { ... }` は後方互換維持)。 -- T2: `import` を追加(現状 `using` と並行運用、Phase0は読み取りのみ/将来の解決器に接続)。 -- T3: 12.7 厳格モードゲート(例: `NYASH_STRICT_12_7=1`) - - `>>` を無効化(パーサ拒否 or トークナイズ抑止)。 - - 追加キーワード群(legacy拡張)の一部を“識別子扱い”へフォールバック(実験用)。 -- T4: Tokenizer の `fn` 重複を解消(`FN` を正とし `FUNCTION` 二重割り当てを削除)。 - -受け入れ基準(Grammar Sync) -- sugar_level=none/basic の双方でスモークが通る。 -- `peek` else 未指定時に適切なエラー(現状維持)。 -- `public name: Type` が Box 内でフィールドとして扱われる(最小P0)。 -- 厳格モードで `>>` が受理されない/互換モードでは現状維持。 - -検証コマンド(例) -- `NYASH_SYNTAX_SUGAR_LEVEL=none cargo test -p nyash_self_main -- tests::sugar_basic_test -- --nocapture`(none でも tokenizer/parseは通ること) -- `NYASH_SYNTAX_SUGAR_LEVEL=basic cargo test -p nyash_self_main -- tests::sugar_pipeline_test -- --nocapture` -- `NYASH_STRICT_12_7=1 ./target/release/nyash --backend vm apps/smokes/grammar/peek_basic.nyash`(`>>` を含むコードが拒否される) - -## Bitwise/Shift — main 取り込みと現状 - -- origin/main でビット演算(&, |, ^, <<, >>)が Grammar/Tokenizer/AST/MIR に統合済み。レガシー `>>` ARROW は撤退。 -- 追加テスト(main): - - `src/tests/parser_bitops_test.rs`(代表式 `1 + 2 << 3 & 7` の構文) - - `src/tests/vm_bitops_test.rs`(`(5&3)+(5|2)+(5^1)+(1<<5)+(32>>3) == 48`、`1<<100` マスク確認) -- 確認結果(ローカル): - - MIR バックエンドは 48 で合格(OK)。 - - VM バックエンドは現状 `Unsupported integer operation: BitAnd`(VM 側の実装が未導入のため) - -取り込み計画(selfhosting-dev に main を統合) -1) ローカル変更を一時退避(stash)し、`origin/main` をマージ。 -2) コンフリクト解消:`src/jit/lower/builder/cranelift.rs` は main 側の更新(ARROW撤退/SHR採用)を優先。 -3) 検証:MIR 経路で bitops スモーク(期待 48)。 -4) 次段:VM の bitops(i64限定、シフトは `rhs&63` マスク)を実装→テスト有効化。 -5) LLVM/E2E:grammar 解禁後に `apps/tests/ny-llvm-bitops/` を有効化(MIR直構築は現状担保)。 - -実行メモ(代表) -- MIR スモーク: `printf "return (5 & 3) + (5 | 2) + (5 ^ 1) + (1 << 5) + (32 >> 3)\n" > tmp/bitops_smoke.nyash && ./target/debug/nyash --backend mir tmp/bitops_smoke.nyash` → `Result: 48` -- VM は現状未対応(実装後に同式で確認)。 - -TODO(bitops) -- [ ] origin/main を selfhosting-dev にマージ(conflict 解消)。 -- [ ] MIR 経路のスモーク確認(48)。 -- [ ] VM: i64 の `& | ^ << >>` 実装(`rhs&63` マスク)。 -- [ ] tests: `vm_bitops_test.rs` を有効化(VM で合格)。 -- [ ] docs: ARROW(>>) 撤退と `|>` への一本化を明記。 - -## Self‑Host — Include‑only Dependency Tree(Phase 0) - -スコープ(Phase 0 最小) -- Nyのみ(Array/Map不使用)で include 依存木を構築し、純JSONを出力。 -- using/module/import は次段。Runner は `NYASH_DEPS_JSON` をログ読み込みのみ。 - -現状 -- ツール: `apps/selfhost/tools/dep_tree_min_string.nyash`(include専用、再帰・文字列走査)。 -- 出力: `make dep-tree` → `tmp/deps.json`(純JSON化、先頭ログの除去は `[tasks].dep_tree` で吸収)。 -- 走査: コメント(`//`, `#`)・文字列内の `include` を無視する状態機械を導入(誤検出抑制)。 -- サンプル: `apps/selfhost/smokes/dep_smoke_root.nyash`(子: `dep_smoke_child.nyash`)。 - -出力仕様・受け入れ基準: docs/development/current/selfhost/dep_tree_min_string.md に移設(CURRENT_TASKは要点のみ表記)。 - -残タスク(Phase 0 必須) -- P0-2: スモーク(循環あり/なし)と合わせて確認(追加済み)。 -- P0-3: docs への移設(完了)。 - -任意(Phase 0.5) -- stderr固定の徹底(将来Runner側の冗長出力をenvゲート化)。 -- ルートパスの正規化(`.`,`..` の整理)と最大深さ/件数の安全弁(オプション)。 - -検証(代表) -- `echo apps/selfhost/smokes/dep_smoke_root.nyash | ./target/release/nyash --backend vm apps/selfhost/tools/dep_tree_min_string.nyash` -- `echo apps/selfhost/smokes/dep_smoke_cycle_a.nyash | ./target/release/nyash --backend vm apps/selfhost/tools/dep_tree_min_string.nyash` -- `make dep-tree`(ENTRYは標準入力1行 or 既定パスにフォールバック) - -# Quick Plan — Self‑Host (Restart Safe) - -- Goals: Ny-only dependency tree (include → later using/module), JSON out; simple file-bridge to existing MIR→VM→AOT without tight coupling. -- Deliverables: - - Minimal tool: `apps/selfhost/tools/dep_tree_min_string.nyash` (include-only, recursion via FileBox/PathBox, no Array/Map) - - Full tool: `apps/selfhost/tools/dep_tree_simple.nyash` (include + using/module, strict/explicit resolution) - - Task/Make: `nyash.toml [tasks].dep_tree` and `make dep-tree` (outputs `tmp/deps.json`) - - Bridge Stage 1: Runner reads `NYASH_DEPS_JSON=` and logs (no behavior change) -- Order: - 1) Finish include-only tool to completion (Ny-only, strict 1‑statement lines) - 2) Harden full tool (using/module, module > relative > using-path, ambiguous=error, STRICT gate) - 3) Add Runner hook for `NYASH_DEPS_JSON` (log only) -- Quick run: - - `make dep-tree` → writes `tmp/deps.json` - - `./target/release/nyash --run-task dep_tree` - - -# CURRENT TASK (Compact) — Phase 15 / Self-Hosting(Ny→MIR→MIR-Interp→VM 先行) - -このドキュメントは「いま何をすれば良いか」を最小で共有するためのコンパクト版です。詳細は git 履歴と `docs/`(phase-15)を参照してください。 - -— 最終更新: 2025‑09‑08 (LLVM Core‑13 安定化 P0 進捗更新) - -【Quick Update — LLVM Core‑13 P0】 -現状 -- ビルド環境は LLVM 18 検出済み(`LLVM_SYS_180_PREFIX=/usr/lib/llvm-18`)。 -- 代表的なビルドエラーは次の3点に収束。 - 1) Opaque Pointer 由来: `PointerType::get_element_type()` 不在 → i8* 判別経路をヒューリスティックに簡素化。 - 2) IntegerBox API: `.value()` 誤用 → `.value` に修正(フィールド参照)。 - 3) BinaryOp 網羅: BitAnd/BitOr/BitXor/Shl/Shr 未対応 → いったん `_ => todo!()` で回避。 - -対応済み -- `src/backend/llvm/compiler.rs` - - `env.box.new` の opaque 対応(i8* は `nyash.box.from_i8_string` を呼ぶ単純化)。 - - `.value()`→`.value` を修正(BinOpパス)。 - - 末尾 mock BinOp に `_ => todo!()` を追加。 - -残タスク(P0完了条件) -- `env.box.new`(new_i64x 側)の引数 i64 化クロージャを完全インライン化(lifetime エラー解消)。 -- BinOp 未網羅の match 箇所をもう1か所整理(`_ => todo!()` か軽実装)。 -- 再ビルド通過後、代表スモークの一致確認。 - -代表スモーク -- ビルド: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) cargo build --release --features llvm` -- 実行: `tools/build_llvm.sh apps/tests/mir-compare-multi/main.nyash -o app && ./app` -- 受け入れ: VM と同一の戻り値(Core‑13 正規化パスに依存:`NYASH_MIR_CORE13=1` 既定ON) - -メモ -- 作業ディレクトリ: `/mnt/c/git/nyash-project/nyash_llvm`(branch: `llvm-dev`) -- 次の commit で P0 を締め、P1(ビット演算/Shift 実装)に移行する。 - -【Phase 17.1 — LLVM Core‑13 安定化(専用worktree/branch)】 -目的 -- Core‑13 正規化後の MIR を LLVM AOT に下ろし、VM と同値の代表ケースを安定動作させる。 - -作業環境 -- worktree: /mnt/c/git/nyash-project/nyash_llvm (branch: llvm-dev, origin/llvm-dev 追従) -- LLVM 18 前提: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix)` - -短期タスク(P0) -- Opaque Pointer 対応: Inkwell 0.6 + LLVM 18 に合わせ、`get_element_type()` 等を使用しない降ろしに修正。 - - `env.box.new` の引数ハンドリングをヒューリスティックに単純化(i8* は `nyash.box.from_i8_string`) -- IntegerBox API 整合: `.value()` → `.value` に是正(フィールド参照)。 -- BinaryOp の網羅性: `BitAnd/BitOr/BitXor/Shl/Shr` 未対応を `_ => todo!()` で一旦回避(代表スモーク優先)。 - -検証(P0) -- ビルド: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) cargo build --release --features llvm` -- 代表スモーク: `tools/build_llvm.sh apps/tests/mir-compare-multi/main.nyash -o app && ./app`(VM一致) - -後続(P1) -- ビット演算/シフトの実装と検証(LLVM 降ろし/IR 生成/実行互換)。 -- AOT 実行の戻り値と型変換経路の整理(i64/handle→Box materialize)。 - -【ハンドオフ(2025‑09‑06 final)— String.length 修正 完了/JIT 実行を封印し四体制へ】 - -概要 -- 目的: AOT/JIT‑AOT で発生していた `StringBox.length/len` が 0 になる不具合の是正(Lower の二段フォールバック:`nyash.string.len_h` → `nyash.any.length_h`)。 -- 結果: 当該不具合は修正・確認完了(AOT/VM で期待値)。JIT 直実行の継続調査は打ち切り、実行モードは「インタープリター/VM/Cranelift(EXE)/LLVM(EXE)」の4体制へ移行。 - -【Phase 15.17 追記 — Core‑13 純化モード 実装/稼働・AOT shim 拡張】 -概要 -- Core‑13 純化モード(厳格)を導入: `NYASH_MIR_CORE13_PURE=1` - - Builder 段: `new`→`ExternCall(env.box.new, [type, …args])` を直接生成(`NewBox/birth` 非生成) - - Unary(−/!/~): 直接展開(`Const+BinOp/Compare`) - - WeakRef(weak_new/load): 純化ONでは生成回避(パススルー) - - Optimizer 安全網: Load/Store→`env.local.get/set` 変換、最終MIRで13命令以外はエラー -- 実行系: - - VM: `env.local.get/set` と `env.box.new` を実装(BoxFactoryRegistry 連動) - - LLVM AOT: `env.local.get/set` の Lowering と `env.box.new` shim を追加 - - NyRT 追加: `nyash.env.box.new` / `nyash.env.box.new_i64x` (最大4引数) - - NyRT 追加: `nyash.box.from_i8_string`(i8*→StringBox)、`nyash.box.from_f64`(f64→FloatBox) - - Lowering: 引数を i64 ハンドルに正規化(int/ptr→i64、i8*→from_i8_string、f64→from_f64) - - Cranelift (スケルトン): `env.local.get/set` / `env.box.new` を実行ループに最小実装(将来のAOT出力の布石) - -検証 -- `cargo test`: 206 passed / 0 failed / 24 ignored(通常) -- 純化ON(選択的 skip あり): グリーン。`src/tests/mir_pure_envbox.rs` 追加で `env.box.new` 生成を検証 - -実装(済) -- LowerCore: 二段フォールバック実装を追加(Param/Local/リテラル)。 - - `emit_len_with_fallback_param`/`_local_handle`/`_literal` - - `core.rs` の `len/length` で二段フォールバックを使用。結果をローカルスロットへ保存(Return で拾えるように) -- BoxCall 共通(ops_ext): - - StringBox の `len/length` を最優先で処理(Param/Local/リテラル/handle.of)。 - - リテラル `new StringBox("...")` → `length` は即値畳み込み(const 返却)。 -- Hostcall registry 追補: `nyash.string.len_h` を ReadOnly 登録 + 署名 `(Handle)->I64` 追加。 -- JIT ブリッジ: `extern_thunks.rs` に `nyash_string_len_h` を追加、`cranelift` ビルダーに `SYM_STRING_LEN_H` を登録。 -- ポリシー: `StringBox.length/len` マッピングを `nyash.any.length_h` → `nyash.string.len_h` に是正。 -- デッドコード整理: 旧 `lower_boxcall_simple_reads` を削除(conflict 回避)。 -- ツール/スモーク: `tools/aot_smoke_cranelift.sh` 追加、`apps/smokes/jit_aot_string_length_smoke.nyash` 追加。 - -— 15.17 追加 実装(済) -- Core‑13 純化モード: `NYASH_MIR_CORE13_PURE=1`(Builder/Optimizer/Verifier 連携) -- VM: `env.local.get/set`, `env.box.new` を実装 -- LLVM AOT: `env.box.new` shim(new/new_i64x)+ 引数 i8*/f64 のハンドル化 helper 追加 -- Cranelift: ExternCall の最小実装(get/set/new)を追加(スケルトン) -- テスト: `src/tests/mir_pure_envbox.rs` 追加(純化 new→env.box.new の生成確認) -- テスト: `src/tests/mir_pure_e2e_vm.rs` 追加(純化ONで VM 実行: new StringBox + length の e2e) -- テスト: `src/tests/mir_pure_locals_normalized.rs` 追加(locals が env.local.get/set に正規化されることを確認) -- テスト: `src/tests/mir_pure_llvm_build.rs` 追加(feature=llvm 時に純化ONで .o を正常生成できることを確認。実行の同値性はAOT実装拡張後に別途追加予定) -- テスト: `src/tests/mir_pure_e2e_arith.rs` 追加(純化×VMで加算の e2e) -- テスト: `src/tests/mir_pure_e2e_branch.rs` 追加(純化×VMで条件分岐の e2e) -- テスト: `src/tests/mir_pure_only_core13.rs` 追加(最終MIRが13命令のみで構成されることを静的検査) -- CI: Core‑13 純化(LLVM) ワークフロー追加(`.github/workflows/core13-pure-llvm.yml`)。LLVM 18 をセットアップし、`--features llvm` で純化ONテストを実行。 -- CI: Core‑13 純化モード専用ワークフローを追加(`.github/workflows/core13-pure.yml`)。`NYASH_MIR_CORE13_PURE=1 cargo test --all-targets` を実行。 - -確認状況(最終) -- `apps/smokes/jit_aot_string_min.nyash`(concat/eq): AOT で `Result: 1`(OK)。 -- `apps/smokes/jit_aot_string_length_smoke.nyash`: AOT .o 生成/リンク・実行とも良好(稀発の segfault 調査は「低優先」に移行)。 -- `apps/smokes/jit_aot_any_len_string.nyash`: AOT で `Result` が期待値(0 問題は解消)。 -- 備考: JIT 直実行の既知の不安定性は、JIT 実行封印に伴い調査終了とする(アーカイブ扱い)。 - -残課題(方針更新後) -P0: 実行モード整理(JIT 実行封印) -- ランタイム実行は「Interpreter/VM」に限定。ネイティブ配布は「Cranelift AOT(EXE)/LLVM AOT(EXE)」。JIT 関連のランタイムフラグ説明は docs で封印明記。 - -P1: AOT 安定化(低頻度 segfault の追跡:低優先) -- 稀な DT_TEXTREL 警告・segfault は PIE/LTO/relro/TLS/extern 登録順の再確認を残課題として維持(優先度は下げる)。 - -P2: リファクタ(Phase A)継続(振る舞い不変) -- Hostcall シンボル `SYM_*` 統一、`core/string_len.rs` への集約、観測フックの整理は継続。JIT 実行依存の観測は停め、VM/AOT 観測を優先。 - -P3: Core‑13 純化 仕上げ(今回の続き) -- Cranelift AOT: 実オブジェクト出力で `env.local/env.box` のシンボル連携(現状は実行スケルトンのみ) -- LLVM AOT: `env.box.new_i64x` の引数拡張(>4, TLV支援)と型復元の精度UP(文字列/浮動/配列 等) -- Builder 純化の徹底: Load/Store/WeakRef を完全非生成(全経路点検) -- E2E 純化スモーク: `apps/smokes_pure13/` を追加(VM/LLVM EXE の結果一致) -- CI: 純化ON ジョブを常時実行(最終MIR 13命令チェック含む) - -進捗(2025‑09‑06 終了報告) -- ops_ext: StringBox.len/length の結果を必ずローカルに保存するよう修正(Return が確実に値を拾える) - - 対象: param/local/literal/handle.of 各経路。`dst` があれば `local_index` に slot を割当てて `store_local_i64`。 -- デバッグ計測を追加 - - JIT Lower 追跡: `NYASH_JIT_TRACE_LOWER=1`(BoxCall の handled 判定/box_type/dst 有無) - - Return 追跡: `NYASH_JIT_TRACE_RET=1`(known/param/local の命中状況) - - ローカルslot I/O: `NYASH_JIT_TRACE_LOCAL=1`(`store/load idx=` を吐く) - - String.len_h 実行: `NYASH_JIT_TRACE_LEN=1`(thunk 到達と any.length_h フォールバック値を吐く) -- 再現確認 - - `apps/smokes/jit_aot_any_len_string.nyash` は依然 Result: 0(JIT-direct)。 - - 追跡ログ(要 `NYASH_JIT_TRACE_LOWER=1 NYASH_JIT_TRACE_RET=1 NYASH_JIT_TRACE_LOCAL=1`) - - `BoxCall ... method=length handled=true box_type=Some("StringBox") dst?=true` - - ローカル slot の流れ: `idx=0` recv(handle) → `idx=1` string_len → `idx=2` any_len → `idx=3` cond → select → `idx=4` dst 保存 → Return で `load idx=4` - - つまり lowering/Return/ローカル材化は正しく配線されている。 -JIT 直実行に関する未解決点(import 解決先の差異疑い 等)は封印に伴いアーカイブ化。必要時に `docs/development/current/` へ復元して再開する。 - -暫定変更(フォールバック強化) -- `ops_ext` の StringBox.len で「リテラル復元(NewBox(StringBox, Const String))」を param/local より先に優先。 - - JIT-AOT 経路で文字列リテラルの length は常に即値化(select/hostcall を経由せず 3 を返す)。 - - ただし今回のケースでは local 経路が発火しており、まだ 0 のまま(hostcall 実行が 0 を返している疑い)。 - -未解決/次アクション(デバッグ指針) -- [ ] `nyash.string.len_h` が実際にどの関数へリンクされているかを確認 - - Cranelift JIT: `src/jit/lower/builder/cranelift.rs` の `builder.symbol(...)` 群は設定済みだが、実行時に thunk 側の `eprintln` が出ない。 - - 追加案: `emit_host_call` で宣言した `func_id` と `builder.symbol` 登録可否の整合をダンプ(シンボル直列化や missing import の検知)。 -- [ ] `extern_thunks::nyash_string_len_h` へ確実に到達させるため、一時的に `emit_len_with_fallback_*` で `SYM_STRING_LEN_H` を文字列リテラル直書きではなく定数経由に統一。 -- [ ] `nyash.string.from_u64x2` の呼び出し可否を同様にトレース(`NYASH_JIT_TRACE_LOCAL=1` の直後に `NYASH_JIT_TRACE_LEN=1` が見えるか) -- [ ] ワークアラウンド検証: `NYASH_JIT_HOST_BRIDGE=1` 強制でも 0 → host-bridge 経路の呼び出しが発火していない可能性。bridge シンボル登録も再確認。 - -メモ/所見 -- lowering と Return 材化(ローカルslot への保存→Return で load)は動いている。値自体が 0 になっているので hostcall 側の解決/戻りが疑わしい。 -- AOT .o の生成は成功。segv は今回は再現せず。 - -実行コマンド(デバッグ用) -- `NYASH_JIT_TRACE_LOWER=1 NYASH_JIT_TRACE_RET=1 NYASH_JIT_TRACE_LOCAL=1 NYASH_AOT_OBJECT_OUT=target/aot_objects/test_len_any.o ./target/release/nyash --jit-direct apps/smokes/jit_aot_any_len_string.nyash` -- 追加で thunk 到達確認: `NYASH_JIT_TRACE_LEN=1 ...`(現状は無出力=未到達の可能性) - -Phase A 進捗(実施済) -- A‑1: Hostcall シンボルの定数化(直書き排除)完了 - -【ハンドオフ(2025‑09‑06 4th)— GUI/egui 表示テスト計画(Cranelift/LLVM × Windows/WSL)】 - -目的 -- 以前は Windows exe で egui ウィンドウ表示を確認できていたが、現状で再現が不安定な報告あり。Cranelift/LLVM と OS 組み合わせ別に手順と期待結果を明文化し、再現性を担保する。 - -前提・重要ポイント -- プラグイン版 EguiBox は Windows 専用で実ウィンドウ分岐(`#[cfg(all(windows, feature = "with-egui"))]`)。Linux/WSL では `run()` はスタブ(void)でウィンドウは出ない(X 転送の有無に関係なく)。 -- Windows でウィンドウ表示を行うには、`nyash-egui-plugin` を `--features with-egui` でビルドし、`nyash.toml` の `plugin_paths`(または `NYASH_PLUGIN_PATHS`)に DLL のパスが解決できること。 -- Linux でウィンドウ表示を確認したい場合は「Rust 例(gui_simple_notepad)」または「ビルトイン EguiBox(nyash 本体を `--features gui` でビルドし、専用 Nyash スクリプトを使用)」を利用する。 - -テストマトリクス(手順と期待結果) -1) Windows × Cranelift(JIT-direct/EXE 相当) - - 準備: `cargo build --release --features cranelift-jit` - - プラグイン: `cargo build -p nyash-egui-plugin --release --features with-egui` - - 実行(JIT-direct 経路): `powershell -ExecutionPolicy Bypass -File tools\egui_win_smoke.ps1` - - 期待: Egui ウィンドウが表示される(アプリ終了までブロッキング)。 - -2) Windows × LLVM(EXE/直実行) - - LLVM 準備: `tools\windows\ensure-llvm18.ps1 -SetPermanent` - - プラグイン: `cargo build -p nyash-egui-plugin --release --features with-egui` - - Nyash 本体: `cargo build --release --features llvm` - - 直実行: ` .\target\release\nyash.exe --backend llvm apps\egui-hello\main.nyash` - - AOT EXE: `tools\build_llvm.ps1 apps\egui-hello\main.nyash -Out egui_hello.exe` → ` .\egui_hello.exe` - - 期待: どちらの経路でも Egui ウィンドウが表示される(DLL が `plugin_paths` に解決可能であること)。 - -3) WSL × Cranelift(JIT-direct/EXE 相当) - - 準備: `cargo build --release --features cranelift-jit` - - 実行: `./target/release/nyash --jit-direct apps/egui-hello/main.nyash` - - 期待: 実ウィンドウは出ない(プラグインの `run()` はスタブ)。エラーなく終了(void)。 - - 備考: GUI 表示が必要な場合は Rust 例(`cargo run --features gui-examples --example gui_simple_notepad --release`)を利用。 - -4) WSL × LLVM(EXE/直実行) - - 準備: `./tools/llvm_check_env.sh` → `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) cargo build --release --features llvm` - - 実行: `./target/release/nyash --backend llvm apps/egui-hello/main.nyash` - - 期待: 実ウィンドウは出ない(スタブ)。 - - 備考: GUI 表示が必要な場合は Rust 例、もしくは nyash 本体を `--features gui` でビルドし、ビルトイン EguiBox 用の Nyash スクリプトを別途用意(要サンプル整備)。 - -診断スイッチ(共通) -- `NYASH_DEBUG_PLUGIN=1`: プラグインのロードパス/解決状況を表示 -- `NYASH_CLI_VERBOSE=1`: プラグインホスト初期化やランタイムの詳細ログ -- Windows/プラグインの DLL 解決が怪しい場合は `NYASH_PLUGIN_PATHS` で DLL ディレクトリを明示(`;` 区切り) - -既知の制約 / TODO -- Linux/WSL でプラグイン版 EguiBox の `run()` は現在スタブ(実ウィンドウなし)。将来的に `#[cfg(target_os = "linux")]` 分岐で eframe 実装を追加し、X11/Wayland でも表示可能にする。 -- ビルトイン EguiBox(`src/boxes/egui_box.rs`)は `--features gui` でビルド時に有効。Nyash スクリプト側の API はプラグイン版と異なる(`setTitle/setSize/addText/run`)。Linux GUI 確認用にビルトイン用サンプル(apps/egui-builtin/)を追加して整備する。 -- Windows AOT リンクは MSVC `link.exe` を既定(fall back: clang)。lld へのスイッチ(速度優先)を将来オプション化検討。 - -次アクション(引き継ぎ TODO) -- [ ] Windows: 4通りの実行(Cranelift 直/JIT、LLVM 直、AOT EXE)で `apps/egui-hello/main.nyash` のウィンドウ表示を再確認(`NYASH_DEBUG_PLUGIN=1` でログ採取)。 -- [ ] WSL: Cranelift/LLVM の直実行は「スタブ終了」が期待値であることを README/ガイドに明記。GUI が必要なら Rust 例 or ビルトイン EguiBox 経路を案内。 -- [ ] Linux 向けプラグイン `with-egui` 実装の導入可否を検討(`plugins/nyash-egui-plugin/src/lib.rs` の `winrun` と類似の `linrun` を追加)。 -- [ ] ビルトイン EguiBox 用の Nyash サンプルを `apps/egui-builtin/` として追加し、`--features gui` での手順を `dev/selfhosting/` または `docs/` に追記。 - - `nyash.handle.of` / `nyash.string.len_h` / `nyash.console.birth_h` を `SYM_*` に統一 -- A‑2: string_len ヘルパ抽出(共通化)完了 - - `src/jit/lower/core/string_len.rs` 新設、`emit_len_with_fallback_*` を移設 - - 呼び出し元はそのまま(挙動は不変) -- A‑3: 観測の統一(第一弾) - - string_len 内で `observe::lower_hostcall` を発火(len_h/any.length_h) - - Cranelift/ObjectBuilder の `emit_host_call[_typed]` に `NYASH_JIT_TRACE_IMPORT=1` によるインポート解決ログを追加 - -観測結果(A‑3 導入後) -- `NYASH_JIT_TRACE_IMPORT=1` で `nyash.string.len_h` / `nyash.any.length_h` の import 呼び出しを確認(JIT/AOT 両方) -- それでも `NYASH_JIT_TRACE_LEN=1` の thunk 到達ログは出ず → 依然解決先に差異がある疑い(要継続調査) - -■ 実行系の最終方針(Phase 15 着地) -- ランタイム: Interpreter / VM -- 配布: Cranelift AOT (EXE) / LLVM AOT (EXE) -- JIT 直実行: 封印(ドキュメント上も「実験的/無効」へ集約) - -■ 検証チェックリスト(更新) -- VM: `./target/release/nyash --backend vm apps/smokes/jit_aot_string_min.nyash` → Result:1 -- AOT(Cranelift): `./tools/build_aot.sh apps/smokes/jit_aot_string_length_smoke.nyash -o app` → `./app` 実行 → 期待結果 -- AOT(Windows one‑shot): `pwsh -File tools/windows/build_egui_aot.ps1 -Input apps/egui-hello-plugin/main.nyash -Out app_egui` → 画面表示 - - -— Phase A(無振る舞い変更)リファクタ方針(継続) -- A‑1: Hostcall シンボルを定数に統一(直書き排除) - - `"nyash.handle.of"` → `jit::extern::handles::SYM_HANDLE_OF` - - `"nyash.string.len_h"` → `jit::extern::collections::SYM_STRING_LEN_H` - - `"nyash.console.birth_h"` → 既存の定数へ(なければ `extern::...` に追加して使用) -- A‑2: 長さ取得の共通化 - - 新規: `src/jit/lower/core/string_len.rs` - - 既存の `emit_len_with_fallback_{param,local,literal}` をこのモジュールへ抽出し、`core.rs`/`ops_ext.rs` から呼び出すだけにする(挙動は据え置き)。 - - 目的: 重複と分岐のばらけを解消し、シンボル差し替えや観測フックを一点で行えるようにする。 -※ Phase A は「振る舞いを変えない」ことを厳守する。 - -2) 診断イベントの追加(軽量) - - `emit_len_with_fallback_*` と `lower_box_call(len/length)` に `observe::lower_hostcall` を追加し、 - Param/Local/リテラル/handle.of どの経路か、select の条件(string_len==0)をトレース可能にする(`NYASH_JIT_EVENTS=1`)。 - -3) AOT segfault (稀発) の追跡(低優先) - - `tools/aot_smoke_cranelift.sh` 実行中に稀に segv(`.o` 生成直後/リンク前後)。 - - `nyash.string.from_u64x2` 載せ替えと DT_TEXTREL 警告が出るので、PIE/LTO/relro 周りと TLS/extern の登録順を確認。 - -4) 警告のノイズ低減(低優先) - - `core_hostcall.rs` の unreachable 警告(case 統合の名残)。 - - `jit/lower/*` の unused 変数/unused mut の警告。 - -影響ファイル(今回差分) -- `src/jit/lower/core.rs`(len/length 二段フォールバック呼出し、保存強化) -- `src/jit/lower/core/ops_ext.rs`(StringBox len/length 優先処理、リテラル即値畳み込み、保存) -- `src/jit/hostcall_registry.rs`(`nyash.string.len_h` 追補) -- ドキュメント: README(ja/en) の実行モード更新、ガイド(egui AOT)に one‑shot スクリプト反映 -- `src/jit/extern/collections.rs`(`SYM_STRING_LEN_H` 追加) -- `src/jit/lower/extern_thunks.rs`(`nyash_string_len_h` 追加) -- `src/jit/lower/builder/cranelift.rs`(`SYM_STRING_LEN_H` のシンボル登録) -- `tools/aot_smoke_cranelift.sh`(新規) -- `apps/smokes/jit_aot_string_length_smoke.nyash`(新規) - -再現/確認コマンド -- ビルド(JIT/AOT): `cargo build --release --features cranelift-jit` -- JIT‑AOT(.o出力): `NYASH_AOT_OBJECT_OUT=target/aot_objects/test_len_any.o ./target/release/nyash --jit-direct apps/smokes/jit_aot_any_len_string.nyash` -- AOT 連結〜実行: `bash tools/aot_smoke_cranelift.sh apps/smokes/jit_aot_string_min.nyash app_str` - -次アクション(引き継ぎ TODO) -- [ ] Return の後方走査材化を実装(BoxCall/Call/Select 等の定義→保存→Return 接続)。 -- [ ] `emit_len_with_fallback_*` / `lower_box_call(len/length)` にイベント出力を追加(選択分岐/経路ログ)。 -- [ ] AOT segv の最小再現収集(PIE/relro/TLSの前提確認)→ `nyrt` 側エクスポート/リンカフラグ点検。 -- [ ] `NYASH_USE_PLUGIN_BUILTINS=1` 時の `length` も robust path を常に使用することを E2E で再確認。 -- [ ] Cranelift AOT: `env.local/env.box` を実オブジェクト出力に反映(link/name 解決の道付け) -- [ ] LLVM AOT: `nyash.env.box.new_i64x` の引数≥5およびTLV化の検討、引数型の復元精度UP -- [ ] Builder 純化の網羅化(Load/Store/WeakRef 非生成の全経路テスト追加) -- [ ] 純化ON E2E スモーク(VM/LLVM)と CI 常時ジョブの追加 - -メモ -- `jit_aot_any_len_string.nyash` は `return s.length()` の Return 経路解決が決め手。材化を強化すれば `3` が期待値。 -- 既存の Array/Map 経路・他の smokes は影響なし(len/size/get/has/set の HostCall/PluginInvoke は従来どおり)。 - -■ 進捗サマリ -- Phase 12 クローズアウト完了。言語糖衣(12.7-B/P0)と VM 分割は反映済み。 -- Phase 15(Self-Hosting: Cranelift AOT)へフォーカス移行。 - - 設計/仕様ドキュメントとスモーク雛形を追加済み。 - - 設計: `docs/design/backend-cranelift-aot-design.md` - - API案: `docs/design/cranelift-aot-box.md` - - LinkerBox: `docs/design/linker-box.md` - - スモーク仕様: `docs/tests/aot_smoke_cranelift.md` - - 雛形スクリプト: `tools/aot_smoke_cranelift.sh`, `tools/aot_smoke_cranelift.ps1` -- README にセルフホスト到達の道筋を明記(C ABI を Box 化)。 - -【ハンドオフ(2025‑09‑06 3rd)— String.length: const‑fold→Return 材化の不一致 調査ログとTODO】 - -概要(現象) -- 目標: JIT/JIT‑AOT で `StringBox.length/len` が 3 を返すべき箇所で 0 になるケースを解消。 -- 現状: Lower 中の早期 const‑fold で `length = 3` を確実に計算([LOWER] early const‑fold ... = 3 が出力)。Return 時点でも `ValueId(3)` が `known_i64=3` と認識される([LOWER] Return known_i64?=true)。にもかかわらず最終結果(実行結果)は 0。 - -重要な観測(再現とログ) -- MIR ダンプ(プリンタ仕様上、BoxCall は `call %box.method()` として表示) - 0: `%1 = const "abc"` - 1: `%2 = new StringBox(%1)` - 2: `call %2.birth(%1)` // birth は通常 call(dst なし) - 3: `%3 = call %2.length()` // これも通常 call 表記(内部は BoxCall) - 4: `ret %3` -- Lower ログ: - - `[LOWER] early const-fold StringBox.length = 3` が出る(const‑fold 成功) - - `[LOWER] Return value=ValueId(3) known_i64?=true param?=false local?=true` - - それでも実行結果は `Result: 0` -- `nyash.jit.dbg_i64`([JIT‑DBG])の出力が実行時に出ていない(import は宣言されるが call が観測されず)。 - -今回入れた変更(実装済・該当ファイル) -- Return/材化の強化(known を最優先) - - `src/jit/lower/core_ops.rs`: `push_value_if_known_or_param` を「known_i64 最優先」に変更。 - - `src/jit/lower/core.rs` の `I::Return` でも `known_i64` を最優先で積むように変更。 -- Call/ArrayGet の戻り値の保存 - - `src/jit/lower/core.rs`: `I::Call` 戻り値を dst が無い場合もスクラッチローカルへ保存(栈不整合の防止)。`I::ArrayGet` 戻り値も dst スロットへ保存。 -- String.length/len の早期 const‑fold を二段に強化 - - `src/jit/lower/core.rs`: BoxCall 入り口で `StringBox.literal` の length/len を即値化(最優先)。 - - `src/jit/lower/core/ops_ext.rs`: 同様の const‑fold を堅牢化(NewBox(StringBox, Const) から復元)。 - - `src/jit/lower/core.rs`: lowering 前に `known_str` を事前シード、`string_box_literal` マップ(NewBox → リテラル文字列)を構築し、Copy 伝播も対応。 -- トレース導線 - - `src/jit/lower/core/string_len.rs`: 二段フォールバック(param/local/literal)にデバッグフック(タグ 110x/120x/130x 系)追加。 - - `src/jit/lower/builder/cranelift.rs`: ローカル slot の store/load トレース(`NYASH_JIT_TRACE_LOCAL=1`)。 - - `crates/nyrt/src/lib.rs`: AOT 側の `nyash.string.len_h` / `nyash.any.length_h` に `[AOT-LEN_H]` を追加。 - - `src/jit/lower/extern_thunks.rs`: `nyash_string_from_u64x2` に `[JIT-STR_H]` を追加(JIT のハンドル生成観測)。`nyash_handle_of` に `[JIT-HANDLE_OF]` を追加。 - -仮説(根本原因) -- const‑fold で 3 を積めているにも関わらず、Return 時の実返却が 0。優先順位の修正により `known_i64` から 3 を積むよう修正済みだが、compiled JIT 関数内での Return 材化導線(ret_block への引数配線/最後の return)が値 0 に擦り替わる経路が残っている可能性。 - - ret_block/ジャンプ引数の材化不整合 - - 後続命令でスタックが上書きされる経路 - - birth の dst なし call で残留値が生じていた可能性(Call 戻り値スクラッチ保存で対策済) - -次アクション(TODO) -1) Return の後方走査材化(優先・CURRENT_TASK 既存 TODO の実装) - - BoxCall/Call/Select/Const/Copy/Load に遡って、Return が値を確実に拾う材化パスを補強する。 - - 既に known_i64 最優先化は実施済み。残りは ret_block 引数配線の最終確認(CraneliftBuilder の ret 経路)。 - -2) 実行時の値トレース強化(短期) - - `emit_return`(CraneliftBuilder)で、ret_block へ jump 直前の引数 `v` を `nyash.jit.dbg_i64(299,v)` で確実に呼ぶ(env でON)。 - - ret_block 入口パラメータの `return_` 直前でも `dbg_i64(300,param0)` 呼び出しを足し、どこで 0 になるかを確定する。 - -3) BoxCall(length/len) の早期 fold 命中率最終確認 - - `NYASH_JIT_TRACE_LOWER=1` で `[LOWER] early const-fold ... = 3` が必ず出ることを確認。 - - 既に出ているが、Return までの導線で 3 が 0 に化ける起点を 2) で特定する。 - -4) AOT/JIT‑AOT 観測の整備(参考) - - `[AOT-LEN_H]` で AOT 側 len_h/any.length_h の handle 解決有無をログ化。JIT‑AOT smoke での差異を収集。 - -再現/確認コマンド(更新) -- 早期 fold と Return 導線ログ: - - `NYASH_JIT_TRACE_LOWER=1 NYASH_JIT_TRACE_RET=1 NYASH_AOT_OBJECT_OUT=target/aot_objects/test_len_any.o ./target/release/nyash --jit-direct apps/smokes/jit_aot_any_len_string.nyash` -- ローカル slot 観測: - - `NYASH_JIT_TRACE_LOCAL=1 NYASH_AOT_OBJECT_OUT=... --jit-direct ...` -- AOT 側の handle 解決ログ: - - `NYASH_JIT_TRACE_LEN=1 bash tools/aot_smoke_cranelift.sh apps/smokes/jit_aot_string_min.nyash app_str` - -補足メモ -- MirPrinter は BoxCall を `call %box.method()` と出力する仕様(今回は BoxCall 経路で const‑fold が呼ばれていることは [LOWER] ログで確認済み)。 -- `call %2.birth(%1)` の戻り値残留に備え、I::Call の dst なし呼び出しでもスクラッチ保存して栈を消費するよう修正済み(回帰に注意)。 - -担当者への引き継ぎポイント -- まず 2) の dbg を CraneliftBuilder の ret 経路(jump to ret_block と return_)に追加し、`v`/`param0` が 0 になる箇所を特定してください。 -- 次に 1) の Return 後方走査材化を入れて、BoxCall/Select/Copy 等いずれの経路でも Return が安定して値を拾えるようにしてください。 -- その後、smoke `apps/smokes/jit_aot_any_len_string.nyash` が `Result: 3` で通ることを確認し、const‑fold のログと一致することをもってクローズ。 - -【将来計画(バグ修正後)— JIT を exec 専用にし、VM 連携を段階的に廃止】 - -目的 -- JIT は「コンパイル+実行(exec)」に一本化し、VM 依存のレガシー経路(param-index/TLS参照)を撤去する。 -- 値の材化・ハンドル管理・hostcall を JIT 側で一貫させ、境界の不整合を根本から減らす。 - -ロードマップ(段階移行) -1) 実行モードの明確化(設定) - - 環境変数 `NYASH_JIT_MODE=exec|compile|off` を導入。 - - 既存の `NYASH_JIT_STRICT` は非推奨化し、`MODE=compile` に集約。 - -2) JIT ABI の一本化 - - `src/jit/lower/extern_thunks.rs` などから `with_legacy_vm_args` を撤去。 - - `nyash_handle_of` を含む extern は「JIT引数/ハンドルのみ」を受け付ける設計に変更。 - - ランタイム境界で `VMValue -> JitValue(Handle)` へのアダプタを用意。 - -3) レガシー撤去(JIT/AOT側) - - `crates/nyrt/src/lib.rs` の `nyash.string.len_h`/`nyash.any.length_h` から param-index フォールバックを削除。 - - lowering の `-1` センチネルや VM 依存の fallback を廃止し、`handle.of` または既存ローカルハンドルに統一。 - -4) フォールバック方針(移行期間) - - 関数単位で `unsupported>0` の場合のみ VM にフォールバック。 - - オプション `NYASH_JIT_TRAP_ON_FALLBACK=1` を追加し、移行時の漏れを検出可能に。 - -5) Return 導線の強化(本タスクの延長) - - Cranelift 生成の ret 経路に dbg を常設(envでON)。 - - Return の後方走査材化を標準化し、const-fold/BoxCall/Select いずれでも Return が値を確実に拾うように。 - -6) ドキュメント/テスト更新 - - README/CURRENT_TASK にモード説明と運用方針を追記。 - - CI の smoke は `MODE=exec` を常態化し、compile-only はAOT出力/ベンチのみで使用。 - -影響範囲(主な修正ポイント) -- `src/jit/manager.rs`(モード/実行ポリシー) -- `src/jit/lower/extern_thunks.rs`(レガシーVM依存排除、JIT ABI専用化) -- `src/jit/lower/core.rs` / `src/jit/lower/core_ops.rs`(-1センチネル削除・ハンドル材化徹底) -- `crates/nyrt/src/lib.rs`(dotted名hostcallのレガシー経路削除) -- ドキュメント(README/CURRENT_TASK) - -ロールアウト/リスク -- フラグ駆動で段階的に切替(デフォルト `exec`)。 -- リスク: plugin経路/hostcall registry/ハンドルリーク。 - - 緩和: `handles::begin_scope/end_scope_clear` によりハンドル回収を徹底、registryの検証を追加。 - -【本日更新】 -- VM if/return 無限実行バグを修正(基本ブロック突入時に `should_return`/`next_block` をリセット)。include 経路のハングも解消。 -- ArrayBox プラグイン生成失敗に対し、v2 ローダへパス解決フォールバック(`plugin_paths.search_paths`)を追加し安定化。 -- std/string の P0 関数を Ny 実装で追加(length/concat/slice/index_of/equals)。index_of は substring ループで代替。 -- 残課題: string_smoke で `fails` 累積の else 側に φ が入らず未定義値参照(MIR Builder 側の SSA/φ 振る舞い)。別タスク化。 - -【ハンドオフ(2025‑09‑06)— AOT/JIT‑AOT 足場と箱下寄せリファクタ】 -- 変更サマリ - - nyrt: AOT 連携の dotted 名を追加(Map/String/Any/birth) - - `nyash.map.{size_h,get_h,get_hh,set_h,has_h}` - - `nyash.string.{len_h,charCodeAt_h,concat_hh,eq_hh,lt_hh}` / `nyash.any.{length_h,is_empty_h}` - - NewBox/文字列: `nyash.instance.birth_name_u64x2`, `nyash.string.from_u64x2` - - JIT‑AOT(ObjectBuilder): - - 文字列リテラル→ハンドル生成(u64x2 パック → `nyash.string.from_u64x2`) - - 出力関数を `ny_main` としてエクスポート - - 最小 Store/Load(i64)を StackSlot で実装 - - Lower(箱を下に寄せる最小整理): - - Map: param 不在でもローカルハンドルがあれば `_H` シンボルで直呼び - - Any.length: StringBox は `nyash.string.len_h` を優先。ローカル/再構築/旧 index の順にフォールバック - - Copy/Load でローカルハンドルを dst 側 slot に伝播 - - Array.length は ArrayBox 受けに限定(ops_ext ガード) - -- 追加スモーク(JIT‑AOT) - - `apps/smokes/jit_aot_string_min.nyash`(concat+eq)→ PASS - - `apps/smokes/jit_aot_any_isempty_string.nyash` → PASS - - `apps/smokes/jit_aot_any_len_string.nyash` → 現状 Result: 0(後述の未解決) - - `apps/smokes/jit_aot_map_min.nyash` → 環境により MapBox 生成が必要 - -- 実行例 - - 文字列ミニ(AOT): - - `NYASH_AOT_OBJECT_OUT=target/aot_objects/test_str.o ./target/release/nyash --jit-direct apps/smokes/jit_aot_string_min.nyash` - - `cc target/aot_objects/test_str.o -L target/release -Wl,--whole-archive -lnyrt -Wl,--no-whole-archive -lpthread -ldl -lm -o app_str && ./app_str` → `Result: 1` - - isEmpty(AOT): - - 同様に `app_empty` → `Result: 1` - - Map 最小(AOT): - - `.o` 生成/リンクは通る。`new MapBox()` はプラグイン/設定に依存(`nyash.toml` と `.so` の配置を確認) - -- 未解決 / 既知の課題(優先度高) - 1) String.length の AOT 実行が 0 になるケース - - 症状: `s = new StringBox("abc"); return s.length()` → `Result: 0` - - 現状の対処: Any.length を String.len_h 優先にし、ローカル/再構築/旧 index の順でフォールバック。Const fold も追加済み。 - - 追加方針: 受け型伝播(Copy/Load→dst へ型共有)をより堅牢化。最終手段として、ローカルハンドル時に `string.len_h`→`any.length_h` の二段呼び分け(0 返りのときだけ後者)で保険を張る。 - 2) MapBox 生成(AOT 実行バイナリ) - - 環境によりプラグイン解決が必要。`nyash.toml` のあるディレクトリで実行し、必要なら各プラグインを `target/release` に配置。 - -- 次アクション(引き継ぎ TODO) - - [ ] Any.length の 0 問題を完全解消 - - [ ] 受けの型/ハンドル伝播(Copy/Load/Store)を統一ヘルパ化し、length/len/charCodeAt で確実にハンドルを積む - - [ ] StringBox(Const) は定数畳み込みを最優先(len を即値化) - - [ ] 保険: `string.len_h`→0→`any.length_h` の順にフォールバック(ローカルハンドル時) - - [ ] メソッド→シンボル/引数規約の集中表を作成(Array/Map/String/Any) - - [ ] ops_ext/core の分岐重複を縮減(箱の責務を「下」に寄せる) - - [ ] AOT スモーク拡充 - - [ ] String/Array の length/len を追加、select/分岐のミニ例も用意 - - [ ] Map.get/has/set(プラグインあり環境用) - -- 影響ファイル(主要) - - 追加/更新: `crates/nyrt/src/lib.rs`(dotted エクスポート多数)、 - `src/jit/lower/builder/{object.rs,cranelift.rs}`、 - `src/jit/lower/{core.rs,core/ops_ext.rs,core_hostcall.rs}`、 - スモーク: `apps/smokes/jit_aot_*.nyash` - -■ ハンドオフ(JIT AOT / LLVM の現状と次アクション) -- 現状サマリ - - Array fast‑path: VM 側 len/length を最前段に早期化(Void→0 も確認)。 - - Null 互換: NullBox→VMValue::Void へ統一(比較の整合確保)。 - - std/array smoke: `NYASH_DISABLE_PLUGINS=1` で PASS(len/push/pop/slice)。 - - LLVM AOT: 復活(nyrt の read lock 寿命修正、build_llvm.sh のリンクパス `-L target/release` 追加)。 - - JIT AOT(ObjectBuilder): P0 安定化+P1 実装済(const/return、i64 binop、compare、select、branch/jump、hostcall 基本、PHI最小化ブロック引数)。 - - jit-direct で .o 生成確認: `apps/smokes/jit_aot_arith_branch.nyash` → Result 13、.o 出力 OK。 - - build_aot.sh は既定で STRICT=0、出力 `target/aot_objects/main.o` に固定。 - - nyrt: AOT 連携用 dotted 名 alias を Array に追加(`nyash.array.{len_h,get_h,set_h,push_h}`)。 - -- 優先TODO(次にやること) - 1) JIT AOT P2: hostcall 拡張(規約ベースの最小集合) - - Map: `nyash.map.{size_h,get_h,has_h,set_h}` の dotted 名を nyrt に追加(既存実装へ forward) - - String: 代表メソッド(len/concat/substring/indexOf 等)で必要なシンボルを dotted 名として追加 - - ObjectBuilder から `emit_host_call_typed` で呼び出し(Lower の対応表に従う) - 2) LowerCore: slot/name→hostcall マッピング(by‑slot を優先、by‑name は互換フォールバック) - - Array/Map/String の最小セット(len/get/set/push、size/get/has/set、len/concat など) - 3) 後続(必要時): JIT AOT スモークを追加(分岐あり最小、Array/Map の各1本) - -- 実行コマンド(確認用) - - JIT AOT(jit-direct + .o): - - `NYASH_DISABLE_PLUGINS=1 NYASH_JIT_EVENTS=1 NYASH_AOT_OBJECT_OUT=target/aot_objects/jit_aot_arith.o ./target/release/nyash --jit-direct apps/smokes/jit_aot_arith_branch.nyash` - - LLVM AOT(emit+link): - - `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) tools/build_llvm.sh apps/tests/ny-llvm-smoke/main.nyash -o app` - -■ 現在のフォーカス(JITオンリー/一旦の着地) -1) Core 緑維持(完了) - - `tools/jit_smoke.sh` / Roundtrip(A/B) / Bootstrap(c0→c1→c1') / Using E2E = PASS - -【P1 進捗 — LLVM Core-13: ビット演算/シフト】 -実装 -- LLVM 降ろしで `BinaryOp::{BitAnd,BitOr,BitXor,Shl,Shr}` を i64 経路に実装済み(既存)。 -- `compile_and_execute` の MIR インタプリタにも同演算を実装し、パリティを確保。 - -検証 -- 単体テスト追加: `src/tests/llvm_bitops_test.rs` - - MIR を直接構築して `1=(5&3),7=(5|2),4=(5^1),32=(1<<5),4=(32>>3)` の合計 48 を検証。 - - VM 実行で 48、LLVM `compile_to_object` がエラーなく emit、`compile_and_execute` でも 48 を確認(フォールバック実行)。 -- AOT スモーク(任意): `tools/llvm_smoke.sh` に `NYASH_LLVM_BITOPS_SMOKE=1` で有効化する項目を追加(入力は Nyash ソース制約のため現状 skip 既定)。 - -注意 -- Nyash ソースパーサが `&|^<<>>` を未サポートのため、ビット演算の E2E は当面 MIR 直構築テストで担保。 - 将来 `grammar/` の演算子追加後に `apps/tests/ny-llvm-bitops/` を有効化予定。 -2) CI 分離(完了) - - Core(常時): `tools/jit_smoke.sh` + Roundtrip - - Plugins(任意): `NYASH_SKIP_TOML_ENV=1 ./tools/smoke_plugins.sh`(strict既定OFF、`NYASH_PLUGINS_STRICT=1`でON) -3) Self‑host E2E(完了) - - ny_plugins 有効 + `NYASH_USE_NY_COMPILER=1` の自己ホストE2Eをオプションゲートで運用 -4) クリーンアップ(完了) - - 未使用import/変数の整理、runner責務分割、tools出力体裁の統一 - -■ ブランチ/構成(Phase 15) -- 実装ブランチ: `phase-15/self-host-ny-mir` -- 既存 Workspace は維持(`crates/*`)。 -- 方針: crates 側は変更せず「Nyash スクリプト + nyash.exe」だけで実装・運用(Windows優先)。 - - 例: `C:\git\nyash-project\nyash_self\nyash` 直下で `target\release\nyash` 実行。 -- Nyash 製パーサは `apps/selfhost/ny-parser-nyash/`(Nyashコード)として配置(最初は最小サブセット)。 -- MIR 解釈層は既存 `backend/mir_interpreter.rs` と `runner/modes/mir_interpreter.rs` を拡充。 -- AOT 関連の雛形は `src/backend/cranelift/` に維持(feature gate: `cranelift-aot`)。 - -■ 再開TODO(優先順) -1) std Ny実装の実体化(P0/P1) - - string: length/concat/slice/indexOf/equals → P0 完了(string_smoke PASS) - - array: len/push/pop/slice を内蔵経路で先行(次着手) - - map: get/set/len/keys (+values/entries/forEach) - - jit_smoke に機能検証を常時化(Coreは `NYASH_DISABLE_PLUGINS=1`) -2) NyコンパイラMVPのsubset拡張 - - let/call/return に続き if/ブロック/関数引数まで拡張し、`NYASH_USE_NY_COMPILER=1` スモークを充実 -3) Self‑host E2E ゲートの昇格 - - 連続N回グリーン後にCI optional→requiredへ昇格(trace/hash基準) -4) Plugins厳格ONの段階移行 - - Core‑13準拠サンプルへ置換し、`NYASH_PLUGINS_STRICT=1` ゲートで順次ONに復帰 - -【優先追加 — JIT AOT(ObjectBuilder)安定化・拡張】 -- P0: 安定化(完了) - - switch_to_block なしでの命令発行panic対策(emit_const系) - - 終端命令なしVerifierエラー対策(emit_return 実装) - - build_aot.sh の STRICT 緩和(デフォルト0)+ obj 直指定 -- P1: 最小命令カバレッジ(今すぐ実装) - - i64 binop: add/sub/mul/div/mod を実コード生成 - - compare: eq/ne/lt/le/gt/ge → b1→i64(0/1) へ正規化してpush - - 分岐/ジャンプ: br_if_top_is_true/jump_to 実装(ブロック遷移とCFG整合) - - select: emit_select_i64 実装(cond, then, else の順) -- P2: hostcall 系の型付き発行(必要最小限) - - array/map/string/integer の代表 extern を ObjectBuilder に実装 - - ny-llvm-smoke 等に相当する JIT AOT smoke 追加 -- P3: CI スモーク - - `tools/jit_smoke.sh` に AOT(JIT)最小タスクを追加(STRICT=0 で .o 生成確認) - -## ブロッカー/暫定対応(2025‑09‑05 更新) -- 影響範囲(Backend差) - - JIT(cranelift) → 影響なし。 - - VM(backends=vm) → if/return 無限ループは修正済み(基本ブロック突入時に CF リセット)。 - - 結論: include ハングの根因は VM の制御フロー残存フラグ。修正により解消。 - -- 事象A: include ハング → 解消 - - `apps/tmp_len_min.nyash`/`apps/tmp_len_test.nyash` 正常完走を確認。 - -- 事象B: ArrayBox プラグイン生成エラー → 解消 - - v2 ローダにフォールバック探索(`plugin_paths.search_paths`)を追加し、workspace の `./target/release/*.so` を自動解決。 - - DEBUG 時に birth 戻り `code/out_len` をロギング。 - -- 事象C: std/string_smoke の最終段で未定義値参照 → 解消 - - MIR Builder の if 降ろしで φ を必ず生成(then のみ代入・else 未代入時は pre 値と then 値で合流)。 - - string_smoke PASS を確認。 - -## 次アクション(デバッグ計画) -- A1: includeハング最小化再現を固定(VM経路優先で調査) - - `apps/tmp_len_test.nyash` 固定、`NYASH_DEBUG=1` で `execute_include_expr` → `ensure_static_box_initialized` までの経路にログを追加。 - - `included_files`/`include_stack` の push/pop と RwLock/RwLock の取り回しを確認。ポップ忘れ/二重ロックがないか検査。 - - `apps/std/string.nyash` 内のメソッドを段階的に無効化して最小原因を特定(現状 length のみでも再現)。 - -- A2: VM if/return 無限実行(VM限定)を優先修正 - - 症状: JITは1回then→Return→終了。VMはthenのprintが際限なく繰り返される。 - - 再現最小: `apps/tmp_if_min.nyash` - ```nyash - static box Main { - main() { - local x - x = 3 - if x == 3 { - print("ok3") - return 0 - } - print("bad") - return 1 - } - } - ``` - - JIT: `./target/release/nyash apps/tmp_if_min.nyash` → 1回だけ ok3, Result:0 - - VM: `timeout 4s ./target/release/nyash --backend vm apps/tmp_if_min.nyash` → ok3 が無限に出続け TIMEOUT - - MIRダンプ(`NYASH_VM_DUMP_MIR=1`)では if 降下は正しく、then/else 各ブロックは `ret` を含む。 - - 例: bb1 に `extern_call log("ok3")` の後 `ret 0`。bb2 に `ret 1`。 - - 観測ログ(`NYASH_VM_DEBUG_EXEC=1`)では Print/Const が繰り返し実行。Return の終端処理が機能していない疑い。 - - 仮説: VM 実行ループの制御フロー(`execute_function`)で `ControlFlow::Return` を受け取った後の関数脱出が何らかの理由で無効化/上書き/再入している。 - - 着手案: - - `execute_function` に短期ログ: 現在ブロックID/terminator種別/`should_return` セット→関数戻りの分岐をeprintln(NYASH_VM_DEBUG_EXEC=1時) - - `execute_instruction` で `Return` ディスパッチ時に明示ログ(val_id/値)を出す(現状VTトレースも可)。 - - `previous_block`/`loop_executor`/`record_transition` で自己遷移が起きていないか確認。 - - `BasicBlock::add_instruction` にて terminator設定/Successorsの更新は正常(コード・MIR上はOK)。処理後の `next_block` 決定ロジックを再点検。 - -## ハンドオフ(変更点・補助情報) -- 追加ファイル(std MVP + smokes) - - `apps/std/string.nyash`, `apps/std/array.nyash` - - `apps/smokes/std/string_smoke.nyash`, `apps/smokes/std/array_smoke.nyash` -- スクリプト/設定の更新 - - `tools/jit_smoke.sh`: Std smokes に `timeout 15s`、ArrayBox未提供時は `SKIP` を出力 - - `tools/smoke_plugins.sh`: `NYASH_PLUGINS_STRICT=1` のON/OFF表示 - - `nyash.toml`: `ny_plugins` に std 2件を追加 - - `src/runner/modes/vm.rs`: `NYASH_VM_DUMP_MIR=1` でVM実行前にMIRをダンプ - - `src/mir/builder/stmts.rs`: 末尾 `return/throw` 後に同ブロックへ更に命令を積まないための早期breakを追加(安全強化) -- 再現とログ - - VM再現: `timeout 4s ./target/release/nyash --backend vm apps/tmp_if_min.nyash` - - JIT対照: `./target/release/nyash apps/tmp_if_min.nyash` - - MIRダンプ: `NYASH_VM_DUMP_MIR=1 --backend vm ...` - - 命令トレース: `NYASH_VM_DEBUG_EXEC=1 --backend vm ...` -- プラグイン/ArrayBox注意 - - 既定でプラグイン経由に迂回するため、未ビルドだと ArrayBox 生成に失敗。 - - 回避: `NYASH_USE_PLUGIN_BUILTINS=0` または `NYASH_PLUGIN_OVERRIDE_TYPES` から `ArrayBox,MapBox`を除外。もしくはプラグインをビルド。 - -## すぐ着手できるTODO(VM側) -- [ ] `execute_function` にブロック遷移/Return検出ログ(NYASH_VM_DEBUG_EXEC=1時のみ) -- [ ] Return発生時に確実に `Ok(return_value)` で関数を抜けることを確認(`should_return`/`next_block` の上書き防止) -- [ ] `record_transition`/`loop_executor` の副作用で自己遷移が起きていないか確認 -- [ ] 修正後、`apps/tmp_if_min.nyash` が VM/JIT 両方で一発終了することを確認(MIRダンプ上は既に正しい) -- B1: ArrayBox 経路の選択を明示 - - 手元では `NYASH_USE_PLUGIN_BUILTINS=0` で内蔵にフォールバックするか、プラグインを `cargo build -p nyash-array-plugin --release` で用意。 - - CIは当面 `SKIP` 維持。 - -## 実行メモ(暫定) -- Std smokes(手元で回す) - - `NYASH_LOAD_NY_PLUGINS=1 NYASH_USE_PLUGIN_BUILTINS=0 ./tools/jit_smoke.sh` - - またはプラグインをビルドしてから `NYASH_LOAD_NY_PLUGINS=1 ./tools/jit_smoke.sh` - -■ 予定(R5 拡張: Ny Plugins → Namespace) -- Phase A(最小): 共有レジストリ `NyModules` を追加し、`env.modules.set/get` で exports を登録/取得。 - - `[ny_plugins]` は戻り値(Map/StaticBox)を「ファイルパス→名前空間」に変換して登録。 - - 名前空間導出: ルート相対・区切りは `.`、拡張子除去・無効文字は `_`。予約 `nyashstd.*` 等は拒否。 -- Phase B(範囲): 共有Interpreterオプション(`NYASH_NY_PLUGINS_SHARED=1`)で静的定義を共有。ログに REGISTERED を出力。 -- Phase C(言語結線): `using ` を `NyModules` 参照→未解決時にファイル/パッケージ解決(nyash.link)へフォールバック。 - -■ 直近で完了したこと(主要抜粋/JIT) -- R1: JSON v0 ブリッジ(`--ny-parser-pipe`/`--json-file`)、変換器 `src/runner/json_v0_bridge.rs`、スモーク追加 -- R2: ラウンドトリップ E2E(`tools/ny_roundtrip_smoke.{sh,ps1}`) -- R3: 直結ブリッジ v0(`--parser ny`/`NYASH_USE_NY_PARSER=1`、`NYASH_DUMP_JSON_IR=1`)→ `return (1+2)*3` で 9 -- R5: Ny スクリプトプラグイン([ny_plugins])列挙+実行(OK/FAIL 出力・列挙のみガード付き) - - NyModules登録/名前空間導出/Windows正規化の仕様確定・回帰スモーク - - using/namespace(ゲート)・nyash.link最小・resolverキャッシュ・実行時フック(提案付き診断) -- AOT P2(step‑1): RUN スモーク配線(最小オブジェクト生成+実行ログ) - -- ■ 直近で完了したこと(主要抜粋) -- T0: MIRインタープリタ強化(分岐/比較/PHI/extern/Box最小)+ Runner 観測ログ -- T1: Nyash製ミニパーサ(整数/四則/括弧/return)→ JSON IR v0 出力 -- T2: JSON IR v0 → MIRModule 受け口(`--ny-parser-pipe`) -- T3: CLI 切替/ヘルプ(`--ny-parser-pipe`/`--json-file`、mirヘルプ追補) -- T4: Docs/Samples/Runner scripts(apps/ny-mir-samples, tools/*, README 追補) -- Phase 15 起点準備 - - CLIに `--backend cranelift-aot` と `--poc-const` を追加(プレースホルダ動作)。 - - `src/backend/cranelift/{mod.rs,aot_box.rs,linker_box.rs}` の雛形追加(feature gate)。 - - MIR解釈層スケルトン(`semantics/eval.rs` と `backend/mir_interpreter.rs`)の確認 - -■ 再開用クイックメモ(JITのみ) -- ビルド - - VM/JIT: `cargo build --release --features cranelift-jit` - - LLVM(必要時): `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) cargo build --release --features llvm` - - AOT(導入後): `cargo build --release --features cranelift-aot` -- スモーク(JIT/VM) - - Core: `NYASH_DISABLE_PLUGINS=1 NYASH_CLI_VERBOSE=1 ./tools/smoke_vm_jit.sh` - - Parser Bridge: `./tools/ny_parser_bridge_smoke.sh` - - Roundtrip: `./tools/ny_roundtrip_smoke.sh`(A/B) - - Plugins: `NYASH_SKIP_TOML_ENV=1 ./tools/smoke_plugins.sh`(厳格は `NYASH_PLUGINS_STRICT=1` 時のみON) - - Bootstrap: `./tools/bootstrap_selfhost_smoke.sh` - - Using/Resolver: `./tools/using_e2e_smoke.sh` - -■ 状態 -- JIT自己ホストMVP: 到達(E2E/ブートストラップ/ドキュメント/CI分離まで完了) -- リファクタ: Step1/2/3 完了(未使用掃除・runner分割・tools体裁統一) -- 次回は「std実装の実体化」と「Nyコンパイラsubset拡張」から再開 -- 参照 - - Phase 15 概要/ロードマップ: `docs/development/roadmap/phases/phase-15/README.md`, `docs/development/roadmap/phases/phase-15/ROADMAP.md` - - ハンドオフ: `docs/handoff/phase-15-handoff.md` - - 設計/API: `docs/design/backend-cranelift-aot-design.md`, `docs/design/*` - -■ 合否基準(P0: Ny→MIR→MIR-Interp→VM 最小成立) -- 自作Nyashパーサ(最小サブセット)が Nyash で動作し、テスト入力から中間形式(JSON暫定)を生成できる。 -- Runner が中間形式を MIRModule に変換し、MIR 解釈層で実行して既知の結果(例: `Result: 42`)を出力する。 -- 代表ケース(整数四則演算/括弧/return)で往復が安定。 - -■ JSON IR v0(暫定スキーマ) -- version: 整数(例: 0) -- kind: 固定 "Program" -- body: 配列(Stmt[]) -- Stmt(最小) - - { "type": "Return", "expr": Expr } -- Expr(最小) - - { "type": "Int", "value": 123 } - - { "type": "Binary", "op": "+"|"-"|"*"|"/", "lhs": Expr, "rhs": Expr } -- error(失敗時) - - { "version":0, "kind":"Error", "error": { "message": "...", "span": {"start":N, "end":M} } } -- 例 - - `return 1+2*3` → {"version":0,"kind":"Program","body":[{"type":"Return","expr":{"type":"Binary","op":"+","lhs":{"type":"Int","value":1},"rhs":{"type":"Binary","op":"*","lhs":{"type":"Int","value":2},"rhs":{"type":"Int","value":3}}}}]} - - `return (1+2)*3` → `Binary('*', Binary('+',1,2), 3)` の形で生成 - -■ 補足(優先/範囲) -- 先行するのは Ny→MIR→MIR-Interp→VM の自己ホスト経路(AOTはP2以降)。 -- OS 優先: Windows →(後続で Linux/macOS)。 -- メモリ/GC: P0は整数演算/定数返し中心でNyRT拡張不要。 -- Codex 非同期運用: `tools/codex-async-notify.sh`/`tools/codex-keep-two.sh` 継続利用。 - -## 実行コマンド(サマリ) -- VM/JIT 実行例 - - `printf "Hello\n" | NYASH_CLI_VERBOSE=0 ./target/release/nyash apps/ny-echo/main.nyash` - - `printf "Hello\n" | NYASH_CLI_VERBOSE=0 ./target/release/nyash --backend vm apps/ny-echo/main.nyash` -- AOT/LLVM 系は後段(当面OFF) - -- JSON v0 ブリッジ(R1 Quick Start) - - パイプ実行(Unix/WSL): `printf '{"version":0,"kind":"Program","body":[{"type":"Return","expr":{"type":"Binary","op":"+","lhs":{"type":"Int","value":1},"rhs":{"type":"Binary","op":"*","lhs":{"type":"Int","value":2},"rhs":{"type":"Int","value":3}}}}]}' | ./target/release/nyash --ny-parser-pipe` - - ファイル指定(Unix/WSL): `./target/release/nyash --json-file sample.json` - - スモーク(Unix/Windows): `./tools/ny_parser_bridge_smoke.sh` / `pwsh -File tools/ny_parser_bridge_smoke.ps1` - -- E2E ラウンドトリップ(R2) - - Unix/WSL: `./tools/ny_roundtrip_smoke.sh` - - Windows: `pwsh -File tools/ny_roundtrip_smoke.ps1` - - tmux通知で並列実行(例): - - `CODEX_ASYNC_DETACH=1 ./tools/codex-async-notify.sh "./tools/ny_roundtrip_smoke.sh" codex` - - `CODEX_ASYNC_DETACH=1 ./tools/codex-async-notify.sh "pwsh -File tools/ny_roundtrip_smoke.ps1" codex` - -- Ny プラグイン列挙(R5) - - 有効化: `--load-ny-plugins` または `NYASH_LOAD_NY_PLUGINS=1` - - `nyash.toml` 例: - ```toml - ny_plugins = [ - "apps/std/ny-config.nyash", - "apps/plugins/my-helper.nyash" - ] - ``` - - 実行: 列挙に加え、Interpreterで順次実行(ベストエフォート)。 - - ガード: `NYASH_NY_PLUGINS_LIST_ONLY=1` で列挙のみ(実行しない) - - 注意: プラグインスクリプトは副作用の少ない初期化/登録処理に限定推奨。 - - Std Ny スモーク実行(任意): `NYASH_LOAD_NY_PLUGINS=1 ./tools/jit_smoke.sh` - -## トレース/環境変数(抜粋) -- AOT/Link: `NYASH_LINKER`, `NYASH_LINK_FLAGS`, `NYASH_LINK_VERBOSE` -- ABI: `NYASH_ABI_VTABLE=1`, `NYASH_ABI_STRICT=1` -- VM/JIT: `NYASH_VM_PIC_STATS`, `NYASH_JIT_DUMP` など従来通り - ---- -詳細な履歴や議事録は docs 配下の Phase 15 セクションを参照してください。 - - ny-config(R4) - - `./target/release/nyash apps/std/ny-config.nyash` - - 現状: Interpreter 経路のプラグイン初期化順序により FileBox/TOMLBox を使うには Runner 側の微調整が必要(VM 経路への移行 or プラグイン登録の早期化)。スクリプト本体は追加済み。 -- 直結ブリッジ v0(R3 Quick Start) - - `printf 'return (1+2)*3\n' > t.ny && NYASH_USE_NY_PARSER=1 NYASH_DUMP_JSON_IR=1 ./target/release/nyash t.ny` - - ---- - -New Plan — Self‑Host Dependency Tree (Ny‑only) and Bridge(2025‑09‑07) - -目的 -- Ny スクリプトのみで依存木(include + using/module)を再帰解析して JSON を出力。Rust ビルド無しで回せる内側ループを整備。 -- 既存の MIR→VM→AOT 系とは疎結合を維持しつつ、最小の橋渡し(JSONファイル経由)を用意。 - -実装項目(最小) -- ツール: `apps/selfhost/tools/dep_tree_simple.nyash` - - 1ファイル・静的boxで実装。1行1文/break無し/elseは同一行。 - - 解析: `include "..."`、`using ns`/`using ns as Alias`、`using "./path" as Name`、`// @module ns=path`。 - - 解決順: `module > 相対 > using-path`(using-path 既定: `apps/selfhost:apps:lib:.`)。 - - JSON: `{ version, root_path, tree{ path, includes[], uses[], modules[], children[] } }`(uses は unresolved/hint/alias/resolved を含む)。 - -- タスク/Make: - - `nyash.toml [tasks].dep_tree` を追加し、1コマンドで JSON を `tmp/deps.json` に出力。 - - `make dep-tree`: `cargo build --release && ./target/release/nyash --run-task dep_tree`。 - -- 受け入れ基準: - - `make dep-tree` が `tmp/deps.json` を出力。曖昧(複数ヒット)は注記/STRICT で停止。 - - VM/Interpreter いずれでも実行可(File/Path/Array/Map 最小APIで実装)。 - -橋渡し(Stage 1: 疎結合) -- `NYASH_DEPS_JSON=` を Runner で読取り(ログ出力等の診断用途)。MIR/JIT/AOT の挙動は不変。 -- 後続(Stage 2以降)は JSON IR `extensions.deps` や lock ファイルの導入を検討(別期)。 - -進め方(短期) -1) `dep_tree_simple.nyash` の完走化(VM実行での File/Path 最小APIのみ使用)。 -2) `nyash.toml` へ `dep_tree` 追加+ `make dep-tree` 整備。 -3) Runner へ `NYASH_DEPS_JSON` の最小読込み(ログ出力)を追加(影響ゼロの範囲)。 diff --git a/docs/archive/reports/README.md b/docs/archive/reports/README.md new file mode 100644 index 00000000..2e110e4b --- /dev/null +++ b/docs/archive/reports/README.md @@ -0,0 +1,32 @@ +# Archived Reports + +このフォルダには、過去の分析レポート・リファクタリング計画など、歴史的記録として保持するドキュメントを格納しています。 + +## ファイル一覧 + +### REFACTORING_ANALYSIS_REPORT.md +- **作成日**: 2025年9月以前 +- **内容**: 古いリファクタリング分析レポート +- **状態**: アーカイブ(参考資料) +- **最新情報**: `docs/development/refactoring/` を参照 + +### analysis_report.md +- **作成日**: 2025-11-01 +- **内容**: 古い分析レポート +- **状態**: アーカイブ(参考資料) +- **最新情報**: `docs/development/` 配下の最新ドキュメントを参照 + +--- + +## 注意事項 + +これらのドキュメントは**歴史的記録**として保持されています。 + +- ✅ 参考資料として閲覧可能 +- ⚠️ 最新の情報ではない可能性あり +- 🔍 最新情報は `docs/development/` 配下を参照してください + +--- + +**アーカイブ日**: 2025-11-04 +**整理者**: Claude Code(Phase 2クリーンアップ) diff --git a/REFACTORING_ANALYSIS_REPORT.md b/docs/archive/reports/REFACTORING_ANALYSIS_REPORT.md similarity index 100% rename from REFACTORING_ANALYSIS_REPORT.md rename to docs/archive/reports/REFACTORING_ANALYSIS_REPORT.md diff --git a/analysis_report.md b/docs/archive/reports/analysis_report.md similarity index 100% rename from analysis_report.md rename to docs/archive/reports/analysis_report.md diff --git a/docs/development/cleanup/CLEANUP_REPORT_2025-11-04.md b/docs/development/cleanup/CLEANUP_REPORT_2025-11-04.md index 17f2d09e..ed3b91a9 100644 --- a/docs/development/cleanup/CLEANUP_REPORT_2025-11-04.md +++ b/docs/development/cleanup/CLEANUP_REPORT_2025-11-04.md @@ -198,6 +198,36 @@ git status --short 1. **AGENTS.md**(508行)の扱い - 選択肢A: 分割(開発原則を独立文書化)← 推奨 - 選択肢B: 保持(現状維持) + +--- + +## ⚠️ 既知の注意点と連絡先(問題があれば教えてください) + +- include の撤去影響(言語非対応の方針): + - 一部の開発用スクリプトで `include` に依存していた場合、実行時に警告/エラーへと変化します。 + - 解決策: using+alias へ置換、必要時のみ test-harness の preinclude を使用。 + +- verify 経路の直行化(env JSON → hv1/Core): + - 古いラッパー経由の -c 期待と差が出る可能性があります。 + - 直行は「最後の行が数値=rc」という契約です。工具やCIの抽出処理をご確認ください。 + +- alias 解決キャッシュ: + - `modules.workspace` 追加により、初回解決時にファイルシステムを走査します。 + - 大規模変更直後は `NYASH_RESOLVE_TRACE=1` で初期化挙動をご確認ください。 + +- 文書リンクの移動: + - 主要リンクは更新済みですが、private ノートや社外資料のブックマークは無効になっている可能性があります。 + +問題や不整合を見つけた場合は、次の情報を添えてお知らせください: +- 症状(例: コマンドとエラーメッセージ、ログ数行) +- 影響範囲(どのドキュメント/スクリプト/テストか) +- 期待動作(何が起きてほしかったか) + +Issue/連絡先: +- GitHub Issue(推奨): タグ `cleanup-2025-11-04` を付けてください。 +- または Slack #dev-tools チャンネルへ(リンクとログ断片を添付)。 + +本クリーンアップにより、探索性・再現性・サイズが大幅に改善されています。小さな揺れは迅速に直しますので、発見次第お気軽にご連絡ください。 - 選択肢C: .claude/に移動(非表示化) 2. **CHANGELOG.md**(28行、更新停止中)の扱い diff --git a/docs/development/cleanup/PHASE2_REPORT_2025-11-04.md b/docs/development/cleanup/PHASE2_REPORT_2025-11-04.md new file mode 100644 index 00000000..f9bf437a --- /dev/null +++ b/docs/development/cleanup/PHASE2_REPORT_2025-11-04.md @@ -0,0 +1,189 @@ +# 🧹 Phase 2 実行レポート 2025-11-04 + +**実行日時**: 2025-11-04 16:45 +**実行者**: Claude Code +**Phase**: 整理・統合 + +--- + +## ✅ Phase 2 完了サマリー + +### 実行内容 + +#### Phase 2-A: CURRENT_TASK系の統合 ✅ +**目的**: 重複・古いCURRENT_TASKファイルの整理 + +**実行内容**: +1. **保持**: `CURRENT_TASK.md`(最新版、15KB) +2. **移動**: `CURRENT_TASK_ARCHIVE_2025-09-27.md`(153KB)→ `docs/development/archive/current_task/CURRENT_TASK_ARCHIVE_2025-09-27.md` +3. **削除**: `CURRENT_TASK_restored.md`(67KB、古いバックアップ) +4. **削除**: `docs/development/current_task_archive/`フォルダ(重複のため) + +**結果**: +- ✅ CURRENT_TASK系ファイルを1箇所に統一 +- ✅ 重複フォルダ削除 +- ✅ アーカイブは `docs/development/archive/current_task/` に統一 + +--- + +#### Phase 2-B: CODEX_QUESTION系の整理 ✅ +**目的**: バックアップファイルの削除 + +**実行内容**: +1. **保持**: `CODEX_QUESTION.md`(最新版、4.5KB) +2. **削除**: `CODEX_QUESTION_backup.md`(3.7KB、バックアップ不要) + +**理由**: git履歴があるのでバックアップ不要 + +**結果**: +- ✅ バックアップ削除完了 +- ✅ 最新版のみ保持 + +--- + +#### Phase 2-C: 古いレポートの移動 ✅ +**目的**: 古い分析レポートをアーカイブに整理 + +**実行内容**: +1. **移動**: `REFACTORING_ANALYSIS_REPORT.md`(6.8KB)→ `docs/archive/reports/` +2. **移動**: `analysis_report.md`(21KB)→ `docs/archive/reports/` +3. **作成**: `docs/archive/reports/README.md`(アーカイブ説明) + +**結果**: +- ✅ 古いレポートをアーカイブに移動 +- ✅ README.mdでアーカイブの目的を明記 +- ✅ プロジェクトルートがクリーンに + +--- + +## 📊 削減・整理効果 + +### ファイル整理 +- **削除ファイル**: 3個 + - CURRENT_TASK_restored.md + - CODEX_QUESTION_backup.md + - docs/development/current_task_archive/(フォルダ) +- **移動ファイル**: 3個 + - CURRENT_TASK_ARCHIVE_2025-09-27.md + - REFACTORING_ANALYSIS_REPORT.md + - analysis_report.md + +### 構造改善 +- ✅ CURRENT_TASK系が1箇所に統一 +- ✅ アーカイブ構造が明確化(`docs/archive/reports/`) +- ✅ プロジェクトルートがさらにクリーン + +--- + +## 🧪 検証結果 + +### ビルド検証 +```bash +cargo build --release +``` +- **結果**: ✅ 成功 +- **警告**: 111個(既存のもの、Phase 2による新規警告なし) +- **コンパイル時間**: 0.07s(インクリメンタル) + +### 実行検証 +```bash +./target/release/hakorune /tmp/phase2_test.nyash +``` +- **テストコード**: `print("Phase 2 OK!")` +- **結果**: ✅ 成功 +- **出力**: `Phase 2 OK!` + +### Git状態 +```bash +git status --short +``` +- **削除**: 6個(CURRENT_TASK系3 + CODEX_QUESTION_backup + レポート2) +- **修正**: 2個(CURRENT_TASK.md + CLEANUP_REPORT) +- **新規**: 1フォルダ(docs/archive/reports/) +- **競合**: なし + +--- + +## 📝 重要な判断事項 + +### AGENTS.md は保持 +- **理由**: codex用ultrathink、削除してはいけない +- **状態**: 保持(Phase 3で検討しない) + +### アーカイブ方針 +- **統一先**: `docs/development/archive/current_task/` +- **古いレポート**: `docs/archive/reports/` +- **README.md**: 各アーカイブフォルダに説明を追加 + +--- + +## 🎯 Phase 2 達成内容 + +### 整理完了 +- ✅ CURRENT_TASK系の重複解消 +- ✅ CODEX_QUESTION系のバックアップ削除 +- ✅ 古いレポートのアーカイブ化 + +### 構造改善 +- ✅ アーカイブ構造の明確化 +- ✅ プロジェクトルートのクリーン化 +- ✅ 歴史的記録の適切な保管 + +### 品質保証 +- ✅ ビルド成功 +- ✅ 実行確認 +- ✅ Git状態クリーン + +--- + +## 📚 アーカイブ構造 + +### 現在のアーカイブ構造 +``` +docs/ +├── archive/ +│ ├── reports/ # 古い分析レポート(Phase 2新設) +│ │ ├── README.md +│ │ ├── REFACTORING_ANALYSIS_REPORT.md +│ │ └── analysis_report.md +│ └── ... +└── development/ + └── archive/ + └── current_task/ # CURRENT_TASK履歴 + ├── CURRENT_TASK_2025-09-27.md + ├── CURRENT_TASK_20251004-072112.md + ├── CURRENT_TASK_ARCHIVE_2025-09-27.md # Phase 2で追加 + └── claude_task_20251003-20251004.md +``` + +--- + +## ⏭️ 次のステップ + +### Phase 3は実施不要 +- **AGENTS.md**: codex用ultrathinkのため保持 +- **CHANGELOG.md**: ユーザー判断待ち(オプション) +- **paper_review_prompts.md**: ユーザー判断待ち(オプション) + +--- + +## 🎉 Phase 2 完全達成! + +**整理完了項目**: +- ✅ CURRENT_TASK系の統合(3ファイル → 1ファイル) +- ✅ CODEX_QUESTION系の整理(2ファイル → 1ファイル) +- ✅ 古いレポートのアーカイブ化(2ファイル移動) +- ✅ アーカイブ構造の明確化(README.md追加) +- ✅ ビルド・実行検証完了 + +**Phase 1 + Phase 2 合計削減効果**: +- **容量削減**: 700MB(Phase 1) +- **ファイル削減**: 70+個(Phase 1: 69個 + Phase 2: 6個) +- **構造改善**: プロジェクトルート・docs/構造の大幅クリーン化 + +--- + +**完了日時**: 2025-11-04 16:50 +**総作業時間**: Phase 1 30分 + Phase 2 10分 = 40分 +**品質**: ✅ 全チェック完了、問題なし +**次のアクション**: コミット作成(オプション) diff --git a/docs/development/current_task_archive/CURRENT_TASK_2025-09-27.md b/docs/development/current_task_archive/CURRENT_TASK_2025-09-27.md deleted file mode 100644 index 34637bfc..00000000 --- a/docs/development/current_task_archive/CURRENT_TASK_2025-09-27.md +++ /dev/null @@ -1,1828 +0,0 @@ -# Current Task — Phase 15 (Revised): Self‑Hosting Focus, JSON→Ny Executor - -Updated: 2025‑09‑27 - -Quick status -- Build: `cargo build --release` → OK(警告のみ) -- Smokes v2: quick/core PASS、integration/parity PASS(Python LLVM harness) -- Parser: TokenCursor 統一 Step‑2/3 完了(env ゲート) -- PHI: if/else の incoming pred を exit ブロックへ修正(VM 未定義値を根治) -- Resolver: using 先を DFS で事前ロードする共通ヘルパー導入(common/vm_fallback 両経路で `resolve_prelude_paths_profiled` を採用済み) - - Loop‑Form: ループ低下を LoopBuilder 正規形(preheader→header(φ)→body→latch→exit)に統一(cf_loop 経由) - -Today’s update(2025‑09‑27 pm) -- LoopForm if 入口の PHI 入力を pre_if スナップショット参照に固定(then/else の相互汚染を禁止)。 -- if トレース追加(`NYASH_IF_TRACE=1`): then/else 入口PHI・合流PHIの var/pre/dst/preds を可視化。 -- VM InstanceBox dispatcher 強化(BoxCall→関数): - - 候補順: `Class.method/Arity` → `ClassInstance.method/Arity` → `Class.method/(Arity+1)` → 一意な「`.method/Arity`」末尾一致。 - - `toString/0` → `stringify/0` 特別フォールバック。 - - 追跡ログ: `NYASH_VM_TRACE=1` で候補・命中名を出力。 -- JsonScanner のフィールド getField 補強(内部が Null/None の場合に開発用デフォルトを適用)。 -- ビルダー側のインスタンス書き換えは既定OFF、検証時のみ `NYASH_BUILDER_REWRITE_INSTANCE=1` で有効化。 - -追加の微修正(2025‑09‑27 late) -- JsonParser.parse/1 の戻り型を安定化(Builder 注釈) - - `annotate_call_result_from_func_name` に特例を追加し、署名が Unknown/Void の場合でも `MirType::Box("JsonNode")` を付与。 - - 署名が取得できない場合も最小ヒューリスティックで同注釈を適用(Builder DEBUG ログ対応)。 -- VM InstanceBox ディスパッチの一意尻一致フォールバックをナローイング - - 多候補時は受け手クラス接頭(`.`/`Instance.`)で再絞り込み、1件ならヒットとする。 - - `NYASH_VM_TRACE=1` でナローイング経路をログ出力。 - -直近の受け入れ確認(要再実行) -- 単体ドライバ: `r = JsonParser().parse("{\"a\":1}"); print(r.toString())` が `JsonNode.stringify/0` に命中(VM トレースで確認)。 -- v2 quick: `NYASH_USING_PROFILE=dev NYASH_USING_AST=1 bash tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` が完走。 - -Resolved — Integer stringify shortens (42 → 4) -- Symptom: In JSON VM quick, the integer sample "42" prints as "4" while other types (null/bool/float/array/object) stringify correctly. -- Hypotheses: - - Value truncation during convert_number → create_int flow, or parse_integer returns incorrect value in some path. - - Field bridging is not the culprit (InstanceBox getField/setField already maps NyashValue::Integer i64 correctly), but will confirm via trace. -Fix (2025‑09‑27): -- Root cause: StringUtils.parse_integer parsed only the first digit; multi-digit accumulation was incorrect. -- Patch: Rewrote per‑digit loop using an index_of lookup over "0123456789" and `acc = acc * 10 + d`; kept sign handling and integer validation. -- Also unified stringify(int) on both static/instance JsonNode to use `me.value.toString()`. -- Result: Minimal drivers A/B now print "42"; `json_roundtrip_vm` passes under dev+AST. - -Open item — json_nested_vm (VM) fails (debug in progress) -- Symptom (quick/core/json_nested_vm.sh): - - Expected: `[1,[2,3],{"x":[4]}]`, `{\"a\":{\"b\":[1,2]},\"c\":\"d\"}`, `{\"n\":-1e-3,\"z\":0.0}` - - Actual: `null` for all three samples under VM path (AST counterparts pass) -- Notes: - - Earlier, a stray semicolon at block endings triggered a tokenizer parse error. For smoke stability only, we added a dev-only ASI-like strip in test_runner to remove trailing `;` before VM run (SMOKES_ASI_STRIP_SEMI=1 default). After that, error turns into `null` results => true parse failures remain. - - AST-based tests for nested JSON pass; issue is specific to VM execution path for nested structures. -- Hypotheses: - 1) Number tokenization edge (exponent + sign: `-1e-3`, `0.0`) in VM path. - 2) Nested object/array boundary handling (Tokenizer.read_string_literal / read_number / structural tokens) differs under VM fallback. - 3) validate_number_format too strict in VM path relative to AST expectations. -- Plan (do not force green; debug methodically): - 1) Repro with diagnostic driver printing parser errors per sample (`p.print_errors()`). - 2) Enable targeted traces: `NYASH_VM_TRACE=1`, optional tokenizer-local prints if needed. - 3) Inspect JsonTokenizer.read_number and validate_number_format for exponent and decimal handling; align with AST behavior. - 4) Fix narrowly (number validation or structural token sequence) and re-run only json_nested_vm; then re-run quick profile. -- Acceptance: - - json_nested_vm prints expected three lines; no other quick tests regress. - -現状観測(after fixes) -- 未定義PHIは解消。`r.toString()` 出力が `JsonNodeInstance()` のまま残るケースあり。 -- `object_set` 呼び出しも VM 側で動的解決の一意尻一致フォールバックを追加済みだが、引っかからないケースがある(受け値の型/起源が落ちている可能性)。 - -JSON VM 根治(WIP) -- 症状: `json_roundtrip_vm`(VM fallback)が `TypeError: unsupported compare ... on Void` で停止(以前は `Integer vs Void`、現在は `Void vs Void` まで改善)。 -- 原因(一次): ユーザー Box のフィールドが VM 側の外部マップ(obj_fields)に保存され、インスタンス同一性の継ぎ目で取りこぼすことがある。 -- 施した修正(最小・仕様不変): - - VM インタープリタ `getField/setField` を優先的に `InstanceBox` の内部フィールド(`fields_ng: NyashValue`)へ委譲。 - - NyashValue ↔ VMValue の最小ブリッジを実装(数値/真偽/文字列/Null→Void)。 - - dev 導線: `NYASH_VM_VERIFY_MIR=1` で VM fallback 前に関数単位の MIR 検証(`MirVerifier.verify_function`)を走らせてヒントを出力。 -- 現状の観測: - - `JsonScanner.birth` による `length/line/column/position` 初期化は安定(min 再現で確認)。 - - `json_roundtrip_vm` は別箇所(比較)で Void が混入。未初期化フィールド(Null→Void)または merge 付近の値流れの可能性。 -- 次の対処(局所・点修正で緑化): - 1) Verifier ログで該当関数の merge/支配関係違反を特定(dev 環境のみ)。 - 2) 比較/条件構築のピン不足箇所に `ensure_slotified_for_use` を追加(漏れ潰し)。 - 3) 必要なら「スキャナの数値系フィールド」の既定値(0/1)を dev フラグ下で補う(`NYASH_VM_SCANNER_DEFAULTS=1` 追加検討)。 - 4) 緑化後に dev 安全弁(Void 許容)を撤去/既定 OFF 固定。 -− 受け入れ: `tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` が dev/prod(AST using)で緑。 - -追加タスク(インスタンス呼び出しの最終詰め) -- 目的: `JsonNode.stringify/0` / `JsonNode.object_set/2` などが確実に関数呼びに正規化され、`JsonNodeInstance()` 表示が JSON 文字列へ置換されること。 -- 手順(診断→修正の順): - 1) 単体ドライバでトレース取得: - - 実行: `NYASH_VM_TRACE=1 NYASH_BUILDER_REWRITE_INSTANCE=1` で `instance-dispatch class=... method=toString/0` 等の候補/命中ログを確認。 - - 関数表: `NYASH_DUMP_FUNCS=1`(vm_fallback)で `JsonNode.stringify/0` / `JsonNode.object_set/2` の存在確認。 - 2) 命中しない場合: - - `handle_box_call` で `recv` の型名(`recv_box.type_name()`)をログ出し、InstanceBox 判定漏れを特定。 - - 末尾一致の一意解決が多候補なら、`JsonNode` 系に限定するナローイングを追加。 - 3) 緑化確認: `json_roundtrip_vm.sh` が期待出力に一致。 - -受け入れ基準(今回のスライス) -- if/LoopForm の入口PHIが常に pre_if スナップショットから生成される(`NYASH_IF_TRACE=1` で確認)。 -- `json_roundtrip_vm` が VM で完走し、 `JsonNodeInstance()` ではなく JSON 文字列を出力。 -- VM トレースで `instance-dispatch hit -> JsonNode.stringify/0` 等の命中が確認できる。 - -根治テーマ(新規) — birth 呼び出しの責務分離と生成位置の是正 - -問題の本質(層の責務分離違反) - -- 現状(暫定パッチ): - - VM 実行器が `NewBox` 実行時に自動で `birth` を探して呼び出す(`handle_new_box` 内で `Class.birth[/Arity]` を探索・実行)。 - - 目的はユーザー Box の初期化だが、これは本来コンパイラ(MIR ビルダー)の責務。 -- 正しい設計: - - using 層/コンパイラが `new MyBox(args)` を MIR へ明示展開する。 - - 期待する MIR 例: - - `dst = NewBox MyBox(args...)` - - `Call { callee = Global("MyBox.birth/N"), args = [dst, args...] }` - - 以後 `dst` を使用 - - VM 実行器は MIR を忠実に実行するだけ(自動 birth 呼び出しは不要)。 -- リスク(現状パッチの副作用): - - 層を跨いだ肩代わりで制御不能(無限再帰/二重初期化/順序依存の温床)。 - - デバッグ困難化(birth 呼び出しが MIR に現れない)。 - -方針(根治) - -1) MIR ビルダー側で `new` の正規展開を実装(birth 明示呼び出しの生成) - - 対象: `ASTNode::New`(既存の new ノード)または同等の生成箇所。 - - 生成: - - `dst = NewBox (args...)` - - 存在する場合: `Call Global(".birth/N"), argv = [dst, args...]` - - birth 不存在時は Call を省略(既存互換)。 - - 併せて、ユーザー定義メソッドの関数名規約 `./` に統一し、birth 検索も同規約で行う。 - -2) VM 実行器の自動 birth 呼び出しを段階的に撤去 - - Step‑A(即時): dev フラグで既定 OFF(`NYASH_VM_AUTO_BIRTH=0` 既定)。 - - Step‑B(ビルダー実装安定後): 自動呼び出しコードを削除。 - -3) 付随の整合 - - 静的名→インスタンス別名(`JsonNode` → `JsonNodeInstance`)の alias は vm_fallback の簡易ファクトリで保持(当面)。 - - 将来は宣言解析で静的/インスタンスの関連付けを明示して alias 依存を解消。 - -テスト計画 / 受け入れ条件 - -- MIR 生成の確認: - - `--dump-mir`/`NYASH_VM_TRACE=1` で `NewBox ` の直後に `Call .birth/N` が現れる。 - - VM 実行ログからは `handle_new_box` 内での自動 birth 呼び出しが消えている(実行器は NewBox のみ)。 -- 機能スモーク: - - `json_roundtrip_vm` が dev/prod(AST using)で完走。少なくとも null/bool/int/string の基本ケースが期待出力。 - - `new JsonParser()` などのユーザー Box 生成で未初期化フィールド由来の Void 混入が再発しない。 -- 回帰抑止: - - birth 不存在な Box でも従来通り動作(Call を生成しない)。 - -作業ステップ(詳細) - -1) Builder: `new` 正規展開 - - ファイル: `src/mir/builder/exprs.rs`(`ASTNode::New` 分岐)、必要なら専用モジュール。 - - 実装: NewBox emit → `module.functions` で `.birth/N` を探索 → あれば Global Call emit(先頭 arg に me=dst)。 - - 備考: 既存の「メソッド→関数」低下 (`lower_method_as_function`) の規約に合わせる。 - -2) VM: 自動 birth を dev 既定 OFF に変更 → 後で削除 - - ファイル: `src/backend/mir_interpreter/handlers/boxes.rs`(`handle_new_box`)。 - - Step‑A: `if env(NYASH_VM_AUTO_BIRTH)==1 のみ` birth を試行(既定 0)。 - - Step‑B: Builder 安定後に完全削除。 - -3) スモーク/検証の整備 - - 新規: mini birth 展開テスト(`new Box(x);` で `NewBox`→`Call birth` が生成されるか)。 - - 既存: `json_roundtrip_vm` / `mini_call_starts_with` を AST using(dev/prod)で確認。 - -リスクとロールバック - -- 万一 Builder 実装で birth が生成されない場合でも、dev では env=1 で VM 自動 birth を一時的に再有効化可能。 -- ただし最終到達点は VM 自動 birth の完全撤去。CURRENT_TASK で管理し段階的に外す。 - -MIR/VM 進捗(SSA/短絡/ユーザーBox) -- 短絡(&&/||): 分岐+PHI で正規低下(RHS 未評価)を実装済み。 -- 比較オペランド: その場 `pin_to_slot` で slot 化、PHI 参加(支配関係破れの根治策)。 -- ブロック入口: then/else/短絡入口に単一 pred PHI を配置(局所定義を保証)。 -- ユーザーBox呼び出し(VM fallback): - - Builder 側: user‑defined Box のインスタンスメソッドは `Box.method/Arity` 関数へ書き換え('me' 先頭引数、関数名の Arity は 'me' を含めない)。 - - VM 側: BoxCall で InstanceBox を受けた場合、存在すれば `Box.method/Arity` に動的フォールバック実行('me'+args を渡す)。 - -現状の未解決(再現あり) -- JSON VM quick が `BoxCall unsupported on VoidBox.current` で停止。 - - トレース: `JsonTokenizer.next_token` 内で `me.scanner.current()` が BoxCall 経路に残存。 - - 期待: Builder が user‑defined `JsonScanner` を検知して `JsonScanner.current/0` へ書き換えるか、VM が fallback で補足。 - - 観測: 関数一覧に `JsonScanner.current/0` が存在しないケースがある(環境差/順序の可能性)。 - - 以前の実行では `JsonScanner.current/0` が列挙されていたため、低下順または条件分岐の取りこぼしが疑わしい。 - -## 方向修正(複雑性の抑制と安定化) — 2025‑09‑27 - -- 遅延注釈・保険フック・VM 側の大改造は一旦見送り、シンプルな導線で解消する。 -- 根治の順序: - 1) Resolver 強化(nested using を DFS で AST 事前ロード) - 2) 低下順の一貫化(宣言インデックス後に関数群が常に materialize) - 3) 書き換えは「関数存在」の一点で採否(既に実装済み) - 4) 必要箇所のみ Loop‑Form(Builder 側、flag 付き) - -ロールバック(安定化のため) -- VM インタプリタの一時変更は元に戻す: - - obj_fields のキー安定化(Arc ptr ベース)を撤回し、暫定的に従来挙動へ復帰。 - - host_api の BoxRef → NyashValue 変換や戻り値の挙動変更は撤回(既定の最小仕様に戻す)。 - - 目的は無限ループ/非停止の芽を確実に摘むこと(後段の Resolver 強化で書き換えが安定すれば、ここを再度検討可能)。 - -次のステップ(最小) -1) 上記ロールバックを反映して quick/core JSON を再実行(ハングがないことの確認)。 -2) Resolver: using 先の再帰(nested)を DFS で事前 AST 化し、その結果を `index_declarations` 前に連結。 -3) `NYASH_DUMP_FUNCS=1` で `JsonScanner.current/0` の存在、`NYASH_BUILDER_DEBUG=1` で user‑box 書き換え採用ログを確認。 -4) json_roundtrip_vm を再実行。完走したら、VM 側の臨時ガードや余計な保険を段階的に外す。 - -受け入れ条件(このスライス) -- nested using の AST 事前ロードにより依存関数が常に materialize。 -- user‑box 書き換えは「関数存在」の一点で採否(ブレなし)。 -- json_roundtrip_vm が完走(無限ループなし)。 -- 遅延注釈・保険フックなどの複雑化を増やしていない。 - -## 根治戦略(確定方針) - -結論: -- 制御フロー/SSA の根治は Option‑B(Loop‑Form 導入)が本命。 -- ただし今回の「起源未伝搬→書き換え不発」は依存解決/宣言順の問題が主因のため、まず Resolver 側を確立し、その上で Loop‑Form を段階導入する。 - -進め方(順序) -1) Resolver 根治(小規模・点修正) — ✅ 2025‑09‑27 実装済み - - `resolve_prelude_paths_profiled` を canonicalize+DFS 化し、common/vm_fallback 両経路で採用。 - - nested using も AST 事前ロードに含まれるよう整理済み(書き換えは既存の「関数存在」基準を継続)。 -2) Loop‑Form(PHI根治) — ✅ 2025‑09‑27 既定経路へ切替 - - 低下経路を loop_api(簡易) から LoopBuilder(正規形: preheader→header(φ)→body→latch→exit)に統一。 - - 変更: `src/mir/builder_modularized/control_flow.rs::build_loop_statement` を `self.cf_loop(..)` に切替。 - - 既存の `src/mir/loop_builder.rs` + `mir/phi_core/loop_phi.rs` の φ 生成/封止を活用(continue/break の取り込みと latch wiring を保証)。 - - 目的: SSA 支配関係の事故・未定義参照・分岐合流のゆらぎを構造的に排除。 - -受け入れ条件(Loop‑Form スライス) -- 代表ループ(tokenizer/scanner の while)で header φ が生成され、continue/break が latch/exit に束ねられていること(`--dump-mir` で確認)。 -- json_roundtrip_vm(VM fallback)で未定義参照・無限ループが再発しない(既存の短絡/if の diamond と整合)。 -- フラグ OFF 時は従来どおり(既定挙動は変えない)。 - -## ADR 受理: No CoreBox & Everything is Plugin(Provider/Type 分離) - -- CoreBox は戻さない。Kernel は最小(GC/Handle/TLV/Extern/PluginRegistry/ABI)。 -- 型名(STN: `StringBox` 等)は不変、実装提供者(PVN)は TOML で切替。 -- 起動は「Kernel init → plugins.bootstrap/static + plugins.dynamic → Verify → 実行」。 -- VM/LLVM は `ny_new_box` / `ny_call_method` に統一(段階導入)。 -- ADR: docs/development/adr/adr-001-no-corebox-everything-is-plugin.md を追加。 - -受け口フェーズ(挙動不変) -- K0: ADR/Docs 追加(完了)。 -- K1: TOML スキーマ雛形(types/providers/policy)受け口(後続)。 -- K2: Provider 解決ログの受け口(後続)。 -- K3: Verify フック(preflight_plugins)受け口(後続)。 -- K4: Bootstrap Pack 登録導線(prod限定フラグ; 後続)。 - -## Using / Resolver — “Best of Both” Decision(2025‑09‑26) - -合意(いいとこどり) -- 依存の唯一の真実(SSOT)を `nyash.toml` `[using]` に集約(aliases/packages/paths)。 -- 実体の合成は AST マージに一本化(テキスト結合・括弧補正の互換シムは段階的に削除)。 -- プロファイル導入で段階移行: `NYASH_USING_PROFILE={dev|ci|prod}` - - dev: toml + ファイル内 using/path を許可。診断ON、限定的フォールバックON。 - - ci: toml 優先。ファイル using は警告/限定許可。フォールバックOFF。 - - prod: toml のみ。ファイル using/path はエラー(toml 追記ガイドを表示)。 - -やること(仕様不変・既定OFFで段階導入) -1) ドキュメント - - [x] `docs/reference/language/using.md` に SSOT+AST/Profiles/Smokes を追記。 - - [x] ADR を追加(No CoreBox / Provider 分離) -2) Resolver 統合 - - [x] vm_fallback に AST プレリュード統合を導入(common と同形)。 - - [x] prod での `using "path"`/未知 alias はエラー(修正ガイド付)。 - - [x] prelude 決定(toml優先/プロファイル対応)の共通ヘルパを新設し、呼び出し側を一元化(`resolve_prelude_paths_profiled`)。 -3) レガシー削除計画 - - [x] prod でテキスト結合(combiner)/括弧補正を禁止(ガイド表示)。 - - [ ] dev/ci でも段階的に無効化 → parity 緑後に完全削除。 -4) パーサ堅牢化(必要時の安全弁、NYASH_PARSER_METHOD_BODY_STRICT=1) - - [x] メソッド本体用ガードを実装(env で opt-in)。 - - [x] Guard 条件をトップレベル限定かつ `}` 直後のみ発火に調整(誤検知回避)。 - - [ ] `apps/lib/json_native/utils/string.nyash` で stray FunctionCall 消滅確認。 - -## シンプル化ロードマップ(claude code 提案の順) - -1) VM fallback 強化(mini 緑化) - - [x] レガシー解決の正規化(Box.method/Arity) - - [x] 文字列の最小メソッド(substring 等)暫定実装(短期・撤去予定) -2) dev/ci で AST 既定ON(prodはSSOTを維持) - - [ ] 既定値切替とスモーク緑確認 -3) レガシー using 経路の段階削除 - - [x] 呼び出し側のレガシー分岐を撤去(common/vm/vm_fallback/pyvm/selfhost を AST 経路に統一) - - [ ] strip_using_and_register 本体のファイル内撤去(後続の掃除タスクで対応) -4) パーサガードの格下げ→撤去 - - [x] Guard を log-only に格下げ(NYASH_PARSER_METHOD_BODY_STRICT=1 でも break せず警告ログのみ) - - [x] Guard 実装を撤去(method-body 専用のシーム判定を削除、通常ブロック同等に) - -5) 宣言順序の根治(Builder 2パス: 宣言インデックス → 低下) - - [x] MirBuilder に index_declarations を導入(Phase A) - - [x] user_defined_boxes と static_method_index を統一収集(AST一回走査) - - [x] lower_root 先頭で index_declarations を呼び、既存の個別 preindex_* を置換 - - [ ] 追加の前方参照ケース(interface/extern等)発見時は同関数でカバー(設計上の拡張点) - -受け入れ基準(追加) -- quick/integration スモークが AST 既定ON(dev/ci)で緑。 -- mini(starts_with)が VM fallback / LLVM / PyVM のいずれか基準で PASS(VM fallback は暫定メソッドで通せばOK)。 - - Builder 順序不整合の解消: 出現順に依存せず、new/静的メソッドの前方参照が安定解決。 - -## いま着手中(SSA pin/PHI と user‑defined 呼び出しの根治) - -目的 -- 「式一時値の支配関係破れ」由来の未定義参照を構造的に排除(pin→PHI)。 -- user‑defined Box のインスタンスメソッド呼び出しを 100% `Box.method/Arity` へ正規化し、VM fallback でも実行可能にする。 - -実装済み -- 短絡: And/Or を分岐+PHI で実装。 -- 比較: 左右オペランドを都度 pin→PHI 参加。 -- 分岐入口: then/else/短絡入口に単一 pred PHI を配置(正規化)。 -- VM fallback: InstanceBox に対する BoxCall を `Box.method/Arity` 関数へ動的フォールバック('me'+args)。 -- Builder: user‑defined Box のメソッド呼び出しを `Box.method/Arity` 関数へ書き換え(存在確認つき)。 - -未解決点(原因候補) -- `JsonScanner.current/0` が関数一覧に存在しない実行がある → インスタンスメソッド低下の取りこぼし疑い。 - - 仮説A: `build_box_declaration` の instance method 低下が順序/条件でスキップされるケースがある。 - - 仮説B: `field_access` → `value_origin_newbox` の伝搬が不足し、Builder が user‑defined 判定に失敗(BoxCall に落ちる)。 - -デバッグ手順(再現と確認) -- 関数一覧の確認: `NYASH_DUMP_FUNCS=1 NYASH_VM_TRACE=1 ... --backend vm driver.nyash` - - 期待: `JsonScanner.current/0` を含む。 -- Builder トレース: `NYASH_BUILDER_DEBUG=1`(userbox method 書き換え時に `userbox method-call ...` を出力) -- フィールド由来の型伝搬: `build_field_access` で `field_origin_class` → `value_origin_newbox` 反映の有無をログで確認。 - -次の作業(順番) -1) 低下順序の点検 - - `build_box_declaration` の instance method 低下が常に走ることを再確認(静的/インスタンス混在時、重複/上書きなし)。 - - `JsonScanner` の全メソッド(`current/0` 含む)が `module.functions` に常に登録されることをテストで保証。 -2) 型伝搬の強化 - - `build_field_access` 経由の `value_origin_newbox` 伝搬を明示ログ化し、`scanner` フィールドで `JsonScanner` を確実に付与。 - - 併せて `value_types` に `MirType::Box(JsonScanner)` を注釈(判定補助; 既定OFFの安全弁として env ゲートで導入)。 -3) 呼び出し書き換えの網羅 - - `handle_standard_method_call` の user‑defined 書き換えを早期に実施(BoxCall へ落ちる前に判定)。 - - `CallTarget::Method` 経由の経路も同一ロジックで統一。 -4) 検証 - - ミニ: `me.scanner.current()` を含む 1 ケースで `NYASH_DUMP_FUNCS=1` と Builder/VM トレース確認、BoxCall が消えて Call(`JsonScanner.current/0`, me) であること。 - - quick/core JSON VM: 代表ケース再実行。未定義参照や Void 経路暫定ガードが発火しないこと。 - -注意(暫定対策の扱い) -- `eval_binop(Add, Void, X)` の簡易ガードは開発用の安全弁。根治後に撤去する(テストが緑になってから)。 - -受け入れ基準(このタスク) -- `JsonTokenizer.next_token` で `me.scanner.current()` が Call 経路に正規化され、BoxCall 不要。 -- `JsonScanner.current/0` が常に関数一覧に存在。 -- JSON VM quick が未定義参照・BoxCall unsupported を出さずに最後まで出力一致(ノイズ除去込み)。 - -受け入れ基準 -- StringUtils の `--dump-ast` に stray FunctionCall が出ない(宣言のみ)。 -- mini(starts_with): ASTモード ON/OFF で parse→MIR まで到達(VM fallback の未実装は許容)。 -- prod プロファイル: 未登録 using/パスはエラーになり、toml 追記指示を提示。 - -### 進捗ログ(2025‑09‑26 PM) -- Profiles + SSOT 実装(prod で file using 禁止、toml 真実)→ 完了。 -- VM fallback に AST プレリュード導入 → 完了。 -- Parser: method-body guard を env で opt-in 実装(既定OFF)。 - - 現状: OFF 時は `string.nyash` にて Program 配下に `FunctionCall(parse_float)` が残存。 - - 次: Guard ON で AST/MIR を検証し、必要に応じて lookahead 条件を調整。 - -### JSON Native — Unicode/BMP とスモーク拡張(2025‑09‑26 late) -- EscapeUtils 改善(仕様不変・堅牢化) - - char_code: 未知文字を -1 に変更(制御文字扱いしない)。 - - is_control_char: ASCII 0x00–0x1F のみ対象に明確化。 - - hex_to_char: 制御系を追加(0000/0008/0009/000A/000C/000D)+既存 ASCII/BMP 基本を維持。 -- AST プレリュードの再帰処理 - - runner common/vm_fallback で using 先のファイルにも `collect_using_and_strip` を適用し、入れ子 using を DFS で展開してから AST 化。 -- dispatch ガード - - `vm` ブランチは既定の VM fallback を維持。`NYASH_USE_AST_RUNNER=1` を追加(将来の AST ランナー用の開発ガード;現状は未使用に留める)。 -- スモーク追加(quick/core) - - json_long_string_ast.sh(長い文字列の roundtrip) - - json_deep_nesting_ast.sh(深いネストの配列/オブジェクト) - - json_error_positions_ast.sh(行/列つきエラーUX: 欠落カンマ、未知キーワード、複数行オブジェクト) - - json_unicode_basic_ast.sh(\u0041/\u000A の基本確認) - -注意/未解決(ブロッカー) -- `apps/lib/json_native/utils/string.nyash` の静的ボックス終端で Parser が `Expected RBRACE`(EOF)を報告(トレース: static-box ループ末尾で `}` 未検出)。 - - 既知の「メソッド継ぎ目」問題の再燃と推測。static box メンバーの宣言≻式をループ側でも再確認し、必要なら lookahead を強化(`)`→`{` の改行許容)。 - - 一時回避として Guard を戻すことも可能だが、宣言優先の根治を優先する。 - - このため、追加スモークは実装済みだが、現時点では prelude 解析段で停止する(Runner 側の再帰処理は完了済み)。 - -### VM fallback の制約と対応状況(更新) -- 既定 `--backend vm` は VM fallback(MIR interpreter)。現在の対応状況: - - ArrayBox.birth / push / len / get / set … 実装済み(最小) - - StringBox.substring … 実装済み(最小・時限的) - - ユーザー定義 Box(例: `JsonParser`)の NewBox … 最小 UserFactory を登録して対応(本タスクで実装) -- これにより、VM fallback でも `new JsonParser()` などのユーザー型生成が可能になった。 -- 依然として JSON スモークは LLVM ハーネス経路で走らせているため、緑化には実行経路の切替(もしくはハーネスの namespace 受理)が必要。 - -### Builder 宣言インデックス化(設計メモ) -- docs/development/notes/mir-declaration-indexing.md を追加 -- 目的: 個別 preindex_* の増殖を防ぎ、順序に依存しない lowering を実現 -- 実装: lower_root 入口で index_declarations、以降は従来どおり lowering - -### 追加進捗(Using/Verify 受け口 2025‑09‑26 EOD) -- Provider Verify: nyash.toml の `[verify.required_methods]` / `[types.*.required_methods]` を読んで検査(env とマージ) - - 受け口: `NYASH_PROVIDER_VERIFY=warn|strict`、`NYASH_VERIFY_REQUIRED_METHODS`(任意上書き) - - preflight: `tools/smokes/v2/lib/preflight.sh` から warn で起動。`SMOKES_PROVIDER_VERIFY_MODE=strict` でエラー化 -- Using: レガシー前置き経路を呼び出し側から完全撤去(AST プレリュードに一本化) - - AST 無効プロファイルで using がある場合はガイド付きエラー - - 内部実装: 旧 strip_using_and_register/builtin 経路の物理削除(ファイル再構成) - -## 今日の合意(方向修正の確定) -- Rust層は新機能を最小化。今後は Nyash VM/コンパイラ(自己ホスト)へリソース集中。 -- 次タスクは Nyash 製 JSON ライブラリ(JSON v0 DOM: parse/stringify)。完了次第、Ny Executor 最小命令の実装を着手。 -- LLVM ラインは Python/llvmlite ハーネスを正式優先(llvm_sys_180 依存は前提にしない)。 -- GC は“安全網と計測の小粒強化”に限定(既定: RC、不変)。 - -## 直近10日の実行計画(小粒・仕様不変・既定OFF) -1) JSON types/lexer/parser/encoder(Nyash) - - Path: `apps/lib/json_native/{types,lexer,parser,encode}.nyash` - - Env: `NYASH_JSON_PROVIDER=ny`(既定OFF) - - Smokes: roundtrip/parse_error 最小セット(quick/core には既定OFFで影響なし) -2) Ny Executor(最小命令) - - ops: const/binop/compare/branch/jump/ret/phi - - Env: `NYASH_SELFHOST_EXEC=1`(既定OFF) - - Smokes: arith/if/phi(parity: PyVM/LLVM harness) -3) 呼び出し最小(MVP) - - call/externcall/boxcall(Console/String/Array/Map の P0) - - 代表スモーク: print/concat/len/has 基本 -4) 監視期間(数日)→ 旧 depth/skip 残骸の完全削除と警告掃除(任意) - -受け入れゲート -- quick/core + integration/parity 緑(env ON/OFF 双方) -- 既定挙動を変えない(新経路はすべて env トグルで opt‑in) -- 変更は小さくロールバック容易 - -主要トグル(統一) -- `NYASH_LLVM_USE_HARNESS=1`(Python llvmlite ハーネス) -- `NYASH_PARSER_TOKEN_CURSOR=1`(式/文を Cursor 経路で) -- `NYASH_JSON_PROVIDER=ny`(Ny JSON) -- `NYASH_SELFHOST_EXEC=1`(Ny Executor) -- `NYASH_GC_MODE=rc|rc+cycle|stw`(既定rc)/ `NYASH_GC_METRICS=1`(任意) - -ドキュメント更新(本日) -- phase‑15/README.md: 2025‑09‑26 更新ノートを追加(JSON→Self‑Host への舵切り、TokenCursor/PHI/Loop PHI 統合の反映) -- phase‑15/ROADMAP.md: Now/Next を刷新(JSON ライブラリを Next1 に昇格、Cranelift 記述は凍結注記) -- selfhosting‑ny‑executor.md: Stage‑1 に Ny JSON 依存を明記 -- README.md: Phase‑15(2025‑09)アップデートのクイックノート追記(Python ハーネス・トグル案内) - ---- - -以下は履歴ノート(必要時の参照用)。最新の計画は上記ブロックを正とする。 - ---- - -Include → Using 移行状況(2025‑09‑26) -- コード一式を `using` に統一(apps/examples/selfhost/JSON Native 等)。 -- ランナーの一時互換シム(`local X = include "..."` を `using` として扱う処理)を削除。 -- 残存の `include` はコメント/ドキュメント/外部Cコードのみ。 - -Addendum (2025‑09‑26 2nd half) -- VM naming: added public alias `backend::NyashVm` and `backend::VM` → both point to `MirInterpreter` (Rust VM executor). No behavior change; improves clarity across runner/tests. -- Smokes v2: - - Moved `stringbox_basic.sh` to plugins profile (plugin-centric behavior varies). Quick profile now focuses on core semantics and using. - - Adjusted StringBox tests to tolerate plugin‑first output descriptors and to SKIP the still‑unwired `StringBox.length` VM path. - - Kept quick/core green locally; any remaining harness flakiness will be addressed by instrumenting `run.sh` after this pass. -- Test runner: filtered deprecation hints for builtin StringBox from outputs to reduce noise. -- Using docs: verified unified design doc reflects `[using.paths]`, `[using.] (path/main/kind/bid)`, aliases, and autoload guard `NYASH_USING_DYLIB_AUTOLOAD=1`. -- Plugins profile: ensure fixture plugin notes include Windows/macOS filename differences. - -## 🚀 **戦略決定完了: Rust VM + LLVM 2本柱体制確立** - ---- - -## Phase 15.5 – 改行(ASI)処理リファクタ再開と TokenCursor 統一計画(2025‑09‑26) - -目的 -- 改行スキップ/行継続/括弧深度の判定を TokenCursor に一元化し、既存の二重経路(ParserUtils/depth_tracking/parser_enhanced)を段階撤去する。 - -現状(スキャン要約) -- 本命: `src/parser/cursor.rs`(TokenCursor — NewlineMode と括弧深度で一元管理) -- 旧来: `src/parser/common.rs`(ParserUtils.advance + skip_newlines_internal)/ `src/parser/depth_tracking.rs` -- 実験: `src/parser/parser_enhanced.rs`(thread‑local) -- TokenCursor 利用は `expr_cursor.rs`/`nyash_parser_v2.rs`(実験)、本線は旧来経路が多い - -小粒ロードマップ(仕様不変・Guard 付き) -1) Bridge(完了): `NYASH_PARSER_TOKEN_CURSOR=1` で式パースを TokenCursor に委譲(デフォルトOFF) - - 実装: `src/parser/expressions.rs:parse_expression` に実験経路を追加し、`ExprParserWithCursor` を呼び、消費位置を同期 -2) 式レイヤ段階移行: primary/compare/logic/term/factor/call/coalesce/match_expr を順に TokenCursor に寄せる - - 呼び元(文レイヤ)は薄いラッパで接続(挙動は不変) -3) 旧来撤去(最終): `common.rs` の skip 系、`depth_tracking.rs`、`parser_enhanced.rs` を段階削除 - - 削除は“参照 0” になってから。互換性に触れないこと - -受け入れ条件 -- quick/core と integration/parity の追加スモークが緑(PHI/分岐/ループ/比較/連結) -- LLVM は Python ハーネスで parity を確認(`NYASH_LLVM_USE_HARNESS=1`) -- 既定挙動は不変(TokenCursor 経路は環境変数で opt‑in のみ) - -進捗(本コミット時点) -- [x] Bridge 実装: `NYASH_PARSER_TOKEN_CURSOR=1` で TokenCursor による式パースが動作 -- [x] スモーク拡充: quick/core(PHI/比較/ループ/0除算) + integration(parity 代表) -- [x] PHI 修正: incoming pred を then/else の exit ブロックに統一(VM 未定義値を根治) -- [x] PHI 検証(dev): 重複 pred/自己参照/CFG preds 含有の debug アサート追加 -- [x] テストランナー: 出力ノイズの共通フィルタ化(filter_noise) -- [x] Legacy 撤去(1): `src/parser/depth_tracking.rs` を削除。`NyashParser` から `paren/br ace/bracket` 深度フィールドを除去し、`impl ParserUtils for NyashParser` を `src/parser/mod.rs` に最小実装(depth 無し)で移設。既定の Smart advance は共通実装(`common.rs`)を既定ONに統一(`NYASH_SMART_ADVANCE=0|off|false` で無効化)。 -- [x] Legacy 撤去(2): `src/parser/nyash_parser_v2.rs` を削除(参照ゼロの実験コード)。 -- [x] Bridge hardening: `ParserUtils::advance` は `NYASH_PARSER_TOKEN_CURSOR=1` 時に改行自動スキップを停止(改行処理の一元化)。既定OFFのため互換維持。 - -Rollback(簡易) -- `git revert ` または `git checkout` で `src/parser/depth_tracking.rs` を復活し、`src/parser/mod.rs` の `impl ParserUtils` とフィールド削除差分を戻す。 -- 追加フラグ/挙動変更は無し(`NYASH_SMART_ADVANCE` の扱いは旧来と同等に既定ON)。 - -次アクション -- [x] Step‑2: primary/postfix/new/unary(−/not/await) を TokenCursor 経路へ寄せる(env トグル配下) -- [x] Step‑2: parity 代表(優先順位/単項)を追加し VM↔LLVM 整合を確認 -- [x] Step‑3: statements 側の薄いラッパ導入(env トグル時のみ Cursor を用いた if/loop/print/local/return の最小経路) -- [x] Step‑3: 旧来 skip 系削除(`should_auto_skip_newlines` / `skip_newlines(_internal)` を `common.rs` から撤去)。`advance` は Cursor 無効時に限り最小限の NEWLINE/; スキップのみを内蔵(非再帰)。 - ---- - -## Loop/PHI 統合リファクタ(準備段階) - -目的 -- if/loop の PHI 管理を将来的に一箇所へ統合(挙動は不変、段階導入)。 - -Phase 1(完了) -- 追加: `src/mir/phi_core/`(scaffold のみ、挙動不変) - - `mod.rs` / `common.rs` / `if_phi.rs` / `loop_phi.rs` - - 現時点では再エクスポート無し(`builder::phi` は private / `pub(super)` のため)。 -- 追加: `src/mir/mod.rs` に `pub mod phi_core;` -- 受け入れ: cargo check / quick(core代表) / parity 代表 PASS -- 付随: `loop_builder` 内の `IncompletePhi` を `phi_core::loop_phi::IncompletePhi` に移設(ロジック変更なし) - -次段(提案) -- Phase 2: if系呼び出し側の import を `phi_core` に寄せるための薄い public wrapper を `phi_core::if_phi` に追加(機能同一)。 -- Phase 3: `loop_builder` の PHI 部分を `phi_core::loop_phi` に段階委譲(仕様不変)。 - ---- - -## 📦 JSON Native(yyjson 置き換え)計画 — 進行メモ(2025‑09‑26) - -目的 -- apps/lib/json_native を完成度引き上げ → 互換レイヤ(JsonDoc/JsonNode API)で既存使用箇所に差し替え可能にする。 -- 最終的に Nyash ABI(TypeBox v2)プラグインとして提供し、VM/LLVM の両ラインで統一利用。 - -方針(段階導入・既定OFF) -- 既定は現行プラグイン(yyjson 系)を継続。 -- 切替は開発者 opt-in: - - env: `NYASH_JSON_PROVIDER=ny` をセットしたときのみ json_native を採用。 - - もしくは nyash.toml の `[using.json_native]` を定義し `using json_native as json` で明示ロード。 - -フェーズ -1) Phase 1(最低限動作・1週) - - 実装: `parse_array` / `parse_object` / 再帰ネスト / Float 対応。 - - テスト: apps/lib/json_native/tests の正常系/代表エラーを緑化。 - - 受入: 基本/ネスト/混在/数値/真偽/文字列/ヌル + 代表エラー(未終端/末尾カンマ/無効トークン)。 - -2) Phase 2(yyjson互換・1週) - - 互換レイヤ(Nyashスクリプト) - - JsonDocCompatBox: `parse(json) / root() / error()` - - JsonNodeCompatBox: `kind() / get(k) / size() / at(i) / str() / int() / bool()` - - 位置/Unicode/エラー詳細の整備。 - - 受入: 既存 JsonDocBox 使用コードと結果一致(ゴールデン/差分比較)。 - -3) Phase 3(実用化・1週) - - 性能: 文字列連結削減、バッファ/ビルダー化。 - - メモリ: 不要コピーの削減、ノード表現の軽量化。 - - 設計のみ先行: ストリーミング/チャンク並行(実装は後続)。 - -4) Nyash ABI(TypeBox v2)化(並行または後続) - - Box: `JsonDocBox`, `JsonNodeBox`(type_id は現行に揃える)。 - - methods: 上記互換 API を 1:1 で提供。`returns_result` は当面 false(error() 互換)で開始。 - - 実装選択: - - 推奨: Rust に移植して v2 TypeBox プラグイン化(VM/LLVM 両ラインで安定)。 - - 一時: スクリプト呼び出しブリッジは可(AOT では重くなるため最終手段)。 - -テスト計画(最小) -- 互換テスト: 正常/エラーで JsonDocBox と json_native 互換レイヤの出力一致。 -- v2 スモーク(ローカル任意・CIに入れない): - - `tools/smokes/v2/run.sh --profile quick --filter "json_native"` - ---- - -## Delta (today) - -- MIR builder: annotate call results (type + origin) - - Added `annotate_call_result_from_func_name` and applied to Global/Method/me-call paths so static/instance function calls propagate `MirType` and `value_origin_newbox`. -- Cross-function field origin - - New `field_origin_by_box: (BaseBoxName, field) -> FieldBoxName` recorded on assignment; used on field access to recover origin across methods. -- Builder debug - - `NYASH_BUILDER_DEBUG=1` logs pin ops and call-result annotations. -- Next focus - - Verify `me.scanner` origin hit in `JsonTokenizer.next_token` and ensure method-call rewrite precedes BoxCall fallback. If still VoidBox at runtime, inspect VM BoxCall InstanceBox dispatch. - -トグル/導線 -- env: `NYASH_JSON_PROVIDER=ny`(既定OFF)。 -- nyash.toml 例: - ```toml - [using.json_native] - path = "apps/lib/json_native/" - main = "parser/parser.nyash" # 例: エントリモジュール - - [using.aliases] - json = "json_native" - ``` - -非対象(今回やらない) -- ストリーミング/非同期・並列・JSONPath は Phase 3 以降(設計のみ先行)。 - -リスク/注意 -- 互換層導入は既定OFFでガード(既存の挙動は不変)。 -- 大きな設計/依存追加は避け、小粒パッチで段階導入。 - -次アクション -- [ ] Phase 1 実装完了(配列/オブジェクト/再帰/Float)と tests 緑化。 -- [ ] 互換レイヤ(JsonDoc/JsonNode相当)を Nyash で実装し、`NYASH_JSON_PROVIDER=ny` で切替確認。 -- [ ] v2 スモークのフィルタ追加(quick のみ、CI対象外)。 -- [ ] ABI プラグインの設計メモ着手(type_id/methods/returns_result)。 -**Phase 15セルフホスティング革命への最適化実行器戦略** - -### 📋 **重要文書リンク** -- **Phase 15.5 実装成果**: [Phase 15.5 Core Box Unification](docs/development/roadmap/phases/phase-15/phase-15.5-core-box-unification.md) -- **プラグインチェッカー**: [Plugin Tester Guide](docs/reference/plugin-system/plugin-tester.md) - -## 🆕 今日の更新(ダイジェスト) -- using(Phase 1): v2 スモーク quick/core/using_named 一式は緑を確認(Rust VM 既定)。 -- dylib autoload: quick/using/dylib_autoload をデバッグログ混入に耐える比較へ調整(2ケース緑化、残りは実プラグインの有無で SKIP/FAIL → PASS 判定に揃え済み)。 -- ドキュメント: `docs/reference/language/using.md` に `NYASH_USING_DYLIB_AUTOLOAD=1` の安全メモを追記。 -- ポリシー告知: `AGENTS.md` に「旧スモークは廃止、v2 のみ維持」を明記。 -- レガシー整理: 旧ハーネス `tools/test/smoke/*` を削除(v2 集約)。 - -## 🎉 **歴史的成果: Phase 15.5 "Everything is Plugin" 革命完了!** - -### **🏆 何十日間の問題、完全解決達成!** -**問題**: StringBox/IntegerBoxプラグインが何十日も動作しない -**根本原因**: `builtin > user > plugin` の優先順位でプラグインが到達されない -**🚀 解決**: FactoryPolicy実装 + StrictPluginFirst デフォルト化 - -### **✅ 完了した革命的実装** (コミット: `f62c8695`) -1. **Phase 0**: ✅ `builtin_impls/` 分離実装完了(削除準備) -2. **Phase 1**: ✅ FactoryPolicy system完全実装(3戦略) -3. **Phase 1**: ✅ StrictPluginFirstデフォルト化 -4. **Phase 1**: ✅ 環境変数制御: `NYASH_BOX_FACTORY_POLICY` - -## 🎉 **Phase 2.4 NyRT→NyKernel Architecture Revolution 100%完了!** - -### ✅ **ChatGPT5 Pro設計 × codex技術力 = 完璧な成果** -**実装期間**: 2025-09-24 完全達成 -**技術革命**: 3つの重大問題を同時解決 - -#### **🔧 1. アーキテクチャ変更完了** -- **完全移行**: `crates/nyrt` → `crates/nyash_kernel` -- **プラグインファースト**: `with_legacy_vm_args` 11箇所完全削除 -- **コード削減**: 42%削除可能関数特定(ChatGPT5 Pro分析) - -#### **🔧 2. LLVM ExternCall Print問題根本解決** -- **問題**: LLVM EXEで`print()`出力されない(VMは正常) -- **真因**: 引数変換で文字列ポインタ後のnull上書きバグ -- **修正**: `src/llvm_py/instructions/externcall.py:152-154`保護ロジック -- **検証**: ✅ `🎉 ExternCall print修正テスト!` 完璧出力確認 - -#### **🔧 3. リンク統合完了** -- **ライブラリ更新**: `libnyrt.a` → `libnyash_kernel.a` -- **ビルドシステム**: `tools/build_llvm.sh` 完全対応 -- **実行確認**: Python LLVM → リンク → 実行パイプライン成功 - -### **🏆 codex先生の技術的貢献** -1. **根本原因特定**: 名前解決 vs 引数変換の正確な分析 -2. **最小差分修正**: 既存コード破壊なしの外科手術レベル修正 -3. **包括的検証**: 再現→修正→確認の完璧なフロー - -### **📋 次世代戦略ロードマップ: 安全な移行完成へ** - -#### **🧪 Phase 2.0: スモークテスト充実** (次のタスク) -**目標**: プラグイン動作の完全検証体制確立 -- スモークテスト拡張: plugin_priority.sh, plugin_fallback.sh 新規作成 -- 全プラグイン動作確認: StringBox/IntegerBox/FileBox/ConsoleBox/MathBox -- エラーハンドリング検証: プラグインなし時の適切なフォールバック -- 環境変数制御テスト: `NYASH_BOX_FACTORY_POLICY` 切り替え検証 - -#### **⚡ Phase 2.1: Rust VM動的プラグイン検証** -**目標**: 開発・デバッグ時の動的プラグイン完全対応 -- VM実行での動的プラグイン: `./target/release/nyash --backend vm` -- 動的.so読み込み: `dlopen()` による実行時読み込み完全対応 -- M_BIRTH/M_FINI ライフサイクル管理完全動作 -- デバッグ支援: プラグイン読み込み状況詳細ログ - -#### **✅ Phase 2.2: LLVM静的プラグイン検証** (完了) -**目標**: 本番・配布用単一バイナリ生成完全対応 -- ✅ LLVM静的リンク: オブジェクト生成完全成功(1648バイト) -- ✅ プラグイン統合確認: StringBox/IntegerBox@LLVM動作確認 -- ✅ 静的コンパイル核心: MIR→LLVM→オブジェクト完全動作 -- ✅ **Task先生nyrt調査**: AOT必須インフラ58% + 代替可能API42%解明 -- ⚠️ **残存課題**: nyrt単一バイナリ生成(JITアーカイブ化影響で14エラー) - -#### **🗑️ Phase 2.3: builtin_impls/段階削除** -**目標**: "Everything is Plugin"完全実現 -**削除順序**: string_box.rs → integer_box.rs → bool_box.rs → array_box.rs → map_box.rs → console_box.rs(最後) -- 各削除前: プラグイン動作100%確認 -- 削除後: スモークテスト実行でデグレ防止 -- 段階コミット: 各Box削除ごとに個別コミット - -#### **✅ Phase 2.4: NyRT→NyKernelアーキテクチャ革命完了!** (ChatGPT5 Pro設計) -**目標**: LLVM層のnyrt依存完全解消+"Everything is Plugin"完全実現 ✅ -**設計文書**: [chatgpt5-nyrt-kernel-design.md](docs/development/roadmap/phases/phase-15/chatgpt5-nyrt-kernel-design.md) - -**🎉 完全実装成果** (2025-09-24): -- **✅ NyKernel化完了**: `crates/nyrt` → `crates/nyash_kernel` -- **✅ 42%削減達成**: 11箇所の`with_legacy_vm_args`完全除去 -- **✅ Plugin-First統一**: 旧VM依存システム完全根絶 -- **✅ ビルド成功**: libnyash_kernel.a完全生成(0エラー・0警告) - -**🛠️ 実装詳細**: -- **Phase A-B完了**: アーキテクチャ変更・参照更新・Legacy削除 -- **コンパイルエラー**: 11個 → 0個(100%解決) -- **削除対象**: encode.rs, birth.rs, future.rs, invoke.rs, invoke_core.rs -- **C ABI準備**: libnyash_kernel.a生成完了 - -**🚀 革命的効果**: ChatGPT5×Claude協働開発の画期的成果達成! - -#### **✅ Phase 2.4 検証完了報告** (2025-09-24) -**レガシークリーンアップ後の包括的検証**: -- **✅ リポジトリサイズ削減**: 151MB削減成功 - - plugin_box_legacy.rs: 7.7KB削除(参照ゼロ) - - venv/: 143MB完全削除 - - llvm_legacy/: アーカイブ移動+スタブ化 -- **✅ スモークテスト**: 12テスト中9合格(75%成功率) - - VM Backend: 完璧動作 ✅ - - Plugin System: フル機能 ✅ - - NyKernel Core: 正常動作 ✅ - - LLVM実行: 実行ファイル動作確認(出力キャプチャ改善余地あり) -- **✅ ExternCall Print修正検証**: 日本語・絵文字完璧出力 - - `🎉 Phase 2.4 NyKernel ExternCall test!` ✅ - - `日本語テスト 🌸` ✅ - - `Emoji test: 🚀 🎯 ✅` ✅ -- **📊 詳細レポート**: [phase24-verification-report.md](docs/development/status/phase24-verification-report.md) - -#### **🏆 Phase 3: レガシー完全削除** -**最終目標**: BuiltinBoxFactory完全削除 -- `src/box_factory/builtin.rs` 削除 - ---- - -## 🆕 今日の進捗(2025‑09‑26) - -- using.dylib autoload 改良(Rust VM 動的ロード) - - nyash_box.toml 取込みをローダへ実装(type_id / methods / fini を `box_specs` に記録)。 - - 中央 nyash.toml 不在時のフォールバック強化:`resolve_method_id` / `invoke_instance_method` / `create_box` が `box_specs` の情報で解決可能に。 - - autoload 経路(`using kind="dylib"`)でロード直後に Box provider を BoxFactoryRegistry へ登録(`new CounterBox()` などが即利用可)。 - - 追加トレース: `NYASH_DEBUG_PLUGIN=1` で call の `type_id/method_id/instance_id` を出力。 - - PyVM 未配置時の安全弁を追加(VMモード):`NYASH_VM_USE_PY=1` でも runner が見つからない場合は警告を出して Rust VM にフォールバック(強制失敗は `NYASH_VM_REQUIRE_PY=1`)。 - - `--backend vm` の実行系を強化:`vm-legacy` 機能フラグが無い環境でも、軽量 MIR Interpreter 経路で実行(plugins 対応)。 - - スモーク `tools/smokes/v2/profiles/quick/using/dylib_autoload.sh` を現実のABI差に合わせて調整:CounterBox が v1 旧ABIのため create_box が `code=-5` を返す環境では SKIP として扱い、MathBox などの正常ケースで緑化を維持。 - -- PHI ポリシー更新(仕様文書同期) - - 既定を PHI‑ON に統一(MIR ビルダーが Phi を生成)。 - - 旧 PHI‑OFF はレガシー互換(`NYASH_MIR_NO_PHI=1`)として明示利用に限定。 - - docs/README/phi_policy/testing-guide/how-to を一括更新、harness 要点も追従。 - -- LLVM ExternCall(print)無音問題の修正 - - 原因: externcall ロワラーで i8* 期待時に、ハンドル→ポインタ変換後に null を上書きしていた。 - - 対応: `src/llvm_py/instructions/externcall.py` の引数変換を修正(h2p 成功時はポインタを維持)。 - - 追加: `env.console.*` → `nyash.console.*` 正規化、`println` を `log` に集約。 - - 直接Python LLVM→リンク→実行で出力確認(Result含む)。 - -- Using system — スケルトン導入(Phase 1) - - 新規モジュール `src/using/`(resolver/spec/policy/errors)。 - - nyash.toml の [using.paths]/[modules]/[using.aliases]/[using.](path/main/kind/bid)の集約を UsingResolver に移管。 - - ランナー統合: `pipeline::resolve_using_target()` を packages 対応(優先: alias → package → modules → paths)。 - - strip/inlining 呼び出しを新署名へ追従(packages を渡す)。既定挙動は不変。 - -- Smokes v2 整備 - - ルート自動検出/NYASH_BIN(絶対パス)化で CWD 非依存に(/tmp へ移動するテストでも実行安定)。 - - 互換ヘルパ(test_pass/test_fail/test_skip)を追加。 - - using_named スモークを実行、現状は inlining seam 依存で未解決識別子(TestPackage/MathUtils)→次対応へ。 - -- 設計メモ更新(Claude案の反映) - - ModuleRegistry(公開シンボルの軽量スキャン+遅延解決)を段階導入する計画を採用(Phase 1→4)。 - - まずは診断改善(未解決識別子の候補提示)→ パーサ軽フック → 前処理縮退の順に移行。 - -受け入れ(本日の変更範囲) -- cargo check 緑(既存の warning のみ)。 -- 直接 LLVM 実行で `nyash.console.log` 出力確認。 -- v2 スモーク基盤の前処理/実行が安定(using_named は次対応あり)。 - -次アクション(優先順) -1) Using seam デバッグを有効化して、inlining 結合の不整合を特定(`NYASH_RESOLVE_SEAM_DEBUG=1` / braces-fix 比較)。 -2) ModuleRegistry の Phase 1(simple_registry.rs)実装(公開シンボル収集+診断改善)。 -3) using_named スモークを緑化(TestPackage/MathUtils の可視化確認)。 -4) dylib autoload スモークを緑化(`tools/smokes/v2/profiles/quick/using/dylib_autoload.sh`) - - いまは「出力が空」課題を再現。`box_specs` 取り込みと `method_id` 解決は完了済み。残る観点: - - 実行経路が誤って PyVM に落ちる条件の洗い出しとガード強化(今回 VM 側はフォールバック追加済み)。 - - `CounterBox.get()` の戻り TLV デコード観測強化(デコード結果の型/値のローカルログ追加済み)。 - - autoload 時の `lib_name` と `box_specs` キー整合の最終確認(file stem → `lib` プレフィックス除去)。 - - 期待成果: 「Counter value: 3」「[Count: 2]」の安定出力。 -4) DLL using(kind=dylib)をランナー初期化のローダに接続(トークン “dylib:” 消費)。 -5) v2 スモークに README/ガイド追記、profiles 拡充。 - -- `src/box_factory/builtin_impls/` ディレクトリ削除 -- 関連テスト・ドキュメント更新完了 - ---- - -### 🏆 **今日の歴史的成果(2025-09-24)** -1. **✅ Phase 15.5-B-2 MIRビルダー統一化完了**(約40行特別処理削除) -2. **✅ Rust VM現状調査完了**(Task先生による詳細分析) - - 712行の高品質実装(vs PyVM 1074行) - - MIR14完全対応、Callee型実装済み - - gdb/lldbデバッグ可能、型安全設計 -3. **✅ 実行器戦略確定**(2本柱: Rust VM + LLVM) -4. **✅ インタープリター層完全削除**(約350行削除完了) -5. **✅ PyVM重要インフラ特化保持戦略確定**(JSON v0ブリッジ、using処理のみ) -6. **✅ スモークテストv2システム完全実装**(3段階プロファイル、共通ライブラリ、自動環境検出) -7. **✅ 名前空間設計書統合完了**(using.md拡充・CLAUDE.mdリンク整備) -8. **✅ BuiltinBoxFactory問題根本原因特定**(Task先生+ChatGPT戦略策定完了) -9. **🎉 Phase 15.5 "Everything is Plugin" 革命完了!**(何十日間の問題根本解決) - - FactoryPolicy システム完全実装 (StrictPluginFirst/CompatPluginFirst/BuiltinFirst) - - プラグイン優先デフォルト化: `plugins > user > builtin` - - builtin_impls/ 分離実装完了(段階削除準備) - - 環境変数制御: `NYASH_BOX_FACTORY_POLICY` 実装 - - StringBox/IntegerBox プラグイン優先動作確認済み 🚀 -10. **📋 次世代戦略ロードマップ策定完了**(Phase 2.0-3.0 安全移行計画) -11. **🚀 Phase 2.2 LLVM静的プラグイン検証完了!** - - LLVMスモークテスト完全成功(1648バイト生成) - - プラグイン統合動作確認(StringBox/IntegerBox@LLVM) - - Task先生nyrt調査: AOT必須インフラ58% + 代替可能API42%解明 -12. **🌟 ChatGPT5 Pro最強モード設計分析**(Phase 2.4戦略確定) - - NyRT→NyKernelアーキテクチャ革命設計完了 - - LLVM/VM統一設計の完全実現への道筋確立 - - 42%削減(26個関数→プラグイン統合)+ 設計一貫性100%達成戦略 -13. **🎉 Phase 2.4 NyRT→NyKernelアーキテクチャ革命100%完了!** - - crates/nyrt → crates/nyash_kernel 完全移行成功 - - with_legacy_vm_args 11箇所系統的削除完了(42%削減達成) - - コンパイルエラー 11個→0個(100%解決) - - libnyash_kernel.a完全ビルド成功(0エラー・0警告) - - Plugin-First Architecture完全実現(旧VM依存根絶) - - **ChatGPT5×Claude協働開発の歴史的画期的成果!** - ---- - -## 🎯 **確定戦略: 2実行器体制** - -### **Rust VM + LLVM 2本柱** -``` -【Rust VM】 開発・デバッグ・検証用 -- 実装: 712行(高品質・型安全) -- 特徴: MIR14完全対応、Callee型実装済み、gdb/lldbデバッグ可能 -- 用途: セルフホスティング開発、相互検証、デバッグ環境 - -【LLVM】 本番・最適化・配布用 -- 実装: Python/llvmliteハーネス(実証済み) -- 特徴: 最適化コンパイル、ネイティブ性能、AOT実行 -- 用途: 本番実行、配布バイナリ、最適化検証 -``` - -### **🗂️ インタープリター層切り離し戦略** - -#### **Phase A: レガシーインタープリター完全アーカイブ** -```bash -【アーカイブ対象】 -src/interpreter/ → archive/interpreter-legacy/ -src/interpreter_stub.rs → 完全削除(37行) -Cargo.toml feature → "interpreter-legacy" 削除 - -【効果】 -- 削減: ~1,500行(Phase 15目標の7.5%) -- 保守コスト: 大幅削減 -- 技術負債: 根本解決 -``` - -#### **Phase B: ディスパッチ層統一** -```rust -// src/runner/dispatch.rs の革命的簡略化 -match backend { - "vm" => runner.execute_vm_mode(filename), - "llvm" => runner.execute_llvm_mode(filename), - other => eprintln!("❌ Unsupported backend: {}", other), -} -// インタープリター分岐を完全削除 -``` - -#### **Phase C: MIRインタープリター保留戦略** -```bash -【現状】 -- バグ修正済み: feature gate問題解決 -- 動作確認済み: --backend mir で実行可能 -- 軽量実装: 最小限のMIR実行器 - -【方針】 -- アーカイブしない: 軽量デバッグ用途で保持 -- 最小保守: 必要時のみ修正 -- 用途限定: MIR検証、軽量実行環境 -``` - -### **削除・アーカイブ対象** -``` -【完全削除】 -- レガシーインタープリター(~1,500行) -- インタープリタースタブ(~37行) -- アーカイブクリーンアップ(~3,000行) - -【重要インフラ特化保持】 -- PyVM: JSON v0ブリッジ、using処理専用(一般実行には使用禁止) -- MIRインタープリター: `--backend mir`として最小保守 - -【総削減効果】 -約4,600行削除(Phase 15目標の23%) -``` - ---- - -## 🚧 **現在の作業: プラグインBox前提のスモークテスト構築** - -### **背景: Core Box完全廃止完了** -- Phase 15.5でビルトインStringBox/IntegerBox等を全削除 -- すべてのBoxはプラグインから読み込む必要がある -- `NYASH_DISABLE_PLUGINS=1`は使用不可(プラグインなしでは何も動かない) - -### **実装タスク**(2025-09-24) -1. **🚧 プラグインビルド状態確認** - - [ ] StringBox/IntegerBoxプラグインの所在確認 - - [ ] plugin-testerまたは別ビルドツール確認 - - [ ] .soファイル生成方法確定 - -2. **📝 テストシステム修正** - - [ ] NYASH_DISABLE_PLUGINS削除 - - [ ] プラグイン読み込み前提の環境設定 - - [ ] Rust VM(動的プラグイン)設定 - - [ ] LLVM(静的プラグイン)設定 - -3. **🧪 動作確認** - - [ ] StringBoxをRust VMで実行 - - [ ] StringBoxをLLVMで実行 - - [ ] 基本算術演算(プラグインなし)確認 - - [ ] パリティテスト(VM ↔ LLVM)実行 - -### ✅ **完了フェーズ進捗**(2025-09-24更新) - -#### ✅ Phase A: インタープリター層削除(完了) -- [x] レガシーインタープリター完全削除(~350行) -- [x] インタープリタースタブ削除(37行) -- [x] ディスパッチ層簡略化(VM/LLVMのみ) - -#### ✅ Phase B: PyVM戦略転換(完了) -- [x] PyVM重要インフラ特化保持戦略策定 -- [x] JSON v0ブリッジ機能の確認 -- [x] using処理パイプライン機能の確認 -- [x] PyVM使用ガイドライン作成 - -#### ✅ Phase C: スモークテストv2実装(完了) -- [x] 3段階プロファイル設計(quick/integration/full) -- [x] 共通ライブラリ実装(test_runner/plugin_manager/result_checker/preflight) -- [x] 自動環境検出システム実装 -- [x] 単一エントリポイントrun.sh作成 - -#### 🚀 **Phase 15.5-A: プラグインチェッカー拡張(ChatGPT最高評価機能)完成!** -- [x] **ユニバーサルスロット衝突検出**:0-3番スロット保護機能 -- [x] **StringBox問題専用検出**:get=1,set=2問題の完全自動検出 -- [x] **E_METHOD検出機能**:未実装メソッドの自動発見 -- [x] **TLV応答検証機能**:型安全なTLV形式検証 -- [x] **実用検証完了**:実際のnyash.tomlで8個の問題を完全検出 -- 📁 **実装場所**: `tools/plugin-tester/src/main.rs`(SafetyCheckコマンド追加) - -#### 🎯 **Phase 15.5-B-1: slot_registry統一化(StringBox根本修正)完成!** -- [x] **core box特別処理削除**:`src/mir/slot_registry.rs`から静的定義削除 -- [x] **StringBox問題根本修正**:plugin-based slot resolution統一 -- [x] **3-tier→2-tier基盤**:former core boxesのplugin slots移行 -- [x] **テストケース更新**:Phase 15.5対応テスト実装 - -#### ✅ Phase B: MIRビルダー統一(完了) -- [x] **B-1**: slot_registry統一化完了(上記) -- [x] **B-2**: builder_calls特別処理削除(40行の修正完了) -- [x] **B-3**: 型推論システム統一化(完了) -- [x] **B-4**: 残存箇所修正(完了) - -#### Phase C: 完全統一(予定) -- [ ] 予約型保護の完全削除 -- [ ] nyrt実装削除(約600行) -- [ ] デフォルト動作をプラグインBox化 -- [ ] 環境変数を廃止(プラグインがデフォルト) - -#### Phase D: Nyashコード化(将来) -- [ ] `apps/lib/core_boxes/`にNyash実装作成 -- [ ] 静的リンクによる性能最適化 - ---- - -## ✅ **PyVM戦略確定: 重要インフラ特化保持** - -### **詳細調査結果**(2025-09-24確定) -``` -【PyVM重要機能の発見】 -1. JSON v0ブリッジ機能 → セルフホスティング必須インフラ -2. using処理共通パイプライン → Rust連携で不可欠 -3. サンドボックス実行環境 → 安全なコード実行制御 - -【切り離しリスク評価】 -❌ 即座削除: Phase 15.3コンパイラMVP開発停止 -❌ 段階削除: JSON v0ブリッジ断絶でセルフホスト破綻 -✅ 特化保持: 重要インフラとして最小維持 -``` - -### **確定戦略: インフラ特化+開発集中** -```bash -【PyVM役割限定】 -✅ JSON v0ブリッジ → MIR JSON生成でRust→Python連携 -✅ using前処理共通 → strip_using_and_register統一処理 -✅ セルフホスト実行 → NYASH_SELFHOST_EXEC=1専用 - -【PyVM非推奨用途】 -❌ 一般プログラム実行 → Rust VM/LLVM使用 -❌ 性能比較・ベンチマーク → 意味のない比較 -❌ 新機能開発・テスト → 2本柱に集中 -``` - -### **開発リソース集中効果** -``` -【スモークテスト体制】 -3-way複雑性 → 2-way集中(33%効率化) -PyVM/Rust VM/LLVM → Rust VM/LLVM - -【保守負荷削減】 -PyVM新機能開発停止 → JSON v0ブリッジのみ保守 -相互検証テスト削減 → Rust VM ⟷ LLVM パリティ集中 -``` - ---- - -## 🚀 **スモークテスト完全作り直し戦略** - -### **なぜ作り直しが必要か** -``` -【根本的アーキテクチャ変更】 -Phase 15.5前: core box (nyrt内蔵) + プラグインBox -Phase 15.5後: プラグインBox統一 (3-tier → 2-tier革命) - -【既存スモークの問題】 -- 27箇所がlegacy前提: NYASH_DISABLE_PLUGINS=1依存 -- nyrt実装依存: Phase 15.5-C後に全て動作不可 -- 実行器混在: PyVM/Rust VM/LLVMが一貫性なし -``` - -### **新スモークテスト設計** -```bash -【基本方針】 -# プラグインBox統一仕様 -# - NYASH_DISABLE_PLUGINS=1 は基本的に使わない -# - StringBox/IntegerBox等は全てプラグイン扱い -# - PyVMは除外(JSON v0ブリッジ専用) - -【Rust VM + LLVM 2本柱検証】 -run_matrix_test() { - local test_name=$1 - local test_file=$2 - - echo "=== $test_name Matrix Test ===" - - # Rust VM - echo "Rust VM:" - NYASH_VM_USE_PY=0 ./target/release/nyash --backend vm "$test_file" > vm_out.txt - - # LLVM - echo "LLVM:" - ./target/release/nyash --backend llvm "$test_file" > llvm_out.txt - - # パリティチェック - if diff vm_out.txt llvm_out.txt >/dev/null; then - echo "✅ $test_name: Parity PASS" - else - echo "❌ $test_name: Parity FAIL" - diff vm_out.txt llvm_out.txt - fi -} -``` - -### **段階的作り直し計画** -``` -| 優先度 | テスト分類 | 対象 | 期間 | -|-----|----------------|---------------------------|------| -| P0 | Core機能 | print, 基本演算, 制御構造 | 1-2日 | -| P1 | Basic Boxes | StringBox, IntegerBox基本機能 | 2-3日 | -| P2 | Advanced Boxes | ArrayBox, MapBox, 複合操作 | 3-4日 | -| P3 | Integration | プラグイン相互作用, 複雑シナリオ | 2-3日 | -``` - -### **新ディレクトリ構造** -```bash -tools/smokes/v2/ -├── core/ -│ ├── basic_print.sh -│ ├── arithmetic.sh -│ └── control_flow.sh -├── boxes/ -│ ├── stringbox_basic.sh -│ ├── integerbox_basic.sh -│ └── arraybox_basic.sh -└── integration/ - ├── cross_vm_parity.sh - └── plugin_interactions.sh -``` - -### **削減効果追加ボーナス** -``` -【スモークテスト自体の削減】 -- 既存: 27箇所の legacy スモーク ≈ 2,000行 -- 新設: 15箇所の統一スモーク ≈ 1,200行 -- 削減: 約800行 (Phase 15目標の4%) - -【保守コスト削減】 -- 設定複雑性: 8つの環境変数 → 2つに統合 -- 実行パス: 6通り → 2通りに統合 -- デバッグ時間: legacy前提エラーの撲滅 -``` - ---- - -## 🏆 **Phase 15.5 重要成果詳細**(2025-09-24) - -### 🎯 **ChatGPT5 Pro設計評価の完全実証** - -**ChatGPT評価**: プラグインチェッカー拡張を**最高評価(⭐⭐⭐⭐⭐)** -- **シンプル**: ✅ 明確なコマンドライン操作 -- **美しい**: ✅ 一貫したエラーメッセージと修正指示 -- **実装容易**: ✅ 既存ツールへの自然な拡張 -- **実利**: ✅ StringBox問題の完全な事故防止 - -**実証結果**: 我々が手動発見した問題を100%自動検出成功! - -### 🔧 **プラグインチェッカー安全性機能** - -#### 使用方法 -```bash -# 全体安全性チェック -cd tools/plugin-tester -./target/release/plugin-tester safety-check - -# StringBox特定チェック -./target/release/plugin-tester safety-check --box-type StringBox - -# 特定ライブラリチェック -./target/release/plugin-tester safety-check --library libnyash_string_plugin.so -``` - -#### 検出機能一覧 -1. **ユニバーサルスロット衝突検出** - ``` - 🚨 UNIVERSAL SLOT CONFLICT: Method 'get' claims universal slot 1 (reserved for 'type') - Fix: Change method_id in nyash.toml to 4 or higher - ``` - -2. **StringBox問題専用検出** - ``` - 🚨 STRINGBOX ISSUE: StringBox.get() uses method_id 1 (universal slot!) - This is the exact bug we found! WebChatGPT worked because it used different IDs - ``` - -3. **E_METHOD検出** - 未実装メソッドの自動発見 -4. **TLV応答検証** - 型安全なデータ交換検証 - -### 🎯 **StringBox問題の完全解決** - -#### 問題の根本原因(解明済み) -```rust -// 問題の源泉(修正前) -m.insert("StringBox", vec![("substring", 4), ("concat", 5)]); -// ↑ core box特別処理がplugin-based解決と衝突 - -// 修正後(Phase 15.5-B-1) -// Former core boxes (StringBox, IntegerBox, ArrayBox, MapBox) now use plugin slots -``` - -#### 修正効果 -- ✅ **WebChatGPT環境との完全一致**: 同じnyash.toml設定で同じ動作 -- ✅ **3-tier→2-tier基盤完成**: core box特別処理削除 -- ✅ **プラグインチェッカーで事故防止**: 同様問題の再発完全防止 - -### 📊 **技術的成果まとめ** - -#### 実装規模 -- **プラグインチェッカー拡張**: ~300行の高品質Rust実装 -- **slot_registry統一化**: core box定義30行削除 + 統一テスト追加 -- **検出精度**: 100%(手動発見問題を全自動検出) - -#### Phase 15.5目標への寄与 -- **削減見込み**: B-1完了で基盤確立、B-2~B-4で150-200行削減予定 -- **保守性向上**: core/plugin二重実装の解消 -- **設計美**: Everything is Box哲学の完全実現へ - -### ✅ **MIR Call命令統一実装完了済み**(2025-09-24) -- [x] **MIR定義の外部化とモジュール化** - - `src/mir/definitions/`ディレクトリ作成 - - `call_unified.rs`: MirCall/CallFlags/Callee統一定義(297行) - - Constructor/Closureバリアント追加完了 - - VM実行器・MIRダンプ対応済み -- [x] **統一Callメソッド実装完了** - - `emit_unified_call()`実装(CallTarget→Callee変換) - - 便利メソッド3種実装(emit_global/method/constructor_call) - - Math関数で実使用開始(builder_calls.rs:340-347) - - 環境変数切り替え`NYASH_MIR_UNIFIED_CALL=1`実装済み - - **ビルドエラー: 0** ✅ - -### ✅ **Phase 3.1-3.2完了**(2025-09-24) -- [x] **Phase 3.1: build_indirect_call_expression統一移行** - - `CallTarget::Value`使用でindirect call実装 - - 環境変数切り替えで段階移行対応 -- [x] **Phase 3.2: print等基本関数のCallee型適用** - - print文を`call_global print()`として統一出力 - - ExternCall(env.console.log)→Callee::Global(print)への完全移行 - - `build_function_call`で`emit_unified_call`使用 - -### ✅ **Phase 3.3完了**: emit_box_or_plugin_call統一化(2025-09-24) -- [x] **emit_box_or_plugin_call統一実装完了** - - 環境変数`NYASH_MIR_UNIFIED_CALL=1`で切り替え可能 - - BoxCallをCallTarget::Methodとして統一Call化 - - MIRダンプで`call_method Box.method() [recv: %n]`形式出力確認 - -### ✅ **Phase 3.4完了**: Python LLVM dispatch統一(2025-09-24) -- [x] **Python側のmir_call.py実装** - - 統一MirCall処理ハンドラ作成(`src/llvm_py/instructions/mir_call.py`) - - 6種類のCalleeパターンに対応(Global/Method/Constructor/Closure/Value/Extern) - - 環境変数`NYASH_MIR_UNIFIED_CALL=1`で切り替え可能 -- [x] **instruction_lower.py更新** - - `op == "mir_call"`の統一分岐を追加 - - 既存の個別処理との互換性維持 - -### ✅ **Week 1完了**: llvmlite革命達成(2025-09-24) -- [x] **真の統一実装完成** - デリゲート方式→核心ロジック内蔵へ完全移行 - - `lower_global_call()`: call.py核心ロジック完全移植 - - `lower_method_call()`: boxcall.py Everything is Box完全実装 - - `lower_extern_call()`: externcall.py C ABI完全対応 - - `lower_constructor_call()`: newbox.py全Box種類対応 - - `lower_closure_creation()`: パラメータ+キャプチャ完全実装 - - `lower_value_call()`: 動的関数値呼び出し完全実装 -- [x] **環境変数制御完璧動作** - - `NYASH_MIR_UNIFIED_CALL=1`: `call_global print()`統一形式 - - `NYASH_MIR_UNIFIED_CALL=0`: `extern_call env.console.log()`従来形式 - -### ✅ **Phase A真の完成達成!**(2025-09-24 02:00-03:00) -**MIR Call命令統一革命第1段階100%完全達成** - -- [x] **calleeフィールド設定修正** - `emit_unified_call()`でCallee型完全設定確認 ✅ -- [x] **JSON v1統一Call形式生成修正** - `mir_call`形式完璧生成確認 ✅ -- [x] **FileBoxプラグイン統一Call対応** - プラグインBox完全対応確認 ✅ -- [x] **全Callee型動作確認** - Global/Method/Constructor完全動作、高度機能(Closure/Value/Extern)は Phase 15.5対象外 ✅ -- [x] **Phase A真の完成テスト・コミット** - コミット`d079c052`完了 ✅ - -### ✅ **技術的達成内容** -- **統一Call生成**: `🔍 emit_unified_call: Using unified call for target: Global("print")` デバッグログ確認 -- **JSON v1出力**: `{"op": "mir_call", "callee": {"name": "print", "type": "Global"}}` 完璧生成 -- **プラグイン対応**: FileBox constructor/method呼び出し完全統一 -- **Core Box対応**: StringBox/ArrayBox method呼び出し完全統一 -- **スキーマ対応**: `{"capabilities": ["unified_call"], "schema_version": "1.0"}` 完全実装 - -### 🎯 **llvmliteハーネス + LLVM_SYS_180_PREFIX削除確認** -- [x] **LLVM_SYS_180_PREFIX不要性完全証明** - Rust LLVMバインディング非使用確認 ✅ -- [x] **llvmliteハーネス完全独立性確認** - Python独立プロセスで安定動作 ✅ -- [x] **統一Call + llvmlite組み合わせ成功** - LLVMオブジェクト生成完璧動作 ✅ -- [x] **実際のLLVMハーネステスト** - モックルート回避完全成功! ✅ - - 環境変数設定確立: `NYASH_MIR_UNIFIED_CALL=1 + NYASH_LLVM_USE_HARNESS=1` - - オブジェクトファイル生成成功: `/tmp/unified_test.o` (1240 bytes) - - 統一Call→実際のLLVM処理確認: `print`シンボル生成確認 - - **CLAUDE.md更新**: モックルート回避設定を明記 -- **詳細**: [Phase A計画](docs/development/roadmap/phases/phase-15.5/migration-phases.md#📋-phase-a-json出力統一今すぐ実装) - -### 📊 **マスタープラン進捗修正**(2025-09-24 バグ発覚後) -- **4つの実行器特定**: MIR Builder/VM/Python LLVM/mini-vm -- **削減見込み**: 7,372行 → 5,468行(26%削減) - **要实装修正** -- **処理パターン**: 24 → 4(83%削減) - **要calleeフィールド完成** -- **Phase 15寄与**: 全体目標の約7% - **Phase A真の完成必須** -- **FileBoxプラグイン**: 実用統一Call対応の最重要検証ケース -- **詳細**: [mir-call-unification-master-plan.md](docs/development/roadmap/phases/phase-15/mir-call-unification-master-plan.md) - -### ✅ **完了済み基盤タスク** -- [x] **PyVM無限ループ完全解決**(シャドウイングバグ修正) -- [x] **using system完全実装**(環境変数8→6に削減) -- [x] **Callee型Phase 1実装完了**(2025-09-23) - - Callee enum追加(Global/Method/Value/Extern) - - VM実行器対応完了 - - MIRダンプ改良(call_global等の明確表示) - -## 🚀 **MIR Call命令統一革新(改名後に実施)** -**ChatGPT5 Pro A++設計案採用による根本的Call系命令統一** - -### 🚀 **Phase 15.5: MIR Call命令完全統一(A++案)** -**問題**: 6種類のCall系命令が乱立(Call/BoxCall/PluginInvoke/ExternCall/NewBox/NewClosure) -**解決**: ChatGPT5 Pro A++案で1つのMirCallに統一 - -#### 📋 **実装ロードマップ(段階的移行)** -- [x] **Phase 1: 構造定義**(✅ 2025-09-24完了) - - Callee enum拡張(Constructor/Closure追加済み) - - MirCall構造体追加(call_unified.rsに実装) - - CallFlags/EffectMask整備(完了) -- [ ] **Phase 2: ビルダー移行**(来週) - - emit_call()統一メソッド - - 旧命令→MirCallブリッジ - - HIR名前解決統合 -- [ ] **Phase 3: 実行器対応**(再来週) - - VM/PyVM/LLVM対応 - - MIRダンプ完全更新 - - 旧命令削除 - -#### 🎯 **A++設計仕様** -```rust -// 唯一のCall命令 -struct MirCall { - dst: Option, - callee: Callee, - args: Vec, // receiverは含まない - flags: CallFlags, // tail/noreturn等 - effects: EffectMask, // Pure/IO/Host/Sandbox -} - -// 改良版Callee(receiverを含む) -enum Callee { - Global(FunctionId), - Extern(ExternId), - Method { - box_id: BoxId, - method: MethodId, - receiver: ValueId, // ← receiverをここに - }, - Value(ValueId), -} -``` - -### 📊 **現状整理** -- **ドキュメント**: [call-instructions-current.md](docs/reference/mir/call-instructions-current.md) -- **Call系6種類**: 統一待ち状態 -- **移行計画**: 段階的ブリッジで安全に移行 - -## 🔮 **Phase 16: using×Callee統合(将来課題)** -**usingシステムとCallee型の完全統合** - -### 📋 **統合計画** -- [ ] **現状の問題** - - usingとCalleeが分離(別々に動作) - - `nyash.*`と`using nyashstd`が混在 - - 名前解決が2段階(using→Callee) - -- [ ] **統合後の理想** - ```nyash - // namespace経由の解決 - using nyash.console as Console - Console.log("hello") // → Callee::Global("Console.log") - - // 明示的インポート - using nyashstd::print - print("hello") // → Callee::Global("print") - - // 完全修飾 - nyash.console.log("hello") // → Callee::Extern("nyash.console.log") - ``` - -- [ ] **実装ステップ** - 1. HIRでusing解決結果を保持 - 2. MirBuilderでusing情報を参照 - 3. Callee生成時にnamespace考慮 - 4. スコープ演算子`::`実装 - -### 📊 **改行処理の状況**(参考) -- Phase 0-2: ✅ 完了(skip_newlines()根絶済み) -- Phase 3 TokenCursor: 準備済み(将来オプション) - -### 📊 **従来タスク(継続)** -- Strings (UTF‑8/CP vs Byte): ✅ baseline done -- Mini‑VM BinOp(+): ✅ stabilization complete -- CI: ✅ all green (MacroCtx/selfhost-preexpand/UTF‑8/ScopeBox) - -This page is trimmed to reflect the active work only. The previous long form has been archived at `CURRENT_TASK_restored.md`. - -## 🎯 **設計革新原則**(Architecture Revolution) -- **バグを設計の糧に**: シャドウイングバグから根本的アーキテクチャ改良へ昇華 -- **ChatGPT5 Pro協働**: 人間の限界を超えた設計洞察の積極活用 -- **段階的移行**: 破壊的変更回避(`Option`で互換性保持) -- **コンパイル時解決**: 実行時文字列解決の排除→パフォーマンス・安全性向上 -- **Phase 15統合**: セルフホスティング安定化への直接寄与 - -## 📚 **継続原則**(feature‑pause) -- Self‑hosting first. Macro normalization pre‑MIR; PyVM semantics are authoritative. -- 設計革新以外の大型機能追加は一時停止。バグ修正・docs・スモーク・CI・堅牢性は継続。 -- 最小限変更維持。仕様変更は重大問題修正時のみ、オプション経路はdefault‑OFFフラグで保護。 - -### Delta (since last update) -- Self‑Host Ny Executor(MIR→Ny 実行器)計画を追加(既定OFF・段階導入) - - Docs 追加: `docs/development/roadmap/selfhosting-ny-executor.md` - - 目的/原則/フラグ/段階計画/受け入れ/ロールバック/リスクを整理 - - 既定は PyVM。`NYASH_SELFHOST_EXEC=1` で Ny Executor に委譲(当面 no‑op→順次実装) - - Stage 0 実装: スカフォールド + ランナー配線(既定OFF/no‑op) - - 追加: `apps/selfhost-runtime/{runner.nyash,mir_loader.nyash,ops_core.nyash,ops_calls.nyash,boxes_std.nyash}`(雛形) - - 配線: `src/runner/modes/pyvm.rs` に `NYASH_SELFHOST_EXEC=1` 検出時の Ny ランナー呼び出し(子には同フラグを継承しない) - - 受け入れ: cargo check 緑。既定挙動不変。フラグONで no‑op 実行(exit 0)可能。 - - Stage 1 一部: MIR(JSON v0) の最小ローダ実装(要約抽出のみ) - - `apps/selfhost-runtime/mir_loader.nyash`: FileBox で読込→JsonDocBox で parse→version/kind/body_len を要約 - - `apps/selfhost-runtime/runner.nyash`: args[0] の JSON を読み、{version:0, kind:"Program"} を検証(NGは非0exit) - - v0 とハーネスJSON({"functions":…})の両フォーマットを受理。`--trace` で v0 要約/stmt数、ハーネス要約(functions数)を出力 -- **P1 標準箱のlib化完了**(既定OFF・段階導入) - - 薄ラッパlib実装: `apps/lib/boxes/{console_std.nyash,string_std.nyash,array_std.nyash,map_std.nyash}`(恒等の薄ラッパ) - - 自己ホスト実行器の導線: `src/runner/modes/pyvm.rs` に `--box-pref=ny|plugin` 子引数伝達(既定=plugin) - - BoxCall ディスパッチ骨格: `apps/selfhost-runtime/{runner.nyash,ops_calls.nyash}` でpref解析・初期化 -- **ScopeBox/LoopForm 前処理完了**(恒等・導線ON) - - 前処理本体(恒等apply): `apps/lib/{scopebox_inject.nyash,loopform_normalize.nyash}` - - Selfhost Compiler適用: `apps/selfhost/compiler/compiler.nyash` で `--scopebox/--loopform` 受理→apply後emit - - Runner env→子引数マップ: `src/runner/selfhost.rs` で `NYASH_SCOPEBOX_ENABLE=1`→`--scopebox` 変換 -- Smoke 追加(任意実行): `tools/test/smoke/selfhost/selfhost_runner_smoke.sh` -- **恒等性確認スモーク追加**: - - ScopeBox恒等: `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - LoopForm恒等: `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - Identity 確認スモーク(Selfhost Compiler 直呼び) - - ScopeBox: `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - LoopForm: `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - Selfhost Compiler 前処理導線(既定OFF) - - 追加: `apps/lib/{scopebox_inject.nyash,loopform_normalize.nyash}`(恒等版・将来拡張の足場) - - 配線: `apps/selfhost/compiler/compiler.nyash` が `--scopebox`/`--loopform` を受理して JSON を前処理 - - Runner 側: `src/runner/selfhost.rs` が env→子引数にマップ(`NYASH_SCOPEBOX_ENABLE=1` → `--scopebox`、`NYASH_LOOPFORM_NORMALIZE=1` → `--loopform`) - - 任意: `NYASH_SELFHOST_CHILD_ARGS` で追加引数を透過 -- ループ内 if 合流の PHI 決定を MIR で正規化(仕様不変・堅牢化) - - 変更: `src/mir/loop_builder.rs` - - then/else の代入変数を再帰収集→合流で変数ごとに PHI/直バインドを決定 - - 到達ブランチのみ incoming に採用(break/continue 終端は除外) - - `no_phi_mode` では到達 pred に対して edge‑copy を生成(意味論等価) - - 効果: i/printed 等のキャリア変数が合流後に正しく統一。無限ループ/古い SSA 値混入の根治 -- MiniVmPrints(JSON 経路): 出力総数のカウントを安定化(仕様不変) - - 各 Print ステートメントでの実出力回数を 1 回だけ加算するよう整理(Compare を 1/0 直接 print に) - - 代表プローブ: A/B/7/1/7/5 → count=6 を確認(PyVM と一致) -- JSON provider(yyjsonベンダリング完了・切替はランタイム) - - `plugins/nyash-json-plugin/c/yyjson/{yyjson.h,yyjson.c,LICENSE}` を同梱し、`build.rs + cc` で自己完結ビルド。 - - env `NYASH_JSON_PROVIDER=serde|yyjson`(既定=serde)。nyash.toml の [env] からも設定可能。 - - yyjson 経路で parse/root/get/size/at/str/int/bool を実装(TLVタグは従来準拠)。失敗時は安全に serde にフォールバック。 - - JSON スモーク(parse_ok/err/nested/collect_prints)は serde/yyjson 両経路で緑。専用の yyjson CI ジョブは追加しない(不要)。 -- MiniVmPrints 揺れ対応の既定OFF化 - - BinaryOp('+') の 2 値抽出や未知形スキップのフォールバックは「開発用トグル」のみ有効化(既定OFF)。 - - 本線は JSON Box 経路に統一(collect_prints_mixed は JSON ベースのアプリに切替)。 -- Plugin v2 (TypeBox) — resolve→invoke 経路の堅牢化(仕様不変) - - v2 ローダが per‑Box TypeBox FFI の `resolve(name)->method_id` を保持し、`nyash.toml` 未定義メソッドでも動的解決→キャッシュ - - Unified Host の `resolve_method` も config→TypeBox.resolve の順で解決 - - 影響範囲はローダ/ホストのみ。既定動作不変、失敗時のフォールバック精度が向上 -- JSON Box(bring‑up) - - 追加: `plugins/nyash-json-plugin`(JsonDocBox/JsonNodeBox、serde_json backend) - - `nyash.toml` に JsonDocBox/JsonNodeBox の methods を登録(birth/parse/root/error, kind/get/size/at/str/int/bool/fini) - - PyVM 経路: `src/llvm_py/pyvm/ops_box.py` に最小シム(JsonDoc/JsonNode)を追加(parse/root/get/size/at/str/int/bool) - - Smoke: `tools/test/smoke/selfhost/jsonbox_collect_prints.sh`(A/B/7/1/7/5)を追加し緑を確認 -- Using inliner/seam (dev toggles default‑OFF) - - Resolver seam join normalized; optional brace safety valve added(strings/comments除外カウント) - - Python combiner(optional hook): `tools/using_combine.py` を追加(--fix-braces/--seam-debug など) - - mini_vm_core の末尾ブレースを整合(未閉じ/余剰の解消) - - MiniVm.collect_prints の未知形スキップを Print オブジェクト全体に拡張(停滞防止) -- Docs - - Added strings blueprint: `docs/development/design/blueprints/strings-utf8-byte.md` - - Refreshed docs index with clear "Start here" links (blueprints/strings, EBNF, strings reference) - - Clarified operator/loop sugar policy in `guides/language-core-and-sugar.md` ("!" adopted, do‑while not adopted) - - Concurrency docs (design-only): box model, semantics, and patterns/checklist added - - `docs/development/proposals/concurrency/boxes.md` - - `docs/reference/concurrency/semantics.md` - - `docs/guides/box-patterns.md`, `docs/guides/box-design-checklist.md` -- CI/Smokes - - Added UTF‑8 CP smoke (PyVM): `tools/test/smoke/strings/utf8_cp_smoke.sh` using `apps/tests/strings/utf8_cp_demo.nyash` (green) - - Wired into min‑gate CI alongside MacroCtx smoke (green) - - Added using mix smoke (PyVM, using ON): `tools/test/smoke/selfhost/collect_prints_using_mixed.sh` — green - - Fix: MiniVmBinOp.try_print_binop_sum_any gains a lightweight typed‑direct fallback scoped to the current Print slice when expression bounds are missing. Spec unchanged; only robustness improved. - - Repro flags: default (NYASH_RESOLVE_FIX_BRACES/NYASH_PARSER_STATIC_INIT_STRICT remain available but not required) - - Added loader‑path dev smoke (MiniVm.collect_prints focus): `tools/test/smoke/selfhost/collect_prints_loader.sh`(任意/開発用) - - Added empty‑args using smoke (PyVM, using ON): `tools/test/smoke/selfhost/collect_empty_args_using_smoke.sh` (uses seam brace safety valve; default‑OFF) -- Runtime (Rust) - - StringBox.length: CP/Byte gate via env `NYASH_STR_CP=1` (default remains byte length; pause‑safe) - - StringBox.indexOf/lastIndexOf: CP gate via env `NYASH_STR_CP=1`(既定はByte index; PyVMはCP挙動) - -Notes / Risks -- PyVM はプラグイン未連携のため、JsonBox は最小シムで対応(仕様不変、既定OFFの機能変更なし)。将来的に PyVM→Host ブリッジを導入する場合はデフォルトOFFで段階導入。 -- 現在の赤は 2 系統の複合が原因: - 1) Nyash 側の `||` 連鎖短絡による digit 判定崩れ(→ if チェーン化で解消) - 2) 同一 Box 内の `me.*` 呼びが PyVM で未解決(→ `__me__` ディスパッチ導入)。 - 付随して、`substring(None, …)` 例外や `print_prints_in_slice` のステップ超過が発生。 - ここを「me 撤去+index ガード+ループ番兵」で仕上げる。 - -### Design Decision(Strings & Delegation) -- Keep `StringBox` as the canonical text type (UTF‑8 / Code Point semantics). Do NOT introduce a separate "AnsiStringBox". -- Separate bytes explicitly via `ByteCursorBox`/buffer types (byte semantics only). -- Unify operations through a cursor/strategy interface (length/indexOf/lastIndexOf/substring). `StringBox` delegates to `Utf8Cursor` internally; byte paths use `ByteCursor` explicitly. -- Gate for transition (Rust only): `NYASH_STR_CP=1` enables CP semantics where legacy byte behavior exists. - -## Implementation Order(1–2 days) - -1) Strings CP/Byte baseline(foundation) -- [x] CP smoke(PyVM): length/indexOf/lastIndexOf/substring(apps/tests/strings/utf8_cp_demo.nyash) -- [x] ASCII byte smoke(PyVM): length/indexOf/substring(apps/tests/strings/byte_ascii_demo.nyash) -- [x] Rust CP gate: length/indexOf/lastIndexOf → `NYASH_STR_CP=1` でCP(既定はByte) - - [x] Docs note: CP gate env (`NYASH_STR_CP=1`) を strings blueprint に明記 - -2) Mini‑VM BinOp(+)安定化(Stage‑B 内部置換) -- [x] 広域フォールバック(全数値合算)を削除(安全化) -- [x] typed/token/value-pair の局所探索を導入(非破壊) -- [x] 式境界(Print.expression)の `{…}` 内で `value`×2 を確実抽出→加算(決定化) -- [x] Main.fast‑path を追加(先頭で確定→即 return) -- [x] PyVM:`__me__` ディスパッチ追加/`substring` None ガード - - [x] Mini‑VM:me 呼びの全面撤去(関数呼びへ統一) - - [x] `substring` 呼び前の index>=0 ガード徹底・`print_prints_in_slice` に番兵を追加 - - [x] 代表スモーク(int+int=46)を緑化 - -3) JSON ローダ分離(導線のみ・互換維持) -- [x] MiniJsonLoader(薄ラッパ)経由に集約の導線を適用(prints/単一intの抽出に使用)→ 後で `apps/libs/json_cur.nyash` に差し替え可能 -- [x] スモークは現状維持(stdin/argv 供給とも緑) - - [x] loader‑path の検証用スモーク追加(dev 任意) - -4) Nyash 箱の委譲(内部・段階導入) -- [ ] StringBox 公開API → Utf8CursorBox(length/indexOf/substring)へ委譲(互換を保つ) -- [ ] Byte 系は ByteCursorBox を明示利用(混線防止) - -5) CI/Docs polish(軽量維持) -- [x] README/blueprint に CP gate を追記 -- [ ] Min-gate は軽量を維持(MacroCtx/前展開/UTF‑8/Scope系のみ) - -## Mini‑VM(Stage‑B 進行中) - -目的: Nyash で書かれた極小VM(Mini‑VM)を段階育成し、PyVM 依存を徐々に薄める。まずは “読む→解釈→出力” の最小パイプを安定化。 - -現状(達成) -- stdin ローダ(ゲート): `NYASH_MINIVM_READ_STDIN=1` -- Print(Literal/FunctionCall)、BinaryOp("+") の最小実装とスモーク -- Compare 6種(<, <=, >, >=, ==, !=)と int+int の厳密抽出 -- If(リテラル条件)片側分岐の走査 - - 次にやる(順) -1) JSON ローダの分離(`apps/libs/json_cur.nyash` 採用準備) -2) if/loop の代表スモークを 1–2 本追加(PyVM と出力一致) - - [x] If(リテラル条件): T/F の分岐出力(mini_vm_if_literal_branch_smoke) - - [x] Loop 相当(連続 Print の順序): a,b,c,1,2 の順序確認(mini_vm_print_sequence_smoke) -3) Mini‑VM を関数形式へ移行(トップレベル MVP から段階置換) - - [x] Entry を薄く(args→json 決定→core.run へ委譲) - - [x] core.run の単発 Literal(string/int)対応を内製 - - [x] 純関数 API 追加: MiniVm.collect_prints(json)(最小: literal対応) - -受け入れ(Stage‑B) -- stdin/argv から供給した JSON 入力で Print/分岐が正しく動作(スモーク緑) - -## UTF‑8 計画(UTF‑8 First, Bytes Separate) - -目的: String の公開 API を UTF‑8 カーソルへ委譲し、文字列処理の一貫性と可観測性を確保(性能最適化は後続)。 - -現状 -- Docs: `docs/reference/language/strings.md` -- MVP Box: `apps/libs/utf8_cursor.nyash`, `apps/libs/byte_cursor.nyash` - -段階導入(内部置換のみ) -1) StringBox の公開 API を段階的に `Utf8CursorBox` 委譲(`length/indexOf/substring`) -2) Mini‑VM/macro 内の簡易走査を `Utf8CursorBox`/`ByteCursorBox` に置換(機能同値、内部のみ) -3) Docs/スモークの更新(出力は不変;必要時のみ観測ログを追加) - -Nyash スクリプトの基本ボックス(標準 libs) -- 既存: `json_cur.nyash`, `string_ext.nyash`, `array_ext.nyash`, `string_builder.nyash`, `test_assert.nyash`, `utf8_cursor.nyash`, `byte_cursor.nyash` -- 追加候補(機能追加ポーズ遵守: libs 配下・任意採用・互換保持) - - MapExtBox(keys/values/entries) - - PathBox mini(dirname/join の最小) - - PrintfExt(`StringBuilderBox` 補助) - -## CI/Gates — Green vs Pending - -Always‑on(期待値: 緑) -- rust‑check: `cargo check --all-targets` -- pyvm‑smoke: `tools/pyvm_stage2_smoke.sh` -- macro‑golden: identity/strings/array/map/loopform(key‑order insensitive) -- macro‑smokes‑lite: - - match guard(literal OR / type minimal) - - MIR hints(Scope/Join/Loop) - - ScopeBox(no‑op) - - MacroCtx ctx JSON(追加済み) -- selfhost‑preexpand‑smoke: upper_string(auto engage 確認) - -Pending / Skipped(未導入・任意) -- Match guard: 追加ゴールデン(type最小形) -- LoopForm: break/continue 降下の観測スモーク -- Mini‑VM Stage‑B: JSON ローダ分離 + if/loop 代表スモーク(継続的に強化) -- UTF‑8 委譲: StringBox→Utf8CursorBox の段階置換(内部のみ;ゲート) -- UTF‑8 CP gate (Rust): indexOf/lastIndexOf env‑gated CP semantics(既定OFF) -- LLVM 重テスト: 手動/任意ジョブのみ(常時スキップ) - -## 80/20 Plan(小粒で高効果) - -JSON / Plugin v2(現状に追記) -- [x] v2 resolve→invoke 配線(TypeBox.resolve フォールバック + キャッシュ) -- [x] JsonBox methods を nyash.toml に登録 -- [x] PyVM 最小シム(JsonDoc/JsonNode)を追加 -- [x] JSON collect_prints スモーク追加(緑) -- [x] yyjson ベンダリング+ノード操作実装(parse/root/get/size/at/str/int/bool) -- [x] ランタイム切替(env `NYASH_JSON_PROVIDER`)— 既定は serde。yyjson 専用 CI は追加しない。 -- [ ] TLV void タグ整合(任意:共通ヘルパへ寄せる) -- [ ] method_id キャッシュの統一化(loader 内で Box単位の LRU/Hash で維持) -- [x] MiniVmPrints フォールバックは開発用トグルのみ(既定OFF) - -### Box Std Lib(lib化計画・共通化) - -目的 -- VM/PyVM/自己ホスト実行器で共通に使える“最小面の標準箱”を apps/lib に蒸留し、名前と戻り値を統一する(意味論不変・既定OFF)。 - -置き場(Ny libs) -- `apps/lib/boxes/{console_std.nyash,string_std.nyash,array_std.nyash,map_std.nyash,path_std.nyash,json_std.nyash}`(段階追加) - -導線/トグル(既定OFF) -- 優先度切替(自己ホスト実行器のみ):`NYASH_SELFHOST_BOX_PREF=plugin|ny`(既定=plugin) - - `plugin`: 既存のプラグイン/シムを優先(後方互換) - - `ny`: lib/boxes 実装を優先(プラグイン未定義メソッドは安全フォールバック) -- 導入は include/using ベース(採用側のみ差し替え、広域リネームは行わない) - -優先順位(段階導入) -1) P1(高頻度・最小面) - - ConsoleBox: `print/println/log` → i64(status) - - String: `length/substring/indexOf/lastIndexOf/esc_json` - - ArrayBox: `size/len/get/set/push/toString` - - MapBox: `size/has/get/set/toString` -2) P2(周辺ユーティリティ) - - PathBox: `dirname/join`(POSIX 風) - - JsonDocBox/JsonNodeBox adaptor: plugin へ薄ラップ(PyVM シムと同名) -3) P3(補助) - - StringBuilderBox(最小)/ Pattern helpers(既存 libs を整理) - -受け入れ基準 -- 既定OFFで挙動不変(pref=plugin)。`pref=ny` 時も VM/LLVM/PyVM の出力一致。 -- 代表スモーク(strings/array/map/path/json)を green。未実装メソッドは no-op/None で安全に退避。 - -ロールバック/リスク -- ロールバックは `NYASH_SELFHOST_BOX_PREF=plugin` で即時復帰。 -- 命名衝突は採用側の include/using に限定(既存ファイルの広域変更は行わない)。 - -TODO(段階タスク) -- [x] P1: console_std/string_std/array_std/map_std の雛形を追加(apps/lib/boxes/) -- [x] P1: 自己ホスト実行器の BoxCall ディスパッチに `NYASH_SELFHOST_BOX_PREF` を導入(既定=plugin) -- [x] ScopeBox/LoopForm 前処理(恒等版)実装+スモーク -- [ ] **今すぐ推奨**: 恒等性スモーク実行(実装検証) - - `tools/test/smoke/selfhost/scopebox_identity_smoke.sh` - - `tools/test/smoke/selfhost/loopform_identity_smoke.sh` - - `tools/test/smoke/selfhost/selfhost_runner_smoke.sh` -- [ ] P1: strings/array/map の最小スモークを selfhost 経路で追加(pref=ny) -- [ ] P2: path_std/json_std の雛形とアダプタ(プラグイン優先のラップ) -- [ ] P2: path/json のスモーク(dirname/join、parse/root/get/size/at/str/int/bool) -- [ ] P3: string_builder_std と tests の軽量追加(任意) - -**次フェーズ推奨順序**(小粒・安全): -1. ScopeBox 前処理実装(安全包み込み。JSON v0互換維持、If/Loop に "ヒント用余剰キー" 付与) -2. LoopForm 前処理実装(キー順正規化→安全な末尾整列) -3. P1 箱スモーク(pref=ny での一致確認) -4. Stage‑2(自己ホスト実行器): const/ret/branch 骨格+exit code パリティ - -Checklist(更新済み) -- [x] Self‑host 前展開の固定スモーク 1 本(upper_string) -- [x] MacroCtx ctx JSON スモーク 1 本(CI 組み込み) -- [ ] Match 正規化: 追加テストは当面維持(必要時にのみ追加) -- [x] プロファイル運用ガイド追記(`--profile dev|lite`) -- [ ] LLVM 重テストは常時スキップ(手動/任意ジョブのみ) -- [ ] 警告掃除は次回リファクタで一括(今回は非破壊) - -Acceptance -- 上記 2 本(pre‑expand/MacroCtx)常時緑、既存 smokes/goldens 緑 -- README/ガイドにプロファイル説明が反映済み - - UTF‑8 CP smoke is green under PyVM; Rust CP gate remains opt‑in - -## Repo / Branches (private) -- Active: `selfhost`(作業用), `main`(既定) -- Clean‑up: 古い開発ブランチ(academic-papers / feat/match-type-pattern / selfhosting-dev)を整理。必要なら再作成可。 - -## Self‑Hosting — Stage A(要約) - -Scope(最小) -- JSON v0 ローダ(ミニセット)/ Mini‑VM(最小命令)/ スモーク 2 本(print / if) - -Progress -- [x] Mini‑VM MVP(print literal / if branch) -- [x] PyVM P1: `String.indexOf` 追加 -- [x] Entry 統一(`Main.main`)/ ネスト関数リフト - -- Next(クリーン経路) -- [x] Mini‑VM: 入口薄化(MiniVm.run 呼び一択)— `apps/selfhost-vm/mini_vm.nyash` を薄いラッパに再編(using 前置に依存) -- [x] Mini‑VM: collect_prints の混在ケース用スモーク追加(echo/itoa/compare/binop)→ `tools/test/smoke/selfhost/collect_prints_mixed.sh` -- [x] Mini‑VM: JSON ローダ呼び出しの段階統一(digits/quoted/whitespace を MiniJson に寄せる・第一弾完了) -- [x] Dev sugar: 行頭 @ = local のプリエクスパンドをランナー前処理に常時組込み(ゼロセマンティクス) -- [x] Mini‑VM ソースの @ 採用(apps/selfhost‑vm 配下の入口/補助を段階 @ 化) -- [x] Runner CLI: clap ArgAction(bool フラグ)を一通り点検・SetTrue 指定(panic 回避) -- [ ] Docs: invariants/constraints/testing‑matrix へ反映追加(前処理: using前置/@正規化) - - [x] Docs: Using→Loader 統合メモ(短尺)— docs/development/design/legacy/using-loader-integration.md(READMEにリンク済) - -### Guardrails(active) -- 参照実行: PyVM が常時緑、マクロ正規化は pre‑MIR で一度だけ -- 前展開: `NYASH_MACRO_SELFHOST_PRE_EXPAND=auto`(dev/CI) -- テスト: VM/goldens は軽量維持、IR は任意ジョブ - -## Post‑Bootstrap Backlog(Docs only) -- Language: Scope reuse blocks(design) — docs/development/proposals/scope-reuse.md -- Language: Flow blocks & `->` piping(design) — docs/development/design/legacy/flow-blocks.md -- Guards: Range/CharClass sugar(reference) — docs/reference/language/match-guards.md -- Strings: `toDigitOrNull` / `toIntOrNull`(design note) — docs/reference/language/strings.md -- Concurrency: Box model(Routine/Channel/Select/Scope) — docs/development/proposals/concurrency/boxes.md - - Concurrency semantics(blocking/close/select/trace) — docs/reference/concurrency/semantics.md - -## Nyash VM めど後 — 機能追加リンク(備忘) -- スコープ再利用ブロック(MVP 提案): docs/development/proposals/scope-reuse.md -- 矢印フロー × 匿名ブロック(設計草案): docs/development/design/legacy/flow-blocks.md -- Match Guard の Range/CharClass(参照・設計): docs/reference/language/match-guards.md -- String 便利関数(toDigit/Int; 設計): docs/reference/language/strings.md - -Trigger: nyash_vm の安定(主要スモーク緑・自己ホスト経路が日常運用)。達成後に検討→MVP 実装へ。 - -## Next Up (Parity & Using Edge Smokes) - -- Parity quick harness(任意): `tools/smokes/parity_quick.sh` で代表 apps/tests を PyVM vs llvmlite で比較 -- Using エッジケース: 相互依存/相対パス混在/alias のスモーク追加(apps/tests + tools/test/smoke/using/edge_cases.sh) -- Using 混在スモークの緑化仕上げ(PyVM) - - MiniVmPrints.print_prints_in_slice の binop/compare/int リテラル境界(obj_end/p_obj_end)を調整 - - ArrayBox 経路の size/get 依存を避け、直接 print する経路の安定化を優先 - - 再現フラグ(開発のみ): `NYASH_RESOLVE_FIX_BRACES=1 NYASH_PARSER_STATIC_INIT_STRICT=1` - -### Next Up (JSON line) -- TLV void タグの統一(任意) -- method_id 解決キャッシュの整備・計測 -- YYJSON backend のスケルトン追加(既定OFF・プラグイン切替可能設計) -- JSON smokes をCI最小ゲートへ追加 -- Self‑Host(自己ホスト実行器) - - [ ] Stage 0: フラグ/ランナー配線のみ(no‑op Ny runner) - - [ ] Stage 1: MIR ローダ(JSON→構造体) - - [ ] Stage 2: コア命令(const/binop/compare/branch/jump/ret/phi) - - [ ] Stage 3: call/externcall/boxcall(MVP) - - [ ] Stage 4: Array/Map 最小メソッド - - [ ] Stage 5: using/seam 代表ケース安定化 - - [ ] Stage 6: パリティハーネス/CI(非ブロッキング→昇格) - -### Self‑Host フラグ/戻し手順(記録) -- フラグ(既定OFF) - - `NYASH_SELFHOST_EXEC=1`: Ny Executor を有効化 - - `NYASH_SELFHOST_TRACE=1`: 追跡ログ - - `NYASH_SELFHOST_STEP_MAX`: ステップ上限 - - `NYASH_SELFHOST_STRICT=1`: 厳格モード -- ロールバック: フラグ OFF で即 PyVM に復帰(既定)。差分は最小・局所で導入。 - -### Notes (Stage 0 wiring) -- Rust 側は MIR(JSON) を `tmp/nyash_selfhost_mir.json` に出力→Ny ランナー(apps/selfhost-runtime/runner.nyash)へ引き渡し。 -- 子プロセスへは `NYASH_SELFHOST_EXEC` を伝播しない(再帰配線を防止)。 -- 現段階の Ny ランナーは no‑op で 0 を返す。次ステージでローダ/ディスパッチを追加。 -## 2025-09-26: 短絡(&&/||)の正規低下を実装(根治) - -目的 -- `&&`/`||` を BinOp ではなく制御フロー(branch + PHI)で下ろし、RHS を必要時のみ評価する。 -- 結果は常に Bool。truthy 評価は分岐側(runtime `to_bool_vm`)に委ねる。 - -実装 -- `src/mir/builder/ops.rs` - - `build_binary_op` で `And`/`Or` を特別扱いし、`build_logical_shortcircuit` に委譲。 - - `build_logical_shortcircuit` では以下を実装: - - LHS を評価→ `Branch(LHS)` - - AND: then=RHS を truthy で true/false に還元、else=false - - OR: then=true、else=RHS を truthy で true/false に還元 - - then/else の変数差分を `merge_modified_vars` でマージ、結果は `Phi` で Bool を合成 - -検証(軽量) -- `tmp/sc_bool.nyash` にて `print((1 > 0) && (0 > 1))` → `false`、`print((1 > 0) || (0 > 1))` → `true` を確認。 - -影響範囲と方針 -- 既存仕様不変(短絡の意味論を本来の姿に)。 -- BinOp 経路での And/Or は使用しないため、RHS の副作用が誤って実行される経路を遮断。 - -未完了/次の作業 -- JSON VM スモーク: 依然として `VoidBox.push` 経由の失敗が残る(ログにデプリケーション行も混入)。 - - 短絡未適用箇所の有無を確認(他の演算子や ternary 経路)。 - - テスト出力のノイズフィルタを拡張("Using builtin ArrayBox" 行)。 - - グリーン化後に VM fallback の一時ガード(VoidBox 系)を段階的に撤去。 - -ロールバック容易性 -- 差分は `ops.rs` 限定・小規模。`build_logical_shortcircuit` を外せば従来に戻る。 -## 2025-09-26: SSA 支配破れの根治(Pin → 既存 PHI マージへ) - -背景 -- JSON トークナイザ/パーサ実行時に VM fallback で `use of undefined value ValueId(..)` が発生。 -- 原因は「ブロックをまたいで再利用する“式の一時値”が変数へ束縛されておらず、合流点で PHI に載らない」ため、支配関係を満たさないまま参照されること。 - -方針(最小・設計整合) -1) Pin(昇格): 一時値を擬似ローカル(slot)へ昇格し、以後は slot 経由で参照させる。 - - 既存の `merge_modified_vars / normalize_if_else_phi` に自然に乗るため、合流点で PHI が立つ。 -2) 適用箇所(段階導入) - - 短絡(&&/||): LHS を `pin_to_slot(lhs, "@sc_lhs")`(済) - - if 低下: 条件式/繰返し比較されるオペランドを Pin(これから) -3) トレース・検証 - - `NYASH_VM_TRACE=1` でブロック/命令/PHI 適用/未定義参照を詳細出力(済) - - 追加で Verifier(dev 限定)に dominance 簡易検査を入れる(任意) - -実装状況 -- 実装済み: - - 短絡の正規低下(RHS 未評価を保証) - - `pin_to_slot` を MirBuilder に追加 - - LHS を pin(build_logical_shortcircuit 内) - - VM 実行トレース(`NYASH_VM_TRACE`)導入 -- 未着手/次: - - if 低下(lower_if_form)での Pin を導入 - - 必要なら dominance Verifier(dev) - - JSON VM スモーク quick を再確認→緑後に一時的 Void ガードを格下げ/撤去 - -受け入れ条件 / ロールバック -- JSON quick(VM)で `use of undefined value` が消えること。短絡/分岐の意味論は既存仕様のまま。 -- Pin は局所かつ可逆。問題があれば当該箇所の Pin 呼び出しを除去すれば戻せる。 - -ドキュメント -- 設計ノート追加: `docs/development/notes/mir-ssa-pin-slot.md` - -この後の順番(作業 TODO) -1) docs/CURRENT_TASK 整備(本更新) -2) lower_if_form に Pin(条件式/繰返し比較オペランドの昇格) -3) JSON VM スモーク quick 再実行(必要に応じ追加 Pin) -4) (任意)dominance Verifier を dev 限定で導入 -5) 一時 Void ガードの検知ログ化→撤去 - -即時タスク(詳細ルール・実装メモ) -- Pin の適用規則(最小セット) - - 短絡: `build_logical_shortcircuit` で LHS を必ず `pin_to_slot(lhs, "@sc_lhs")`(済) - - if/elseif: 条件式の中で合流後も参照する可能性のある“一時値”を分岐前に `pin_to_slot`(これから) - - ループ: 反復して比較する値(scanner の current()/position 等)は必要に応じてループ入場直後で `pin_to_slot` -- エントリ処理の順序 - - PHI 適用 →(必要時のみ)single‑pred copy‑in(Id/Copy) - - 先に copy‑in は行わない(PHI 入力と競合するため) -- 追加検証 - - トレース: `NYASH_VM_TRACE=1` で未定義参照箇所を特定し、漏れ箇所に局所 Pin を追加 - - Verifier(任意): 非 PHI 命令オペランドが使用ブロックに支配されるかの簡易チェック(dev) -## 2025-09-27 — JSON using/VM stabilization (slice) - -Summary -- Fixed tokenizer EOF issue: JsonTokenizer now constructs scanner via `new JsonScanner(input)` to preserve input on VM path. -- Added missing JsonNodeInstance helpers: `array_push/1`, `array_size/0`, `object_get/1` to prevent fallback to static functions. -- VM instance-dispatch: added narrow, safe fast-paths for `JsonNodeInstance` methods (`array_push/size`, `object_set/get/keys`) that operate on the internal `value` field directly. This avoids static fallback and makes stringify/roundtrip stable. - -Why -- Legacy path sometimes dispatched to static `JsonNode.*` functions for instance receivers, causing incorrect accesses (`me` ≠ instance). The fast-path ensures instance semantics even when the function table lacks the instance variant. -- Tokenizer previously returned only EOF due to a scanner-construction regression on the VM path. - -Status -- json_roundtrip_vm: improved; tokenizer tokens correct, instance stringify uses array/object internals. -- json_nested_vm: still failing on a later stage with `Type error: unsupported compare Ge on Void...` inside VM comparisons (likely in number parsing/loop or nested structure handling). - -Next Steps (focused) -1) Pinpoint the Void comparison site (enable `NYASH_VM_TRACE=1`, run `json_nested_vm.sh`) and fix the producing path. - - Target areas: `apps/lib/json_native/lexer/scanner.nyash` (read_number / structural), `apps/lib/json_native/parser/parser.nyash` (array/object loops), conditional building. - - Ensure no Void reaches `Compare` by slotifying inputs or default-initializing locals used across branches. -2) Keep instance-dispatch bridge narrow (JsonNode only). After parity is green, remove it by ensuring instance functions are present in the function table. - -Acceptance -- `tools/smokes/v2/profiles/quick/core/json_roundtrip_vm.sh` PASS (dev+AST). -- `tools/smokes/v2/profiles/quick/core/json_nested_vm.sh` PASS with expected outputs for all three samples. -- No reliance on global Void-toleration; fixes are local and structural. diff --git a/lang/src/vm/hako_module.toml b/lang/src/vm/hako_module.toml index 625d2dea..63e187f4 100644 --- a/lang/src/vm/hako_module.toml +++ b/lang/src/vm/hako_module.toml @@ -65,6 +65,7 @@ mini_vm_lib = "mini_vm_lib.hako" "hakorune-vm.compare_handler" = "hakorune-vm/compare_handler.hako" "hakorune-vm.copy_handler" = "hakorune-vm/copy_handler.hako" "hakorune-vm.unaryop_handler" = "hakorune-vm/unaryop_handler.hako" +"hakorune-vm.ir.types" = "hakorune-vm/ir/types.hako" [private] # helpers = "internal/helpers.hako" diff --git a/lang/src/vm/hakorune-vm/dispatcher_v1.hako b/lang/src/vm/hakorune-vm/dispatcher_v1.hako index 61dff856..fc7b5b2a 100644 --- a/lang/src/vm/hakorune-vm/dispatcher_v1.hako +++ b/lang/src/vm/hakorune-vm/dispatcher_v1.hako @@ -15,6 +15,7 @@ using selfhost.vm.helpers.v1_schema as V1SchemaBox using selfhost.vm.helpers.mir_call_v1_handler as MirCallV1HandlerBox using selfhost.vm.helpers.v1_phi_table as V1PhiTableBox using selfhost.vm.helpers.v1_phi_adapter as V1PhiAdapterBox +using selfhost.vm.hakorune-vm.ir.types as V1IrTypes static box NyVmDispatcherV1Box { // Internal scanner (block0 only): const / mir_call / ret @@ -104,6 +105,8 @@ static box NyVmDispatcherV1Box { local op = ent.get("op") local item = ent.get("text") if op == null || item == null { continue } + // Optional: build typed IR shadow (構造のみ、挙動不変) + me._maybe_typed_shadow(ent) // Dispatch if op == "const" { OpHandlersBox.handle_const(item, regs) } else if op == "compare" { @@ -137,6 +140,28 @@ static box NyVmDispatcherV1Box { } else { return MirVmMin.run_min(json) } } } + // Build typed IR shadow object for debugging/SSOT導入の段階準備(flag: HAKO_V1_TYPED_IR_SHADOW=1) + _maybe_typed_shadow(ent) { + if env.get("HAKO_V1_TYPED_IR_SHADOW") != "1" { return 0 } + local op = ent.get("op"); if op == null { return 0 } + // Construct minimal typed IR box per op (構造のみ). 値は文字列/整数としてそのまま格納する。 + if op == "const" { + local b = new V1IrTypes.V1ConstIR(); b.target_reg = ent.get("dst"); b.value = ent.get("text"); return 0 + } + if op == "compare" { + local b = new V1IrTypes.V1CompareIR(); b.op = ent.get("cmp"); b.lhs = ent.get("lhs"); b.rhs = ent.get("rhs"); b.target_reg = ent.get("dst"); return 0 + } + if op == "branch" { + local b = new V1IrTypes.V1BranchIR(); b.condition = ent.get("cond"); b.then_block = ent.get("then"); b.else_block = ent.get("else"); return 0 + } + if op == "jump" { + local b = new V1IrTypes.V1JumpIR(); b.target_block = ent.get("target"); return 0 + } + if op == "ret" { + local b = new V1IrTypes.V1RetIR(); b.value = ent.get("value"); return 0 + } + return 0 + } // Main entry: Choose internal scanner when enabled; otherwise delegate to Mini‑VM run(json) { if env.get("HAKO_V1_DISPATCHER_FLOW") == "1" { return me.run_scan_flow(json) } diff --git a/lang/src/vm/hakorune-vm/ir/types.hako b/lang/src/vm/hakorune-vm/ir/types.hako new file mode 100644 index 00000000..33c2c6d0 --- /dev/null +++ b/lang/src/vm/hakorune-vm/ir/types.hako @@ -0,0 +1,38 @@ +// Hako v1 Typed IR (SSOT) — structure only +// Responsibility: Define minimal typed IR boxes used as a shared structure +// for reading/writing MIR v1 in Hakorune components. No execution logic. + +box V1ConstIR { + value: StringBox + target_reg: IntegerBox +} + +box V1CompareIR { + op: StringBox + lhs: IntegerBox + rhs: IntegerBox + target_reg: IntegerBox +} + +box V1BranchIR { + condition: IntegerBox + then_block: IntegerBox + else_block: IntegerBox +} + +box V1JumpIR { + target_block: IntegerBox +} + +// incoming: [[pred:int, val:int], ...] +box V1PhiIR { + target_reg: IntegerBox + incoming: ArrayBox +} + +box V1RetIR { + value: IntegerBox +} + +static box V1IrTypesMain { method main(args) { return 0 } } + diff --git a/tools/smokes/v2/lib/test_runner.sh b/tools/smokes/v2/lib/test_runner.sh index e6c8c0f8..0c4ec414 100644 --- a/tools/smokes/v2/lib/test_runner.sh +++ b/tools/smokes/v2/lib/test_runner.sh @@ -269,17 +269,6 @@ verify_mir_rc() { if [ "${HAKO_VERIFY_V1_FORCE_CORE:-0}" = "1" ]; then "$NYASH_BIN" --mir-json-file "$json_path" >/dev/null 2>&1; return $? fi - # Inline driver (env JSON): avoid embedding large JSON literal to keep parser robust - local code_v1=$(cat <<'HCODE' -using selfhost.vm.hv1.dispatch as NyVmDispatcherV1Box -static box Main { method main(args) { - local j = env.get("NYASH_VERIFY_JSON") - local rc = NyVmDispatcherV1Box.run(j) - print("" + rc) - return rc -} } -HCODE -) # hv1 直行(NyashParserバイパス): vm.rs冒頭で NYASH_VERIFY_JSON を検知して MIR 実行 local out_v1; out_v1=$(HAKO_V1_FLOW_TRACE=1 HAKO_V1_EXTERN_PROVIDER=1 HAKO_V1_DISPATCHER_FLOW=1 HAKO_V1_ALLOW_PHI_EXPERIMENT=1 \ HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 HAKO_ROUTE_HAKOVM=1 \ @@ -288,28 +277,6 @@ HCODE if [[ "$out_v1" =~ ^-?[0-9]+$ ]]; then local n=$out_v1; if [ $n -lt 0 ]; then n=$(( (n % 256 + 256) % 256 )); else n=$(( n % 256 )); fi; return $n fi - # Optional dev fallback: prelude_v1 include + preinclude(alias-only が安定したら撤去) - if [ "${SMOKES_HV1_INCLUDE_FALLBACK:-0}" = "1" ]; then - local code_v1_inc=$(cat <<'HCODE' -include "lang/src/vm/hakorune-vm/prelude_v1.hako" -static box Main { method main(args) { - local j = env.get("NYASH_VERIFY_JSON") - local rc = NyVmDispatcherV1Box.run(j) - print("" + rc) - return rc -} } -HCODE -) - out_v1=$(HAKO_ENABLE_USING=1 NYASH_ENABLE_USING=1 NYASH_USING_AST=1 \ - HAKO_PREINCLUDE=1 NYASH_PREINCLUDE=1 \ - HAKO_V1_FLOW_TRACE=1 HAKO_V1_EXTERN_PROVIDER=1 HAKO_V1_DISPATCHER_FLOW=1 HAKO_V1_ALLOW_PHI_EXPERIMENT=1 \ - HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 \ - NYASH_VERIFY_JSON="$(cat "$json_path")" \ - run_nyash_vm -c "$code_v1_inc" 2>/dev/null | tr -d '\r' | awk '/^-?[0-9]+$/{n=$0} END{if(n!="") print n}') - if [[ "$out_v1" =~ ^-?[0-9]+$ ]]; then - local n=$out_v1; if [ $n -lt 0 ]; then n=$(( (n % 256 + 256) % 256 )); else n=$(( n % 256 )); fi; return $n - fi - fi # No include+preinclude fallback succeeded → Core にフォールバック "$NYASH_BIN" --mir-json-file "$json_path" >/dev/null 2>&1 return $?