chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更

Phase 25.1 完了成果:
-  LoopForm v2 テスト・ドキュメント・コメント完備
  - 4ケース(A/B/C/D)完全テストカバレッジ
  - 最小再現ケース作成(SSAバグ調査用)
  - SSOT文書作成(loopform_ssot.md)
  - 全ソースに [LoopForm] コメントタグ追加

-  Stage-1 CLI デバッグ環境構築
  - stage1_cli.hako 実装
  - stage1_bridge.rs ブリッジ実装
  - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh)
  - アーキテクチャ改善提案文書

-  環境変数削減計画策定
  - 25変数の完全調査・分類
  - 6段階削減ロードマップ(25→5、80%削減)
  - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG)

Phase 26-D からの累積変更:
- PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等)
- MIRビルダーリファクタリング
- 型伝播・最適化パス改善
- その他約300ファイルの累積変更

🎯 技術的成果:
- SSAバグ根本原因特定(条件分岐内loop変数変更)
- Region+next_iパターン適用完了(UsingCollectorBox等)
- LoopFormパターン文書化・テスト化完了
- セルフホスティング基盤強化

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <noreply@openai.com>
Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-21 06:25:17 +09:00
parent baf028a94f
commit f9d100ce01
366 changed files with 14322 additions and 5236 deletions

View File

@ -1,9 +1,5 @@
use super::super::NyashRunner;
use nyash_rust::{
ast::ASTNode,
parser::NyashParser,
mir::MirCompiler,
};
use nyash_rust::{ast::ASTNode, mir::MirCompiler, parser::NyashParser};
use std::{fs, process};
impl NyashRunner {
@ -71,9 +67,7 @@ impl NyashRunner {
// Centralized plugin guard
let strict = crate::config::env::env_bool("NYASH_VM_PLUGIN_STRICT");
crate::runner::modes::common_util::plugin_guard::check_and_report(
strict,
quiet_pipe,
"vm",
strict, quiet_pipe, "vm",
);
}
@ -97,17 +91,13 @@ impl NyashRunner {
// When using is enabled, resolve preludes/profile; otherwise, keep original code.
let mut code_final = if crate::config::env::enable_using() {
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(
self,
&code,
filename,
self, &code, filename,
) {
Ok((_, prelude_paths)) => {
if !prelude_paths.is_empty() {
// SSOT: always text-merge for VM (includes .hako-safe handling inside)
match crate::runner::modes::common_util::resolve::merge_prelude_text(
self,
&code,
filename,
self, &code, filename,
) {
Ok(merged) => {
if trace {
@ -144,24 +134,18 @@ impl NyashRunner {
};
// Dev sugar pre-expand: @name = expr → local name = expr
code_final =
crate::runner::modes::common_util::resolve::preexpand_at_local(&code_final);
code_final = crate::runner::modes::common_util::resolve::preexpand_at_local(&code_final);
// Hako-friendly normalize: strip leading `local ` at line head for Nyash parser compatibility.
if crate::runner::modes::common_util::hako::looks_like_hako_code(&code_final)
|| filename.ends_with(".hako")
{
code_final =
crate::runner::modes::common_util::hako::strip_local_decl(&code_final);
code_final = crate::runner::modes::common_util::hako::strip_local_decl(&code_final);
}
// Optional: dump merged Hako source after using/prelude merge and Hako normalization.
// Guarded by env; defaultはOFFPhase 25.1a selfhost builder デバッグ用)。
if std::env::var("NYASH_VM_DUMP_MERGED_HAKO")
.ok()
.as_deref()
== Some("1")
{
if std::env::var("NYASH_VM_DUMP_MERGED_HAKO").ok().as_deref() == Some("1") {
let default_path = {
let mut tmp = std::env::temp_dir();
tmp.push("nyash_merged_vm.hako");
@ -176,15 +160,14 @@ impl NyashRunner {
if trace {
eprintln!("[vm/merged-hako] failed to write {}: {}", path, e);
}
} else if trace
|| crate::config::env::env_bool("NYASH_VM_DUMP_MERGED_HAKO_LOG")
{
} else if trace || crate::config::env::env_bool("NYASH_VM_DUMP_MERGED_HAKO_LOG") {
eprintln!("[vm/merged-hako] dumped merged code to {}", path);
}
}
if trace && (std::env::var("NYASH_PARSER_STAGE3").ok() == Some("1".into())
|| std::env::var("HAKO_PARSER_STAGE3").ok() == Some("1".into()))
if trace
&& (std::env::var("NYASH_PARSER_STAGE3").ok() == Some("1".into())
|| std::env::var("HAKO_PARSER_STAGE3").ok() == Some("1".into()))
{
eprintln!("[vm] Stage-3: enabled (env) for {}", filename);
}
@ -210,9 +193,12 @@ impl NyashRunner {
let ast_combined = match NyashParser::parse_from_string(&code_final) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error in {}: {}", filename, e);
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename, &code_final, &e,
);
// Enhanced context: list merged prelude files if any
let preludes = crate::runner::modes::common_util::resolve::clone_last_merged_preludes();
let preludes =
crate::runner::modes::common_util::resolve::clone_last_merged_preludes();
if !preludes.is_empty() {
eprintln!("[parse/context] merged prelude files ({}):", preludes.len());
let show = std::cmp::min(16, preludes.len());
@ -297,7 +283,8 @@ impl NyashRunner {
type_parameters,
is_static,
..
} = st {
} = st
{
if *is_static {
static_names.push(name.clone());
// Store static box declaration for VM singleton persistence
@ -372,7 +359,8 @@ impl NyashRunner {
&self,
name: &str,
args: &[Box<dyn crate::box_trait::NyashBox>],
) -> Result<Box<dyn crate::box_trait::NyashBox>, RuntimeError> {
) -> Result<Box<dyn crate::box_trait::NyashBox>, RuntimeError>
{
let opt = { self.decls.read().unwrap().get(name).cloned() };
let decl = match opt {
Some(d) => d,
@ -408,7 +396,9 @@ impl NyashRunner {
let factory = InlineUserBoxFactory {
decls: Arc::new(RwLock::new(decls)),
};
crate::runtime::unified_registry::register_user_defined_factory(std::sync::Arc::new(factory));
crate::runtime::unified_registry::register_user_defined_factory(
std::sync::Arc::new(factory),
);
}
// Return static_box_decls for VM registration
@ -430,10 +420,7 @@ impl NyashRunner {
if crate::config::env::env_bool("NYASH_VM_ESCAPE_ANALYSIS") {
let removed = crate::mir::passes::escape::escape_elide_barriers_vm(&mut module_vm);
if removed > 0 {
crate::cli_v!(
"[VM] escape_elide_barriers: removed {} barriers",
removed
);
crate::cli_v!("[VM] escape_elide_barriers: removed {} barriers", removed);
}
}
@ -476,13 +463,17 @@ impl NyashRunner {
match vm.execute_module(&module_vm) {
Ok(ret) => {
use crate::box_trait::{IntegerBox, BoolBox};
use crate::box_trait::{BoolBox, IntegerBox};
// Extract exit code from return value
let exit_code = if let Some(ib) = ret.as_any().downcast_ref::<IntegerBox>() {
ib.value as i32
} else if let Some(bb) = ret.as_any().downcast_ref::<BoolBox>() {
if bb.value { 1 } else { 0 }
if bb.value {
1
} else {
0
}
} else {
// For non-integer/bool returns, default to 0 (success)
0