feat(phase32): L-2.1 Stage-1 UsingResolver JoinIR integration + cleanup

Phase 32 L-2.1 complete implementation:

1. Stage-1 UsingResolver main line JoinIR connection
   - CFG-based LoopForm construction for resolve_for_source/5
   - LoopToJoinLowerer integration with handwritten fallback
   - JSON snapshot tests 6/6 PASS

2. JoinIR/VM Bridge improvements
   - Simplified join_ir_vm_bridge.rs dispatch logic
   - Enhanced json.rs serialization
   - PHI core boxes cleanup (local_scope_inspector, loop_exit_liveness, loop_var_classifier)

3. Stage-1 CLI enhancements
   - Extended args.rs, groups.rs, mod.rs for new options
   - Improved stage1_bridge module (args, env, mod)
   - Updated stage1_cli.hako

4. MIR builder cleanup
   - Simplified if_form.rs control flow
   - Removed dead code from loop_builder.rs
   - Enhanced phi_merge.rs

5. Runner module updates
   - json_v0_bridge/lowering.rs improvements
   - dispatch.rs, selfhost.rs, modes/vm.rs cleanup

6. Documentation updates
   - CURRENT_TASK.md, AGENTS.md
   - Various docs/ updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-26 10:17:37 +09:00
parent 7d0581c9a4
commit 51ff558904
36 changed files with 474 additions and 361 deletions

View File

@ -49,6 +49,11 @@ pub fn build_command() -> Command {
.arg(Arg::new("json-file").long("json-file").value_name("FILE").help("Read Ny JSON IR v0 from a file and execute via MIR Interpreter"))
.arg(Arg::new("mir-json-file").long("mir-json-file").value_name("FILE").help("[Diagnostic] Read MIR JSON v0 from a file and perform minimal validation/inspection (experimental)") )
.arg(Arg::new("emit-mir-json").long("emit-mir-json").value_name("FILE").help("Emit MIR JSON v0 to file and exit"))
.arg(Arg::new("emit-program-json").long("emit-program-json").value_name("FILE").help("Emit Program(JSON v0) to file and exit (AST direct; no Stage-1 stub)"))
.arg(Arg::new("hako-emit-program-json").long("hako-emit-program-json").value_name("FILE").help("Emit Program(JSON v0) via Stage-1 (.hako) stub and exit"))
.arg(Arg::new("hako-emit-mir-json").long("hako-emit-mir-json").value_name("FILE").help("Emit MIR(JSON) via Stage-1 (.hako) stub (json_v0_bridge path)"))
.arg(Arg::new("hako-run").long("hako-run").help("Run via Stage-1 (.hako) stub (equivalent to NYASH_USE_STAGE1_CLI=1)").action(clap::ArgAction::SetTrue))
.arg(Arg::new("emit-program-json").long("emit-program-json").value_name("FILE").help("Emit Program(JSON v0) to file and exit (AST direct)"))
.arg(Arg::new("program-json-to-mir").long("program-json-to-mir").value_name("FILE").help("Convert Program(JSON v0) to MIR(JSON) and exit (use with --json-file)"))
.arg(Arg::new("emit-exe").long("emit-exe").value_name("FILE").help("Emit native executable via ny-llvmc and exit"))
.arg(Arg::new("emit-exe-nyrt").long("emit-exe-nyrt").value_name("DIR").help("Directory containing libnyash_kernel.a (used with --emit-exe)"))
@ -121,6 +126,8 @@ pub fn from_matches(matches: &ArgMatches) -> CliConfig {
if let Some(a) = matches.get_one::<String>("ny-compiler-args") {
std::env::set_var("NYASH_NY_COMPILER_CHILD_ARGS", a);
}
let hako_emit_program_path = matches.get_one::<String>("hako-emit-program-json").cloned();
let hako_emit_mir_path = matches.get_one::<String>("hako-emit-mir-json").cloned();
let cfg = CliConfig {
file: matches.get_one::<String>("file").cloned(),
debug_fuel: parse_debug_fuel(matches.get_one::<String>("debug-fuel").unwrap()),
@ -182,7 +189,17 @@ pub fn from_matches(matches: &ArgMatches) -> CliConfig {
.get_many::<String>("using")
.map(|v| v.cloned().collect())
.unwrap_or_else(|| Vec::new()),
emit_mir_json: matches.get_one::<String>("emit-mir-json").cloned(),
emit_mir_json: matches
.get_one::<String>("emit-mir-json")
.cloned()
.or(hako_emit_mir_path.clone()),
emit_program_json: matches
.get_one::<String>("emit-program-json")
.cloned()
.or(hako_emit_program_path.clone()),
hako_emit_program_json: hako_emit_program_path.is_some(),
hako_emit_mir_json: hako_emit_mir_path.is_some(),
hako_run: matches.get_flag("hako-run"),
program_json_to_mir: matches.get_one::<String>("program-json-to-mir").cloned(),
emit_exe: matches.get_one::<String>("emit-exe").cloned(),
emit_exe_nyrt: matches.get_one::<String>("emit-exe-nyrt").cloned(),
@ -201,6 +218,35 @@ pub fn from_matches(matches: &ArgMatches) -> CliConfig {
if cfg.vm_stats_json {
std::env::set_var("NYASH_VM_STATS_JSON", "1");
}
// hako-prefixed Stage-1 stub routes
if cfg.hako_emit_program_json {
std::env::set_var("NYASH_USE_STAGE1_CLI", "1");
std::env::set_var("HAKO_STAGE1_MODE", "emit-program");
std::env::set_var("HAKO_EMIT_PROGRAM_JSON", "1");
std::env::set_var("STAGE1_EMIT_PROGRAM_JSON", "1");
if let Some(f) = cfg.file.as_ref() {
std::env::set_var("HAKO_STAGE1_INPUT", f);
std::env::set_var("NYASH_STAGE1_INPUT", f);
}
}
if cfg.hako_emit_mir_json {
std::env::set_var("NYASH_USE_STAGE1_CLI", "1");
std::env::set_var("HAKO_STAGE1_MODE", "emit-mir");
std::env::set_var("HAKO_EMIT_MIR_JSON", "1");
std::env::set_var("STAGE1_EMIT_MIR_JSON", "1");
if let Some(f) = cfg.file.as_ref() {
std::env::set_var("HAKO_STAGE1_INPUT", f);
std::env::set_var("NYASH_STAGE1_INPUT", f);
}
}
if cfg.hako_run {
std::env::set_var("NYASH_USE_STAGE1_CLI", "1");
std::env::set_var("HAKO_STAGE1_MODE", "run");
if let Some(f) = cfg.file.as_ref() {
std::env::set_var("HAKO_STAGE1_INPUT", f);
std::env::set_var("NYASH_STAGE1_INPUT", f);
}
}
if cfg.jit_exec {
std::env::set_var("NYASH_JIT_EXEC", "1");
}

View File

@ -57,6 +57,10 @@ pub struct BuildConfig {
pub struct EmitConfig {
pub emit_cfg: Option<String>,
pub emit_mir_json: Option<String>,
pub emit_program_json: Option<String>,
pub hako_emit_program_json: bool,
pub hako_emit_mir_json: bool,
pub hako_run: bool,
pub program_json_to_mir: Option<String>,
pub emit_exe: Option<String>,
pub emit_exe_nyrt: Option<String>,

View File

@ -43,6 +43,7 @@ pub struct CliConfig {
pub jit_only: bool,
pub jit_direct: bool,
pub emit_cfg: Option<String>,
pub emit_program_json: Option<String>,
pub cli_verbose: bool,
pub run_task: Option<String>,
pub load_ny_plugins: bool,
@ -59,6 +60,9 @@ pub struct CliConfig {
pub build_target: Option<String>,
pub cli_usings: Vec<String>,
pub emit_mir_json: Option<String>,
pub hako_emit_program_json: bool,
pub hako_emit_mir_json: bool,
pub hako_run: bool,
pub program_json_to_mir: Option<String>,
pub emit_exe: Option<String>,
pub emit_exe_nyrt: Option<String>,
@ -127,6 +131,10 @@ impl CliConfig {
emit: EmitConfig {
emit_cfg: self.emit_cfg.clone(),
emit_mir_json: self.emit_mir_json.clone(),
emit_program_json: self.emit_program_json.clone(),
hako_emit_program_json: self.hako_emit_program_json,
hako_emit_mir_json: self.hako_emit_mir_json,
hako_run: self.hako_run,
program_json_to_mir: self.program_json_to_mir.clone(),
emit_exe: self.emit_exe.clone(),
emit_exe_nyrt: self.emit_exe_nyrt.clone(),
@ -184,6 +192,7 @@ impl Default for CliConfig {
jit_native_f64: false,
jit_native_bool: false,
emit_cfg: None,
emit_program_json: None,
jit_only: false,
jit_direct: false,
cli_verbose: false,
@ -202,6 +211,9 @@ impl Default for CliConfig {
build_target: None,
cli_usings: Vec::new(),
emit_mir_json: None,
hako_emit_program_json: false,
hako_emit_mir_json: false,
hako_run: false,
program_json_to_mir: None,
emit_exe: None,
emit_exe_nyrt: None,