2025-11-21 06:25:17 +09:00
use super ::utils ::parse_debug_fuel ;
use super ::CliConfig ;
2025-09-22 07:54:25 +09:00
use clap ::{ Arg , ArgMatches , Command } ;
use serde_json ;
pub fn parse ( ) -> CliConfig {
let argv : Vec < String > = std ::env ::args ( ) . collect ( ) ;
if let Some ( pos ) = argv . iter ( ) . position ( | s | s = = " -- " ) {
let script_args : Vec < String > = argv . iter ( ) . skip ( pos + 1 ) . cloned ( ) . collect ( ) ;
if ! script_args . is_empty ( ) {
if let Ok ( json ) = serde_json ::to_string ( & script_args ) {
std ::env ::set_var ( " NYASH_SCRIPT_ARGS_JSON " , json ) ;
}
2025-11-08 15:49:25 +09:00
// Provide HEX-escaped JSON as an alternate robust path for multiline/special bytes
// Each arg is encoded as lowercase hex of its UTF-8 bytes
2025-11-21 06:25:17 +09:00
let hex_args : Vec < String > = script_args . iter ( ) . map ( | s | hex_encode_utf8 ( s ) ) . collect ( ) ;
2025-11-08 15:49:25 +09:00
if let Ok ( hex_json ) = serde_json ::to_string ( & hex_args ) {
std ::env ::set_var ( " NYASH_SCRIPT_ARGS_HEX_JSON " , hex_json ) ;
}
2025-09-22 07:54:25 +09:00
}
let matches = build_command ( )
. try_get_matches_from ( & argv [ .. pos ] )
. unwrap_or_else ( | e | e . exit ( ) ) ;
from_matches ( & matches )
} else {
let matches = build_command ( ) . get_matches ( ) ;
from_matches ( & matches )
}
}
pub fn build_command ( ) -> Command {
Command ::new ( " nyash " )
. version ( " 1.0 " )
. author ( " Claude Code <claude@anthropic.com> " )
. about ( " 🦀 Nyash Programming Language - Everything is Box in Rust! 🦀 " )
2025-09-27 08:45:25 +09:00
. arg ( Arg ::new ( " dev " ) . long ( " dev " ) . help ( " Enable development defaults (AST using ON; Operator Boxes observe; safe diagnostics) " ) . action ( clap ::ArgAction ::SetTrue ) )
2025-09-22 07:54:25 +09:00
. arg ( Arg ::new ( " file " ) . help ( " Nyash file to execute " ) . value_name ( " FILE " ) . index ( 1 ) )
. arg ( Arg ::new ( " macro-expand-child " ) . long ( " macro-expand-child " ) . value_name ( " FILE " ) . help ( " Macro sandbox child: read AST JSON v0 from stdin, expand using Nyash macro file, write AST JSON v0 to stdout (PoC) " ) )
. arg ( Arg ::new ( " dump-ast " ) . long ( " dump-ast " ) . help ( " Dump parsed AST and exit " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " macro-preexpand " ) . long ( " macro-preexpand " ) . help ( " Enable selfhost macro pre-expand " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " macro-preexpand-auto " ) . long ( " macro-preexpand-auto " ) . help ( " Auto enable selfhost macro pre-expand " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " macro-top-level-allow " ) . long ( " macro-top-level-allow " ) . help ( " Allow top-level macro usage " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " macro-profile " ) . long ( " macro-profile " ) . value_name ( " {dev|ci-fast|strict} " ) . help ( " Select macro profile " ) )
. arg ( Arg ::new ( " dump-expanded-ast-json " ) . long ( " dump-expanded-ast-json " ) . help ( " Dump AST after macro expansion as JSON v0 and exit " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " macro-ctx-json " ) . long ( " macro-ctx-json " ) . value_name ( " JSON " ) . help ( " Provide MacroCtx as JSON string for macro child routes " ) )
. arg ( Arg ::new ( " gc " ) . long ( " gc " ) . value_name ( " {auto,rc+cycle,minorgen,stw,rc,off} " ) . help ( " Select GC mode (default: rc+cycle) " ) )
. arg ( Arg ::new ( " parser " ) . long ( " parser " ) . value_name ( " {rust|ny} " ) . help ( " Choose parser: 'rust' (default) or 'ny' (direct v0 bridge) " ) )
. arg ( Arg ::new ( " ny-parser-pipe " ) . long ( " ny-parser-pipe " ) . help ( " Read Ny JSON IR v0 from stdin and execute via MIR Interpreter " ) . action ( clap ::ArgAction ::SetTrue ) )
. 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 " ) )
2025-11-03 23:21:48 +09:00
. 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) " ) )
2025-09-22 07:54:25 +09:00
. arg ( Arg ::new ( " emit-mir-json " ) . long ( " emit-mir-json " ) . value_name ( " FILE " ) . help ( " Emit MIR JSON v0 to file and exit " ) )
2025-11-26 10:17:37 +09:00
. 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 ) )
2025-11-02 18:54:16 +09:00
. 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) " ) )
2025-09-22 07:54:25 +09:00
. arg ( Arg ::new ( " emit-exe " ) . long ( " emit-exe " ) . value_name ( " FILE " ) . help ( " Emit native executable via ny-llvmc and exit " ) )
2025-12-22 14:48:37 +09:00
. arg ( Arg ::new ( " emit-exe-nyrt " ) . long ( " emit-exe-nyrt " ) . value_name ( " DIR " ) . help ( " Directory containing libnyash_kernel.a (used with --emit-exe). Hint: build via `cargo build -p nyash_kernel --release` (default output: target/release/libnyash_kernel.a) " ) )
2025-09-22 07:54:25 +09:00
. arg ( Arg ::new ( " emit-exe-libs " ) . long ( " emit-exe-libs " ) . value_name ( " FLAGS " ) . help ( " Extra linker flags for ny-llvmc when emitting executable " ) )
. arg ( Arg ::new ( " stage3 " ) . long ( " stage3 " ) . help ( " Enable Stage-3 syntax acceptance for selfhost parser " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " ny-compiler-args " ) . long ( " ny-compiler-args " ) . value_name ( " ARGS " ) . help ( " Pass additional args to selfhost child compiler " ) )
. arg ( Arg ::new ( " using " ) . long ( " using " ) . value_name ( " NAME " ) . help ( " Add a using directive to current session; repeat " ) . action ( clap ::ArgAction ::Append ) )
. arg ( Arg ::new ( " debug-fuel " ) . long ( " debug-fuel " ) . value_name ( " N|unlimited " ) . help ( " Limit interpreter/JIT steps or 'unlimited' (default 100000) " ) . default_value ( " 100000 " ) )
. arg ( Arg ::new ( " run-tests " ) . long ( " run-tests " ) . help ( " Run inline tests in the module (functions starting with 'test_') " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " test-filter " ) . long ( " test-filter " ) . value_name ( " SUBSTR " ) . help ( " Only run tests whose name contains SUBSTR (with --run-tests) " ) )
. arg ( Arg ::new ( " test-entry " ) . long ( " test-entry " ) . value_name ( " {wrap|override} " ) . help ( " When --run-tests and a main exists: wrap or override " ) )
. arg ( Arg ::new ( " test-return " ) . long ( " test-return " ) . value_name ( " {tests|original} " ) . help ( " Harness return policy (tests or original) " ) )
. arg ( Arg ::new ( " dump-mir " ) . long ( " dump-mir " ) . help ( " Dump MIR instead of executing " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " verify " ) . long ( " verify " ) . help ( " Verify MIR integrity and exit " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " mir-verbose " ) . long ( " mir-verbose " ) . help ( " Show verbose MIR output with statistics " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " mir-verbose-effects " ) . long ( " mir-verbose-effects " ) . help ( " Show per-instruction effect category " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " no-optimize " ) . long ( " no-optimize " ) . help ( " Disable MIR optimizer passes " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " backend " ) . long ( " backend " ) . value_name ( " BACKEND " ) . help ( " Backend: vm (default), llvm, interpreter " ) . default_value ( " vm " ) )
. arg ( Arg ::new ( " verbose " ) . long ( " verbose " ) . short ( 'v' ) . help ( " Verbose CLI output (sets NYASH_CLI_VERBOSE=1) " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " compile-wasm " ) . long ( " compile-wasm " ) . help ( " Compile to WebAssembly " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " compile-native " ) . long ( " compile-native " ) . help ( " Compile to native executable (AOT) " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " aot " ) . long ( " aot " ) . help ( " Short form of --compile-native " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " output " ) . long ( " output " ) . short ( 'o' ) . value_name ( " FILE " ) . help ( " Output file for compilation " ) )
. arg ( Arg ::new ( " benchmark " ) . long ( " benchmark " ) . help ( " Run performance benchmarks " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " iterations " ) . long ( " iterations " ) . value_name ( " COUNT " ) . help ( " Iterations for benchmarks " ) . default_value ( " 10 " ) )
. arg ( Arg ::new ( " vm-stats " ) . long ( " vm-stats " ) . help ( " Enable VM instruction statistics " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " vm-stats-json " ) . long ( " vm-stats-json " ) . help ( " Output VM statistics in JSON " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-exec " ) . long ( " jit-exec " ) . help ( " Enable JIT execution " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-stats " ) . long ( " jit-stats " ) . help ( " Print JIT statistics " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-stats-json " ) . long ( " jit-stats-json " ) . help ( " Output JIT stats in JSON " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-dump " ) . long ( " jit-dump " ) . help ( " Dump JIT lowering summary " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-events " ) . long ( " jit-events " ) . help ( " Emit JIT events JSONL " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-events-compile " ) . long ( " jit-events-compile " ) . help ( " Emit compile-time JIT events " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-events-runtime " ) . long ( " jit-events-runtime " ) . help ( " Emit runtime JIT events " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-events-path " ) . long ( " jit-events-path " ) . value_name ( " FILE " ) . help ( " Write JIT events JSONL to file " ) )
. arg ( Arg ::new ( " jit-threshold " ) . long ( " jit-threshold " ) . value_name ( " N " ) . help ( " Hotness threshold for JIT compilation " ) )
. arg ( Arg ::new ( " jit-phi-min " ) . long ( " jit-phi-min " ) . help ( " Minimal PHI path for branches " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-hostcall " ) . long ( " jit-hostcall " ) . help ( " Enable JIT hostcall bridge " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-handle-debug " ) . long ( " jit-handle-debug " ) . help ( " Print JIT handle allocation debug logs " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-native-f64 " ) . long ( " jit-native-f64 " ) . help ( " Enable native f64 ABI path " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-native-bool " ) . long ( " jit-native-bool " ) . help ( " Enable native bool ABI path " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-only " ) . long ( " jit-only " ) . help ( " Run JIT only (no VM fallback) " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " jit-direct " ) . long ( " jit-direct " ) . help ( " Independent JIT engine mode " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " emit-cfg " ) . long ( " emit-cfg " ) . value_name ( " DOT_FILE " ) . help ( " Emit JIT CFG as DOT " ) )
. arg ( Arg ::new ( " run-task " ) . long ( " run-task " ) . value_name ( " NAME " ) . help ( " Run a named task from nyash.toml " ) )
. arg ( Arg ::new ( " load-ny-plugins " ) . long ( " load-ny-plugins " ) . help ( " Load scripts from nyash.toml [ny_plugins] " ) . action ( clap ::ArgAction ::SetTrue ) )
. arg ( Arg ::new ( " build " ) . long ( " build " ) . value_name ( " PATH " ) . help ( " Build AOT executable using nyash.toml at PATH (MVP) " ) )
. arg ( Arg ::new ( " build-app " ) . long ( " app " ) . value_name ( " FILE " ) . help ( " Entry Nyash script for --build " ) )
. arg ( Arg ::new ( " build-out " ) . long ( " out " ) . value_name ( " FILE " ) . help ( " Output executable name for --build " ) )
. arg ( Arg ::new ( " build-aot " ) . long ( " build-aot " ) . value_name ( " {cranelift|llvm} " ) . help ( " AOT backend for --build " ) )
. arg ( Arg ::new ( " build-profile " ) . long ( " profile " ) . value_name ( " {release|debug} " ) . help ( " Cargo profile for --build " ) )
. arg ( Arg ::new ( " build-target " ) . long ( " target " ) . value_name ( " TRIPLE " ) . help ( " Target triple for --build " ) )
}
2025-11-08 15:49:25 +09:00
fn hex_encode_utf8 ( s : & str ) -> String {
let bytes = s . as_bytes ( ) ;
let mut out = String ::with_capacity ( bytes . len ( ) * 2 ) ;
const HEX : & [ u8 ; 16 ] = b " 0123456789abcdef " ;
for & b in bytes {
out . push ( HEX [ ( b > > 4 ) as usize ] as char ) ;
out . push ( HEX [ ( b & 0x0f ) as usize ] as char ) ;
}
out
}
2025-09-22 07:54:25 +09:00
pub fn from_matches ( matches : & ArgMatches ) -> CliConfig {
2025-11-21 06:25:17 +09:00
if matches . get_flag ( " stage3 " ) {
std ::env ::set_var ( " NYASH_NY_COMPILER_STAGE3 " , " 1 " ) ;
}
if let Some ( a ) = matches . get_one ::< String > ( " ny-compiler-args " ) {
std ::env ::set_var ( " NYASH_NY_COMPILER_CHILD_ARGS " , a ) ;
}
2025-11-26 10:17:37 +09:00
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 ( ) ;
2025-09-22 07:54:25 +09:00
let cfg = CliConfig {
file : matches . get_one ::< String > ( " file " ) . cloned ( ) ,
debug_fuel : parse_debug_fuel ( matches . get_one ::< String > ( " debug-fuel " ) . unwrap ( ) ) ,
dump_ast : matches . get_flag ( " dump-ast " ) ,
dump_mir : matches . get_flag ( " dump-mir " ) ,
verify_mir : matches . get_flag ( " verify " ) ,
mir_verbose : matches . get_flag ( " mir-verbose " ) ,
mir_verbose_effects : matches . get_flag ( " mir-verbose-effects " ) ,
no_optimize : matches . get_flag ( " no-optimize " ) ,
backend : matches . get_one ::< String > ( " backend " ) . unwrap ( ) . clone ( ) ,
compile_wasm : matches . get_flag ( " compile-wasm " ) ,
compile_native : matches . get_flag ( " compile-native " ) | | matches . get_flag ( " aot " ) ,
output_file : matches . get_one ::< String > ( " output " ) . cloned ( ) ,
benchmark : matches . get_flag ( " benchmark " ) ,
2025-11-21 06:25:17 +09:00
iterations : matches
. get_one ::< String > ( " iterations " )
. unwrap ( )
. parse ( )
. unwrap_or ( 10 ) ,
2025-09-22 07:54:25 +09:00
vm_stats : matches . get_flag ( " vm-stats " ) ,
vm_stats_json : matches . get_flag ( " vm-stats-json " ) ,
jit_exec : matches . get_flag ( " jit-exec " ) ,
jit_stats : matches . get_flag ( " jit-stats " ) ,
jit_stats_json : matches . get_flag ( " jit-stats-json " ) ,
jit_dump : matches . get_flag ( " jit-dump " ) ,
jit_events : matches . get_flag ( " jit-events " ) ,
jit_events_compile : matches . get_flag ( " jit-events-compile " ) ,
jit_events_runtime : matches . get_flag ( " jit-events-runtime " ) ,
jit_events_path : matches . get_one ::< String > ( " jit-events-path " ) . cloned ( ) ,
2025-11-21 06:25:17 +09:00
jit_threshold : matches
. get_one ::< String > ( " jit-threshold " )
. and_then ( | s | s . parse ::< u32 > ( ) . ok ( ) ) ,
2025-09-22 07:54:25 +09:00
jit_phi_min : matches . get_flag ( " jit-phi-min " ) ,
jit_hostcall : matches . get_flag ( " jit-hostcall " ) ,
jit_handle_debug : matches . get_flag ( " jit-handle-debug " ) ,
jit_native_f64 : matches . get_flag ( " jit-native-f64 " ) ,
jit_native_bool : matches . get_flag ( " jit-native-bool " ) ,
emit_cfg : matches . get_one ::< String > ( " emit-cfg " ) . cloned ( ) ,
jit_only : matches . get_flag ( " jit-only " ) ,
jit_direct : matches . get_flag ( " jit-direct " ) ,
cli_verbose : matches . get_flag ( " verbose " ) ,
run_task : matches . get_one ::< String > ( " run-task " ) . cloned ( ) ,
load_ny_plugins : matches . get_flag ( " load-ny-plugins " ) ,
gc_mode : matches . get_one ::< String > ( " gc " ) . cloned ( ) ,
2025-11-21 06:25:17 +09:00
parser_ny : matches
. get_one ::< String > ( " parser " )
. map ( | s | s = = " ny " )
. unwrap_or ( false ) ,
2025-09-22 07:54:25 +09:00
ny_parser_pipe : matches . get_flag ( " ny-parser-pipe " ) ,
json_file : matches . get_one ::< String > ( " json-file " ) . cloned ( ) ,
2025-11-03 23:21:48 +09:00
mir_json_file : matches . get_one ::< String > ( " mir-json-file " ) . cloned ( ) ,
2025-09-22 07:54:25 +09:00
build_path : matches . get_one ::< String > ( " build " ) . cloned ( ) ,
build_app : matches . get_one ::< String > ( " build-app " ) . cloned ( ) ,
build_out : matches . get_one ::< String > ( " build-out " ) . cloned ( ) ,
build_aot : matches . get_one ::< String > ( " build-aot " ) . cloned ( ) ,
build_profile : matches . get_one ::< String > ( " build-profile " ) . cloned ( ) ,
build_target : matches . get_one ::< String > ( " build-target " ) . cloned ( ) ,
2025-11-21 06:25:17 +09:00
cli_usings : matches
. get_many ::< String > ( " using " )
. map ( | v | v . cloned ( ) . collect ( ) )
. unwrap_or_else ( | | Vec ::new ( ) ) ,
2025-11-26 10:17:37 +09:00
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 " ) ,
2025-11-02 18:54:16 +09:00
program_json_to_mir : matches . get_one ::< String > ( " program-json-to-mir " ) . cloned ( ) ,
2025-09-22 07:54:25 +09:00
emit_exe : matches . get_one ::< String > ( " emit-exe " ) . cloned ( ) ,
emit_exe_nyrt : matches . get_one ::< String > ( " emit-exe-nyrt " ) . cloned ( ) ,
emit_exe_libs : matches . get_one ::< String > ( " emit-exe-libs " ) . cloned ( ) ,
macro_expand_child : matches . get_one ::< String > ( " macro-expand-child " ) . cloned ( ) ,
dump_expanded_ast_json : matches . get_flag ( " dump-expanded-ast-json " ) ,
macro_ctx_json : matches . get_one ::< String > ( " macro-ctx-json " ) . cloned ( ) ,
} ;
2025-11-21 06:25:17 +09:00
if cfg . cli_verbose {
std ::env ::set_var ( " NYASH_CLI_VERBOSE " , " 1 " ) ;
}
if cfg . vm_stats {
std ::env ::set_var ( " NYASH_VM_STATS " , " 1 " ) ;
}
if cfg . vm_stats_json {
std ::env ::set_var ( " NYASH_VM_STATS_JSON " , " 1 " ) ;
}
2025-11-26 10:17:37 +09:00
// 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 ) ;
}
}
2025-11-21 06:25:17 +09:00
if cfg . jit_exec {
std ::env ::set_var ( " NYASH_JIT_EXEC " , " 1 " ) ;
}
if cfg . jit_stats {
std ::env ::set_var ( " NYASH_JIT_STATS " , " 1 " ) ;
}
if cfg . jit_stats_json {
std ::env ::set_var ( " NYASH_JIT_STATS_JSON " , " 1 " ) ;
}
if cfg . jit_dump {
std ::env ::set_var ( " NYASH_JIT_DUMP " , " 1 " ) ;
}
if cfg . jit_events {
std ::env ::set_var ( " NYASH_JIT_EVENTS " , " 1 " ) ;
}
if cfg . jit_events_compile {
std ::env ::set_var ( " NYASH_JIT_EVENTS_COMPILE " , " 1 " ) ;
}
if cfg . jit_events_runtime {
std ::env ::set_var ( " NYASH_JIT_EVENTS_RUNTIME " , " 1 " ) ;
}
if let Some ( p ) = & cfg . jit_events_path {
std ::env ::set_var ( " NYASH_JIT_EVENTS_PATH " , p ) ;
}
if let Some ( t ) = cfg . jit_threshold {
std ::env ::set_var ( " NYASH_JIT_THRESHOLD " , t . to_string ( ) ) ;
}
if cfg . jit_phi_min {
std ::env ::set_var ( " NYASH_JIT_PHI_MIN " , " 1 " ) ;
}
if cfg . jit_hostcall {
std ::env ::set_var ( " NYASH_JIT_HOSTCALL " , " 1 " ) ;
}
if cfg . jit_handle_debug {
std ::env ::set_var ( " NYASH_JIT_HANDLE_DEBUG " , " 1 " ) ;
}
if cfg . jit_native_f64 {
std ::env ::set_var ( " NYASH_JIT_NATIVE_F64 " , " 1 " ) ;
}
if cfg . jit_native_bool {
std ::env ::set_var ( " NYASH_JIT_NATIVE_BOOL " , " 1 " ) ;
}
if cfg . jit_only {
std ::env ::set_var ( " NYASH_JIT_ONLY " , " 1 " ) ;
}
if cfg . jit_direct {
std ::env ::set_var ( " NYASH_JIT_DIRECT " , " 1 " ) ;
}
if let Some ( gc ) = & cfg . gc_mode {
std ::env ::set_var ( " NYASH_GC_MODE " , gc ) ;
}
2025-09-22 07:54:25 +09:00
if matches . get_flag ( " run-tests " ) {
std ::env ::set_var ( " NYASH_RUN_TESTS " , " 1 " ) ;
2025-11-21 06:25:17 +09:00
if let Some ( filter ) = matches . get_one ::< String > ( " test-filter " ) {
std ::env ::set_var ( " NYASH_TEST_FILTER " , filter ) ;
}
2025-09-22 07:54:25 +09:00
if let Some ( entry ) = matches . get_one ::< String > ( " test-entry " ) {
let v = entry . as_str ( ) ;
2025-11-21 06:25:17 +09:00
if v = = " wrap " | | v = = " override " {
std ::env ::set_var ( " NYASH_TEST_ENTRY " , v ) ;
}
2025-09-22 07:54:25 +09:00
}
if let Some ( ret ) = matches . get_one ::< String > ( " test-return " ) {
let v = ret . as_str ( ) ;
2025-11-21 06:25:17 +09:00
if v = = " tests " | | v = = " original " {
std ::env ::set_var ( " NYASH_TEST_RETURN " , v ) ;
}
2025-09-22 07:54:25 +09:00
}
}
2025-11-21 06:25:17 +09:00
if matches . get_flag ( " macro-preexpand " ) {
std ::env ::set_var ( " NYASH_MACRO_SELFHOST_PRE_EXPAND " , " 1 " ) ;
}
if matches . get_flag ( " macro-preexpand-auto " ) {
std ::env ::set_var ( " NYASH_MACRO_SELFHOST_PRE_EXPAND " , " auto " ) ;
}
if matches . get_flag ( " macro-top-level-allow " ) {
std ::env ::set_var ( " NYASH_MACRO_TOPLEVEL_ALLOW " , " 1 " ) ;
}
2025-09-22 07:54:25 +09:00
if let Some ( p ) = matches . get_one ::< String > ( " macro-profile " ) {
match p . as_str ( ) {
" dev " | " ci-fast " | " strict " = > {
std ::env ::set_var ( " NYASH_MACRO_ENABLE " , " 1 " ) ;
std ::env ::set_var ( " NYASH_MACRO_STRICT " , " 1 " ) ;
std ::env ::set_var ( " NYASH_MACRO_TOPLEVEL_ALLOW " , " 0 " ) ;
std ::env ::set_var ( " NYASH_MACRO_SELFHOST_PRE_EXPAND " , " auto " ) ;
}
_ = > { }
}
}
2025-09-27 08:45:25 +09:00
// --dev flag (or NYASH_DEV=1) enables safe development defaults
// - AST using ON (NYASH_USING_AST=1)
// - Operator Boxes observe ON (Stringify/Compare/Add) and prelude injection (NYASH_OPERATOR_BOX_ALL=1)
// (Adopt is OFF by default; builder-call OFF)
// - Keep production behavior otherwise (no plugin/trace changes here)
if matches . get_flag ( " dev " ) | | std ::env ::var ( " NYASH_DEV " ) . ok ( ) . as_deref ( ) = = Some ( " 1 " ) {
// Profile hint
std ::env ::set_var ( " NYASH_USING_PROFILE " , " dev " ) ;
// AST prelude merge
std ::env ::set_var ( " NYASH_USING_AST " , " 1 " ) ;
2025-09-28 01:33:58 +09:00
// Using grammar is mainline; keep explicit enable for clarity (default is ON; this makes intent obvious in dev)
std ::env ::set_var ( " NYASH_ENABLE_USING " , " 1 " ) ;
// Allow top-level main resolution in dev for convenience (prod default remains OFF)
std ::env ::set_var ( " NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN " , " 1 " ) ;
2025-09-27 08:45:25 +09:00
// Ensure project root is available for prelude injection
if std ::env ::var ( " NYASH_ROOT " ) . is_err ( ) {
if let Ok ( cwd ) = std ::env ::current_dir ( ) {
std ::env ::set_var ( " NYASH_ROOT " , cwd . display ( ) . to_string ( ) ) ;
}
}
// Operator Boxes: observe + prelude injection
std ::env ::set_var ( " NYASH_OPERATOR_BOX_ALL " , " 1 " ) ;
std ::env ::set_var ( " NYASH_OPERATOR_BOX_STRINGIFY " , " 1 " ) ;
std ::env ::set_var ( " NYASH_OPERATOR_BOX_COMPARE " , " 1 " ) ;
std ::env ::set_var ( " NYASH_OPERATOR_BOX_ADD " , " 1 " ) ;
// Adopt selected operators in dev for parity with observe path
std ::env ::set_var ( " NYASH_OPERATOR_BOX_COMPARE_ADOPT " , " 1 " ) ;
std ::env ::set_var ( " NYASH_OPERATOR_BOX_ADD_ADOPT " , " 1 " ) ;
// VM: tolerate Void/BoxRef(VoidBox) in comparisons/binops (dev-only guard)
std ::env ::set_var ( " NYASH_VM_TOLERATE_VOID " , " 1 " ) ;
// Builder-call ALL is still OFF here to keep MIR shape stable.
}
2025-09-22 07:54:25 +09:00
cfg
}