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

@ -23,18 +23,21 @@ mod demos;
mod dispatch;
pub mod json_v0_bridge;
mod json_v1_bridge;
pub mod mir_json { pub mod common; }
mod mir_json_v0;
pub mod mir_json {
pub mod common;
}
pub mod core_executor;
pub mod hv1_inline;
pub mod mir_json_emit;
mod mir_json_v0;
pub mod modes;
mod pipe_io;
pub mod core_executor;
mod pipeline;
mod plugins;
mod selfhost;
mod stage1_bridge;
mod tasks;
mod trace;
mod plugins;
pub mod hv1_inline;
// v2 plugin system imports
use nyash_rust::runner_plugin_init;
@ -89,27 +92,43 @@ impl NyashRunner {
return;
}
let groups = self.config.as_groups();
if let Some(code) = self.maybe_run_stage1_cli_stub(&groups) {
std::process::exit(code);
}
// Early: direct MIR JSON execution (no source file). Experimental diagnostics/exec.
if let Some(path) = groups.parser.mir_json_file.as_ref() {
match std::fs::read_to_string(path) {
Ok(text) => {
match crate::runner::json_v1_bridge::try_parse_v1_to_module(&text) {
Ok(Some(module)) => { let rc = self.execute_mir_module_quiet_exit(&module); std::process::exit(rc); }
Ok(None) => {
if text.contains("\"functions\"") && text.contains("\"blocks\"") {
match crate::runner::mir_json_v0::parse_mir_v0_to_module(&text) {
Ok(module) => { let rc = self.execute_mir_module_quiet_exit(&module); std::process::exit(rc); }
Err(e) => { eprintln!("❌ MIR JSON v0 parse error: {}", e); std::process::exit(1); }
}
} else {
eprintln!("❌ MIR JSON invalid or unsupported shape: {}", path);
std::process::exit(1);
}
}
Err(e) => { eprintln!("❌ MIR JSON parse error (v1): {}", e); std::process::exit(1); }
Ok(text) => match crate::runner::json_v1_bridge::try_parse_v1_to_module(&text) {
Ok(Some(module)) => {
let rc = self.execute_mir_module_quiet_exit(&module);
std::process::exit(rc);
}
Ok(None) => {
if text.contains("\"functions\"") && text.contains("\"blocks\"") {
match crate::runner::mir_json_v0::parse_mir_v0_to_module(&text) {
Ok(module) => {
let rc = self.execute_mir_module_quiet_exit(&module);
std::process::exit(rc);
}
Err(e) => {
eprintln!("❌ MIR JSON v0 parse error: {}", e);
std::process::exit(1);
}
}
} else {
eprintln!("❌ MIR JSON invalid or unsupported shape: {}", path);
std::process::exit(1);
}
}
Err(e) => {
eprintln!("❌ MIR JSON parse error (v1): {}", e);
std::process::exit(1);
}
},
Err(e) => {
eprintln!("❌ Error reading MIR JSON {}: {}", path, e);
std::process::exit(1);
}
Err(e) => { eprintln!("❌ Error reading MIR JSON {}: {}", path, e); std::process::exit(1); }
}
}
// Early: build
@ -123,7 +142,9 @@ impl NyashRunner {
// Preprocess usings and directives (includes dep-tree log)
self.preprocess_usings_and_directives(&groups);
// JSON v0 bridge
if self.try_run_json_v0_pipe() { return; }
if self.try_run_json_v0_pipe() {
return;
}
// Named task
if let Some(task) = groups.run_task.clone() {
if let Err(e) = run_named_task(&task) {
@ -139,7 +160,9 @@ impl NyashRunner {
self.configure_backend(&groups);
self.enforce_runtime_jit_policy(&groups);
// Benchmark
if self.maybe_run_benchmark(&groups) { return; }
if self.maybe_run_benchmark(&groups) {
return;
}
// Dispatch
if std::env::var("NYASH_VM_ROUTE_TRACE").ok().as_deref() == Some("1") {
let backend = &groups.backend.backend;
@ -159,15 +182,26 @@ impl NyashRunner {
let mut pending_using: Vec<(String, Option<String>)> = Vec::new();
for spec in &groups.input.cli_usings {
let s = spec.trim();
if s.is_empty() { continue; }
if s.is_empty() {
continue;
}
let (target, alias) = if let Some(pos) = s.find(" as ") {
(s[..pos].trim().to_string(), Some(s[pos + 4..].trim().to_string()))
} else { (s.to_string(), None) };
(
s[..pos].trim().to_string(),
Some(s[pos + 4..].trim().to_string()),
)
} else {
(s.to_string(), None)
};
let is_path = crate::runner::modes::common_util::resolve::path_util::is_using_target_path_original(&target);
if is_path {
let path = target.trim_matches('"').to_string();
let name = alias.clone().unwrap_or_else(|| {
std::path::Path::new(&path).file_stem().and_then(|s| s.to_str()).unwrap_or("module").to_string()
std::path::Path::new(&path)
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("module")
.to_string()
});
pending_using.push((name, Some(path)));
} else {
@ -190,29 +224,51 @@ impl NyashRunner {
root_info = format!(" root='{}'", r);
}
}
crate::cli_v!("[deps] loaded {} bytes from{} {}", bytes, if root_info.is_empty() { "" } else { ":" }, root_info);
crate::cli_v!(
"[deps] loaded {} bytes from{} {}",
bytes,
if root_info.is_empty() { "" } else { ":" },
root_info
);
}
Err(e) => {
crate::cli_v!("[deps] read error: {}", e);
}
Err(e) => { crate::cli_v!("[deps] read error: {}", e); }
}
}
// If a file is provided, apply script-level directives and late using/env merges
if let Some(ref filename) = groups.input.file {
if let Ok(code) = fs::read_to_string(filename) {
// Apply directives and lint
let strict_fields = std::env::var("NYASH_FIELDS_TOP_STRICT").ok().as_deref() == Some("1");
if let Err(e) = cli_directives::apply_cli_directives_from_source(&code, strict_fields, groups.debug.cli_verbose) {
let strict_fields =
std::env::var("NYASH_FIELDS_TOP_STRICT").ok().as_deref() == Some("1");
if let Err(e) = cli_directives::apply_cli_directives_from_source(
&code,
strict_fields,
groups.debug.cli_verbose,
) {
eprintln!("❌ Lint/Directive error: {}", e);
std::process::exit(1);
}
// Late env overrides (paths/modules)
if let Ok(paths) = std::env::var("NYASH_USING_PATH") {
for p in paths.split(':') { let p = p.trim(); if !p.is_empty() { using_ctx.using_paths.push(p.to_string()); } }
for p in paths.split(':') {
let p = p.trim();
if !p.is_empty() {
using_ctx.using_paths.push(p.to_string());
}
}
}
if let Ok(mods) = std::env::var("NYASH_MODULES") {
for ent in mods.split(',') {
if let Some((k, v)) = ent.split_once('=') {
let k = k.trim(); let v = v.trim();
if !k.is_empty() && !v.is_empty() { using_ctx.pending_modules.push((k.to_string(), v.to_string())); }
let k = k.trim();
let v = v.trim();
if !k.is_empty() && !v.is_empty() {
using_ctx
.pending_modules
.push((k.to_string(), v.to_string()));
}
}
}
}
@ -226,9 +282,22 @@ impl NyashRunner {
let verbose = crate::config::env::cli_verbose();
let ctx = std::path::Path::new(filename).parent();
for (ns, alias) in pending_using.iter() {
let value = match resolve_using_target(ns, false, &using_ctx.pending_modules, &using_ctx.using_paths, &using_ctx.aliases, &using_ctx.packages, ctx, strict, verbose) {
let value = match resolve_using_target(
ns,
false,
&using_ctx.pending_modules,
&using_ctx.using_paths,
&using_ctx.aliases,
&using_ctx.packages,
ctx,
strict,
verbose,
) {
Ok(v) => v,
Err(e) => { eprintln!("❌ using: {}", e); std::process::exit(1); }
Err(e) => {
eprintln!("❌ using: {}", e);
std::process::exit(1);
}
};
let sb = nyash_rust::box_trait::StringBox::new(value.clone());
nyash_rust::runtime::modules_registry::set(ns.clone(), Box::new(sb));
@ -244,8 +313,14 @@ impl NyashRunner {
/// Apply early environment toggles that affect CLI behavior and VM stats.
/// Side effects: sets `NYASH_CLI_VERBOSE`, `NYASH_GC_MODE` when specified by CLI groups.
fn apply_common_env(&self, groups: &crate::cli::CliGroups) {
if groups.debug.cli_verbose { std::env::set_var("NYASH_CLI_VERBOSE", "1"); }
if let Some(ref m) = groups.gc_mode { if !m.trim().is_empty() { std::env::set_var("NYASH_GC_MODE", m); } }
if groups.debug.cli_verbose {
std::env::set_var("NYASH_CLI_VERBOSE", "1");
}
if let Some(ref m) = groups.gc_mode {
if !m.trim().is_empty() {
std::env::set_var("NYASH_GC_MODE", m);
}
}
}
// init_runtime_and_plugins moved to runner/plugins.rs
@ -253,8 +328,12 @@ impl NyashRunner {
/// Configure backend knobs (VM) from CLI flags and env.
/// JIT configuration removed with JIT/Cranelift archival.
fn configure_backend(&self, groups: &crate::cli::CliGroups) {
if groups.backend.vm_stats { std::env::set_var("NYASH_VM_STATS", "1"); }
if groups.backend.vm_stats_json { std::env::set_var("NYASH_VM_STATS_JSON", "1"); }
if groups.backend.vm_stats {
std::env::set_var("NYASH_VM_STATS", "1");
}
if groups.backend.vm_stats_json {
std::env::set_var("NYASH_VM_STATS_JSON", "1");
}
// JIT configuration removed - archived to archive/jit-cranelift/
}
@ -272,7 +351,9 @@ impl NyashRunner {
println!("Running {} iterations per test...", groups.iterations);
println!();
// VM-legacy removed - benchmark mode no longer available
eprintln!("❌ Benchmark mode removed with vm-legacy. Use regular execution modes instead.");
eprintln!(
"❌ Benchmark mode removed with vm-legacy. Use regular execution modes instead."
);
std::process::exit(1);
}
false
@ -281,7 +362,10 @@ impl NyashRunner {
/// Final dispatch to selected execution mode (file/JIT-direct or demos).
fn dispatch_entry(&self, groups: &crate::cli::CliGroups) {
if let Some(ref filename) = groups.input.file {
if groups.backend.jit.direct { self.run_file_jit_direct(filename); return; }
if groups.backend.jit.direct {
self.run_file_jit_direct(filename);
return;
}
// Optional route trace before delegating to backend dispatcher
if std::env::var("NYASH_VM_ROUTE_TRACE").ok().as_deref() == Some("1") {
eprintln!(
@ -290,7 +374,9 @@ impl NyashRunner {
);
}
self.run_file(filename);
} else { demos::run_all_demos(); }
} else {
demos::run_all_demos();
}
}
}