chore: stop ignoring src/config/env

This commit is contained in:
2025-12-28 13:55:04 +09:00
parent 5757eb740e
commit df7f63f3c0
9 changed files with 864 additions and 1 deletions

2
.gitignore vendored
View File

@ -4,7 +4,7 @@ __pycache__/
*$py.class
*.so
.Python
env/
/env/
venv/
.venv/
pip-log.txt

27
src/config/env/dump.rs vendored Normal file
View File

@ -0,0 +1,27 @@
//! Dump / diagnostics env helpers.
/// Optional dump path for MIR printer output (JSON v0 route only).
pub fn rust_mir_dump_path() -> Option<String> {
std::env::var("RUST_MIR_DUMP_PATH")
.ok()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
}
/// CLI verbose level (0=quiet, 1=verbose, 2=trace).
pub fn cli_verbose_level() -> u8 {
match std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() {
Some("2") => 2,
Some("1") => 1,
_ => 0,
}
}
/// Leak report level (0=off, 1=summary, 2=verbose).
pub fn leak_log_level() -> u8 {
match std::env::var("NYASH_LEAK_LOG").ok().as_deref() {
Some("2") => 2,
Some("1") => 1,
_ => 0,
}
}

227
src/config/env/mir_flags.rs vendored Normal file
View File

@ -0,0 +1,227 @@
//! MIR-related environment flags
//!
//! This module groups all MIR feature flags and environment variable controls.
//! Use this for IDE autocomplete to discover MIR flags easily.
use super::env_bool;
// ---- MIR PHI / PHI-less (edge-copy) mode ----
/// Enable MIR PHI non-generation for Bridge compatibility mode only.
/// フェーズM.2: MirBuilder/LoopBuilderでPHI統一済み、Bridge層の互換性制御のみ
/// Default: PHI-ON (Phase 15 direction), override with NYASH_MIR_NO_PHI=1
pub fn mir_no_phi() -> bool {
env_bool("NYASH_MIR_NO_PHI")
}
// ---- Phase 11.8 MIR cleanup toggles ----
/// Core-13 minimal MIR mode toggle. Default ON unless NYASH_MIR_CORE13=0.
pub fn mir_core13() -> bool {
match std::env::var("NYASH_MIR_CORE13").ok() {
Some(v) => {
let lv = v.to_ascii_lowercase();
!(lv == "0" || lv == "false" || lv == "off")
}
None => true,
}
}
pub fn mir_ref_boxcall() -> bool {
std::env::var("NYASH_MIR_REF_BOXCALL").ok().as_deref() == Some("1") || mir_core13()
}
pub fn mir_array_boxcall() -> bool {
std::env::var("NYASH_MIR_ARRAY_BOXCALL").ok().as_deref() == Some("1") || mir_core13()
}
pub fn mir_plugin_invoke() -> bool {
std::env::var("NYASH_MIR_PLUGIN_INVOKE").ok().as_deref() == Some("1")
}
pub fn plugin_only() -> bool {
std::env::var("NYASH_PLUGIN_ONLY").ok().as_deref() == Some("1")
}
/// Core-13 "pure" mode: only the 13 canonical ops are allowed (verifier rejects others).
pub fn mir_core13_pure() -> bool {
env_bool("NYASH_MIR_CORE13_PURE")
}
// ---- Optimizer diagnostics ----
pub fn opt_debug() -> bool {
std::env::var("NYASH_OPT_DEBUG").is_ok()
}
pub fn opt_diag() -> bool {
std::env::var("NYASH_OPT_DIAG").is_ok()
}
pub fn opt_diag_forbid_legacy() -> bool {
std::env::var("NYASH_OPT_DIAG_FORBID_LEGACY").is_ok()
}
pub fn opt_diag_fail() -> bool {
std::env::var("NYASH_OPT_DIAG_FAIL").is_ok()
}
// ---- Rewriter flags (optimizer transforms)
pub fn rewrite_debug() -> bool {
std::env::var("NYASH_REWRITE_DEBUG").ok().as_deref() == Some("1")
}
pub fn rewrite_safepoint() -> bool {
std::env::var("NYASH_REWRITE_SAFEPOINT").ok().as_deref() == Some("1")
}
pub fn rewrite_future() -> bool {
std::env::var("NYASH_REWRITE_FUTURE").ok().as_deref() == Some("1")
}
// ---- Operator Boxes adopt defaults ----
/// CompareOperator.apply adopt: default ON (prod/devともに採用)
pub fn operator_box_compare_adopt() -> bool {
match std::env::var("NYASH_OPERATOR_BOX_COMPARE_ADOPT")
.ok()
.as_deref()
.map(|v| v.to_ascii_lowercase())
{
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
_ => true, // default ON
}
}
/// AddOperator.apply adopt: default OFF順次昇格のため
pub fn operator_box_add_adopt() -> bool {
match std::env::var("NYASH_OPERATOR_BOX_ADD_ADOPT")
.ok()
.as_deref()
.map(|v| v.to_ascii_lowercase())
{
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
_ => true, // default ON (promoted after validation)
}
}
// ---- Null/Missing Boxes (dev-only observe → adopt) ----
/// Enable NullBox/MissingBox observation path (no behavior change by default).
/// Default: OFF. Turn ON with `NYASH_NULL_MISSING_BOX=1`. May be auto-enabled in --dev later.
pub fn null_missing_box_enabled() -> bool {
std::env::var("NYASH_NULL_MISSING_BOX").ok().as_deref() == Some("1")
}
/// Strict null policy for operators (when enabled): null in arithmetic/compare is an error.
/// Default: OFF (null propagates). Effective only when `null_missing_box_enabled()` is true.
pub fn null_strict() -> bool {
std::env::var("NYASH_NULL_STRICT").ok().as_deref() == Some("1")
}
// ---- Phase 12: Nyash ABI (vtable) toggles ----
pub fn abi_vtable() -> bool {
std::env::var("NYASH_ABI_VTABLE").ok().as_deref() == Some("1")
}
/// ABI strict diagnostics: missing vtable methods become errors when enabled.
pub fn abi_strict() -> bool {
std::env::var("NYASH_ABI_STRICT").ok().as_deref() == Some("1")
}
// ---- Legacy compatibility (dev-only) ----
/// Enable legacy InstanceBox fields (SharedNyashBox map) for compatibility.
/// Default: OFF. Set NYASH_LEGACY_FIELDS_ENABLE=1 to materialize and use legacy fields.
pub fn legacy_fields_enable() -> bool {
env_bool("NYASH_LEGACY_FIELDS_ENABLE")
}
// ---- GC/Runtime tracing (execution-affecting visibility) ----
pub fn gc_trace() -> bool {
env_bool("NYASH_GC_TRACE")
}
pub fn gc_barrier_trace() -> bool {
env_bool("NYASH_GC_BARRIER_TRACE")
}
pub fn runtime_checkpoint_trace() -> bool {
env_bool("NYASH_RUNTIME_CHECKPOINT_TRACE")
}
pub fn gc_barrier_strict() -> bool {
std::env::var("NYASH_GC_BARRIER_STRICT").ok().as_deref() == Some("1")
}
/// Return 0 (off) to 3 (max) for `NYASH_GC_TRACE`.
pub fn gc_trace_level() -> u8 {
match std::env::var("NYASH_GC_TRACE").ok().as_deref() {
Some("1") => 1,
Some("2") => 2,
Some("3") => 3,
Some(_) => 1,
None => 0,
}
}
// ---- GC mode and instrumentation ----
/// Return current GC mode string (auto default = "rc+cycle").
/// Allowed: "auto", "rc+cycle", "minorgen", "stw", "rc", "off"
pub fn gc_mode() -> String {
match std::env::var("NYASH_GC_MODE").ok() {
Some(m) if !m.trim().is_empty() => m,
_ => "rc+cycle".to_string(),
}
}
/// Brief metrics emission (text)
pub fn gc_metrics() -> bool {
std::env::var("NYASH_GC_METRICS").ok().as_deref() == Some("1")
}
/// JSON metrics emission (single line)
pub fn gc_metrics_json() -> bool {
std::env::var("NYASH_GC_METRICS_JSON").ok().as_deref() == Some("1")
}
/// Optional allocation threshold; if Some(n) and exceeded, print warning
pub fn gc_alloc_threshold() -> Option<u64> {
std::env::var("NYASH_GC_ALLOC_THRESHOLD").ok()?.parse().ok()
}
// ---- Cleanup (method-level postfix) policy toggles ----
/// Allow `return` inside a cleanup block. Default: false (0)
pub fn cleanup_allow_return() -> bool {
match std::env::var("NYASH_CLEANUP_ALLOW_RETURN").ok() {
Some(v) => {
let lv = v.to_ascii_lowercase();
!(lv == "0" || lv == "false" || lv == "off")
}
None => false,
}
}
/// Allow `throw` inside a cleanup block. Default: false (0)
pub fn cleanup_allow_throw() -> bool {
match std::env::var("NYASH_CLEANUP_ALLOW_THROW").ok() {
Some(v) => {
let lv = v.to_ascii_lowercase();
!(lv == "0" || lv == "false" || lv == "off")
}
None => false,
}
}
/// Run a collection every N safepoints (if Some)
pub fn gc_collect_sp_interval() -> Option<u64> {
std::env::var("NYASH_GC_COLLECT_SP").ok()?.parse().ok()
}
/// Run a collection when allocated bytes since last >= N (if Some)
pub fn gc_collect_alloc_bytes() -> Option<u64> {
std::env::var("NYASH_GC_COLLECT_ALLOC").ok()?.parse().ok()
}
/// Get await maximum milliseconds, centralized here for consistency.
pub fn await_max_ms() -> u64 {
std::env::var("NYASH_AWAIT_MAX_MS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(5000)
}

136
src/config/env/parser_flags.rs vendored Normal file
View File

@ -0,0 +1,136 @@
//! Parser-related environment flags
//!
//! This module groups all parser and language feature flags.
//! Use this for IDE autocomplete to discover parser flags easily.
use super::warn_alias_once;
fn nyash_features_list() -> Option<Vec<String>> {
let raw = std::env::var("NYASH_FEATURES").ok()?;
let list: Vec<String> = raw
.split(',')
.filter_map(|s| {
let trimmed = s.trim();
if trimmed.is_empty() {
None
} else {
Some(trimmed.to_ascii_lowercase())
}
})
.collect();
if list.is_empty() {
None
} else {
Some(list)
}
}
fn feature_stage3_enabled() -> bool {
if let Some(list) = nyash_features_list() {
for item in list {
let normalized = item.replace(['-', '_'], "");
if normalized == "stage3" || normalized == "parserstage3" {
return true;
}
}
}
false
}
fn env_flag(var: &str) -> Option<bool> {
std::env::var(var).ok().map(|v| {
let lv = v.to_ascii_lowercase();
lv == "1" || lv == "true" || lv == "on"
})
}
/// Core (Rust) parser Stage-3 gate (default ON).
/// Precedence:
/// 1) NYASH_FEATURES contains `stage3`/`parser-stage3`
/// 2) Legacy env aliases (NYASH_PARSER_STAGE3 / HAKO_PARSER_STAGE3)
/// 3) Default true (Stage-3 is standard syntax)
pub fn parser_stage3_enabled() -> bool {
if feature_stage3_enabled() {
return true;
}
if let Some(v) = env_flag("NYASH_PARSER_STAGE3") {
warn_alias_once("NYASH_PARSER_STAGE3", "NYASH_FEATURES=stage3");
return v;
}
if let Some(v) = env_flag("HAKO_PARSER_STAGE3") {
warn_alias_once("HAKO_PARSER_STAGE3", "NYASH_FEATURES=stage3");
return v;
}
true
}
#[deprecated(note = "Use parser_stage3_enabled() instead")]
pub fn parser_stage3() -> bool {
parser_stage3_enabled()
}
/// Parser gate for BlockPostfix Catch acceptance
/// Enabled when either NYASH_BLOCK_CATCH=1 or Stage3 gate is on.
/// Phase 15.5 allows parsing a standalone `{ ... }` block optionally followed by
/// a single `catch (...) { ... }` and/or `finally { ... }`, which is folded into
/// ASTNode::TryCatch with the preceding block as the try body.
pub fn block_postfix_catch() -> bool {
std::env::var("NYASH_BLOCK_CATCH").ok().as_deref() == Some("1") || parser_stage3_enabled()
}
/// Parser gate for method-level postfix catch/finally acceptance on method definitions.
/// Enabled when either NYASH_METHOD_CATCH=1 or Stage3 gate is on.
pub fn method_catch() -> bool {
std::env::var("NYASH_METHOD_CATCH").ok().as_deref() == Some("1") || parser_stage3_enabled()
}
/// Parser gate for expression-level postfix catch/cleanup acceptance.
/// Enabled when Stage-3 gate is on (NYASH_FEATURES=stage3 or legacy aliases). Separate gate can
/// be introduced in future if needed, but we keep minimal toggles now.
pub fn expr_postfix_catch() -> bool {
parser_stage3_enabled()
}
/// Parser gate for Unified Members (stored/computed/once/birth_once).
/// Default: ON during Phase-15 (set NYASH_ENABLE_UNIFIED_MEMBERS=0|false|off to disable).
pub fn unified_members() -> bool {
match std::env::var("NYASH_ENABLE_UNIFIED_MEMBERS").ok() {
Some(v) => {
let lv = v.to_ascii_lowercase();
!(lv == "0" || lv == "false" || lv == "off")
}
None => true,
}
}
/// Unicode decode toggle for string literals (\uXXXX, optional surrogate pairs).
/// Enabled when either HAKO_PARSER_DECODE_UNICODE=1 or NYASH_PARSER_DECODE_UNICODE=1.
/// Default: OFF (for strict backward compatibility).
pub fn parser_decode_unicode() -> bool {
env_flag("HAKO_PARSER_DECODE_UNICODE")
.or_else(|| env_flag("NYASH_PARSER_DECODE_UNICODE"))
.unwrap_or(false)
}
/// Entry policy: allow top-level `main` resolution in addition to `Main.main`.
/// Default: true (prefer `Main.main` when both exist; otherwise accept `main`).
pub fn entry_allow_toplevel_main() -> bool {
match std::env::var("NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN").ok() {
Some(v) => {
let v = v.to_ascii_lowercase();
v == "1" || v == "true" || v == "on"
}
None => true,
}
}
/// Macro pre-expand mode for selfhost (NYASH_MACRO_SELFHOST_PRE_EXPAND).
/// Returns "1", "auto", or None.
pub fn macro_selfhost_pre_expand() -> Option<String> {
std::env::var("NYASH_MACRO_SELFHOST_PRE_EXPAND").ok()
}
/// ScopeBox enable flag (NYASH_SCOPEBOX_ENABLE=1).
pub fn scopebox_enable() -> bool {
std::env::var("NYASH_SCOPEBOX_ENABLE").ok().as_deref() == Some("1")
}

98
src/config/env/selfhost_flags.rs vendored Normal file
View File

@ -0,0 +1,98 @@
//! Selfhost compiler-related environment flags
//!
//! This module groups all selfhost NY compiler flags.
//! Use this for IDE autocomplete to discover selfhost compiler flags easily.
use super::warn_alias_once;
// Self-host compiler knobs
pub fn ny_compiler_timeout_ms() -> u64 {
std::env::var("NYASH_NY_COMPILER_TIMEOUT_MS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(2000)
}
/// Emit-only flag for selfhost compiler (default ON to avoid execution).
pub fn ny_compiler_emit_only() -> bool {
std::env::var("NYASH_NY_COMPILER_EMIT_ONLY").unwrap_or_else(|_| "1".to_string()) == "1"
}
/// Path to external selfhost compiler executable (when enabled).
pub fn use_ny_compiler_exe() -> bool {
std::env::var("NYASH_USE_NY_COMPILER_EXE").ok().as_deref() == Some("1")
}
/// Path to external selfhost compiler executable (when enabled).
pub fn ny_compiler_exe_path() -> Option<String> {
std::env::var("NYASH_NY_COMPILER_EXE_PATH").ok()
}
/// Pass `-- --min-json` to child selfhost compiler (minimal JSON output).
pub fn ny_compiler_min_json() -> bool {
std::env::var("NYASH_NY_COMPILER_MIN_JSON").ok().as_deref() == Some("1")
}
/// When true, child reads tmp/ny_parser_input.ny instead of stdin/source text.
pub fn selfhost_read_tmp() -> bool {
std::env::var("NYASH_SELFHOST_READ_TMP").ok().as_deref() == Some("1")
}
/// Pass `-- --stage3` to child selfhost compiler to allow Stage-3 surface.
pub fn ny_compiler_stage3() -> bool {
std::env::var("NYASH_NY_COMPILER_STAGE3").ok().as_deref() == Some("1")
}
pub fn ny_compiler_child_args() -> Option<String> {
// Pass-through args to selfhost child (space-separated).
std::env::var("NYASH_NY_COMPILER_CHILD_ARGS").ok()
}
pub fn ny_compiler_use_tmp_only() -> bool {
std::env::var("NYASH_NY_COMPILER_USE_TMP_ONLY")
.ok()
.as_deref()
== Some("1")
}
/// Use Python MVP harness for Ny compiler (NYASH_NY_COMPILER_USE_PY=1).
pub fn ny_compiler_use_py() -> bool {
std::env::var("NYASH_NY_COMPILER_USE_PY").ok().as_deref() == Some("1")
}
/// Dev-only escape hatch: force inline selfhost path (NYASH_SELFHOST_INLINE_FORCE=1).
pub fn selfhost_inline_force() -> bool {
std::env::var("NYASH_SELFHOST_INLINE_FORCE").ok().as_deref() == Some("1")
}
/// Consolidated toggle for selfhost NY compiler pipeline.
/// Primary: NYASH_USE_NY_COMPILER=0|1明示指定のみ有効。Legacy disables accepted (with warning):
/// NYASH_DISABLE_NY_COMPILER/HAKO_DISABLE_NY_COMPILER (any true value disables).
pub fn use_ny_compiler() -> bool {
fn env_bool(key: &str) -> bool {
match std::env::var(key).ok() {
Some(v) => {
let lv = v.to_ascii_lowercase();
lv == "1" || lv == "true" || lv == "on"
}
None => false,
}
}
// Primary knob takes precedence when explicitly set
if let Some(v) = std::env::var("NYASH_USE_NY_COMPILER").ok() {
let lv = v.trim().to_ascii_lowercase();
return lv == "1" || lv == "true" || lv == "on";
}
// Legacy disable aliases — if any is true, treat as disabled and warn
if env_bool("NYASH_DISABLE_NY_COMPILER") {
warn_alias_once("NYASH_DISABLE_NY_COMPILER", "NYASH_USE_NY_COMPILER=0");
return false;
}
if env_bool("HAKO_DISABLE_NY_COMPILER") {
warn_alias_once("HAKO_DISABLE_NY_COMPILER", "NYASH_USE_NY_COMPILER=0");
return false;
}
// Phase 25.1b: Default OFFselfhost NY compiler は明示 opt-in のみ)
false
}

109
src/config/env/stage1.rs vendored Normal file
View File

@ -0,0 +1,109 @@
//! Stage-1 / selfhost CLI environment helpers (SSOT).
use crate::config::env::{env_bool, warn_alias_once};
/// Primary toggle: enable Stage-1 stub routing.
pub fn enabled() -> bool {
env_bool("NYASH_USE_STAGE1_CLI")
|| env_bool("HAKO_STAGE1_ENABLE")
|| env_bool("HAKO_EMIT_PROGRAM_JSON")
|| env_bool("HAKO_EMIT_MIR_JSON")
}
/// Recursion guard when Stage-1 stub calls back into the runner.
pub fn child_invocation() -> bool {
env_bool("NYASH_STAGE1_CLI_CHILD")
}
/// Stage-1 mode hint (emit-program / emit-mir / run).
pub fn mode() -> Option<String> {
if let Some(m) = std::env::var("HAKO_STAGE1_MODE")
.ok()
.or_else(|| std::env::var("NYASH_STAGE1_MODE").ok())
{
let trimmed = m.trim();
if !trimmed.is_empty() {
return Some(trimmed.to_ascii_lowercase().replace('_', "-"));
}
}
if std::env::var("HAKO_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1") {
return Some("emit-program".into());
}
if std::env::var("HAKO_EMIT_MIR_JSON").ok().as_deref() == Some("1") {
return Some("emit-mir".into());
}
if std::env::var("STAGE1_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1") {
return Some("emit-program".into());
}
if std::env::var("STAGE1_EMIT_MIR_JSON").ok().as_deref() == Some("1") {
return Some("emit-mir".into());
}
if enabled() {
return Some("run".into());
}
None
}
/// True when Stage-1 should emit Program(JSON v0).
pub fn emit_program_json() -> bool {
matches!(
mode().as_deref(),
Some("emit-program" | "emit-program-json")
)
}
/// True when Stage-1 should emit MIR(JSON).
pub fn emit_mir_json() -> bool {
matches!(mode().as_deref(), Some("emit-mir" | "emit-mir-json"))
}
/// Input source path passed to Stage-1 stub (aliases included).
pub fn input_path() -> Option<String> {
std::env::var("HAKO_STAGE1_INPUT")
.ok()
.or_else(|| std::env::var("NYASH_STAGE1_INPUT").ok())
.or_else(|| std::env::var("STAGE1_SOURCE").ok())
.or_else(|| std::env::var("STAGE1_INPUT").ok())
}
/// Program(JSON v0) path for Stage-1 emit-mir mode (aliases included).
pub fn program_json_path() -> Option<String> {
std::env::var("HAKO_STAGE1_PROGRAM_JSON")
.ok()
.or_else(|| std::env::var("NYASH_STAGE1_PROGRAM_JSON").ok())
.or_else(|| std::env::var("STAGE1_PROGRAM_JSON").ok())
}
/// Backend hint for Stage-1 run mode (aliases included).
pub fn backend_hint() -> Option<String> {
std::env::var("HAKO_STAGE1_BACKEND")
.ok()
.or_else(|| std::env::var("NYASH_STAGE1_BACKEND").ok())
.or_else(|| std::env::var("STAGE1_BACKEND").ok())
}
/// Optional override for Stage-1 CLI entry path.
pub fn entry_override() -> Option<String> {
std::env::var("STAGE1_CLI_ENTRY")
.ok()
.or_else(|| std::env::var("HAKORUNE_STAGE1_ENTRY").ok())
}
/// Optional Stage-1 child args (passed through to stub).
pub fn child_args_env() -> Option<String> {
std::env::var("NYASH_SCRIPT_ARGS_JSON").ok()
}
/// Stage-1 debug flag (verbose child stderr).
pub fn debug() -> bool {
std::env::var("STAGE1_CLI_DEBUG").ok().as_deref() == Some("1")
}
/// Alias compatibility for backends (warn once).
pub fn backend_alias_warned() -> Option<String> {
if let Some(be) = std::env::var("STAGE1_BACKEND").ok() {
warn_alias_once("STAGE1_BACKEND", "NYASH_STAGE1_BACKEND");
return Some(be);
}
None
}

70
src/config/env/using_flags.rs vendored Normal file
View File

@ -0,0 +1,70 @@
//! Using/namespace-related environment flags
//!
//! This module groups all `using` system and namespace flags.
//! Use this for IDE autocomplete to discover using/namespace flags easily.
use super::warn_alias_once;
pub fn enable_using() -> bool {
// Phase 15: デフォルトONusing systemはメイン機能
// NYASH_ENABLE_USING=0 で明示的に無効化可能。HAKO_ENABLE_USING は互換のため受理(警告)。
match std::env::var("NYASH_ENABLE_USING").ok().as_deref() {
Some("0") | Some("false") | Some("off") => return false,
Some(_) => return true,
None => {}
}
// Fallback to alias
if let Some(v) = std::env::var("HAKO_ENABLE_USING").ok() {
warn_alias_once("HAKO_ENABLE_USING", "NYASH_ENABLE_USING");
let lv = v.to_ascii_lowercase();
return !(lv == "0" || lv == "false" || lv == "off");
}
true // default ON
}
// ---- Using profiles (dev|ci|prod) ----
/// Return using profile string; default is "dev".
pub fn using_profile() -> String {
std::env::var("NYASH_USING_PROFILE").unwrap_or_else(|_| "dev".to_string())
}
/// True when using profile is prod (disables some dev-only behaviors).
pub fn using_is_prod() -> bool {
using_profile().eq_ignore_ascii_case("prod")
}
/// True when using profile is ci.
pub fn using_is_ci() -> bool {
using_profile().eq_ignore_ascii_case("ci")
}
/// True when using profile is dev (default).
pub fn using_is_dev() -> bool {
using_profile().eq_ignore_ascii_case("dev")
}
/// Allow `using "path"` statements in source (dev-only by default).
pub fn allow_using_file() -> bool {
// SSOT 徹底: 全プロファイルで既定禁止nyash.toml を唯一の真実に)
// 明示オーバーライドでのみ許可(開発用緊急時)
match std::env::var("NYASH_ALLOW_USING_FILE").ok().as_deref() {
Some("1") | Some("true") | Some("on") => true,
_ => false,
}
}
/// Determine whether AST prelude merge for `using` is enabled.
/// Precedence:
/// 1) Explicit env `NYASH_USING_AST` = 1/true/on → enabled, = 0/false/off → disabled
/// 2) Default by profile: dev/ci → ON, prod → OFF
pub fn using_ast_enabled() -> bool {
match std::env::var("NYASH_USING_AST")
.ok()
.as_deref()
.map(|v| v.to_ascii_lowercase())
{
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
_ => !using_is_prod(), // dev/ci → true, prod → false
}
}

61
src/config/env/verification_flags.rs vendored Normal file
View File

@ -0,0 +1,61 @@
//! Verification and checking-related environment flags
//!
//! This module groups all verification, checking, and testing flags.
//! Use this for IDE autocomplete to discover verification flags easily.
use super::{env_bool, env_bool_default};
/// Allow verifier to skip SSA/dominance/merge checks for PHI-less MIR.
pub fn verify_allow_no_phi() -> bool {
std::env::var("NYASH_VERIFY_ALLOW_NO_PHI").ok().as_deref() == Some("1") || mir_no_phi()
}
fn mir_no_phi() -> bool {
env_bool("NYASH_MIR_NO_PHI")
}
/// Enable strict edge-copy policy verification in PHI-off mode.
/// When enabled, merge blocks must receive merged values via predecessor copies only,
/// and the merge block itself must not introduce a self-copy to the merged destination.
pub fn verify_edge_copy_strict() -> bool {
env_bool("NYASH_VERIFY_EDGE_COPY_STRICT")
}
/// Enforce purity of return blocks: no side-effecting instructions allowed before Return
/// Default: OFF. Enable with NYASH_VERIFY_RET_PURITY=1 in dev/profiling sessions.
pub fn verify_ret_purity() -> bool {
env_bool("NYASH_VERIFY_RET_PURITY")
}
/// Stage-B/selfhost 専用の dev verify トグルSSA などの厳格チェックを一時緩和するためのスイッチ)
/// Default: ON現行挙動。NYASH_STAGEB_DEV_VERIFY=0 で Stage-B 経路の dev verify をスキップ。
pub fn stageb_dev_verify_enabled() -> bool {
fn env_flag(var: &str) -> Option<bool> {
std::env::var(var).ok().map(|v| {
let lv = v.to_ascii_lowercase();
lv == "1" || lv == "true" || lv == "on"
})
}
env_flag("NYASH_STAGEB_DEV_VERIFY").unwrap_or(true)
}
/// Global fail-fast policy for runtime fallbacks.
/// Default: ON (true) to prohibit silent/different-route fallbacks in Rust layer.
/// Set NYASH_FAIL_FAST=0 to temporarily allow legacy fallbacks during bring-up.
pub fn fail_fast() -> bool {
env_bool_default("NYASH_FAIL_FAST", true)
}
/// Bridge lowering: use Result-style try/throw lowering instead of MIR Catch/Throw
/// When on, try/catch is lowered using structured blocks and direct jumps,
/// without emitting MIR Throw/Catch. The thrown value is routed to catch via
/// block parameters (PHI-off uses edge-copy).
pub fn try_result_mode() -> bool {
std::env::var("NYASH_TRY_RESULT_MODE").ok().as_deref() == Some("1")
}
/// Runner/CLI common toggles (hot-path centralization)
pub fn cli_verbose() -> bool {
// Use cli_verbose_level from dump module
super::dump::cli_verbose_level() > 0
}

135
src/config/env/vm_backend_flags.rs vendored Normal file
View File

@ -0,0 +1,135 @@
//! VM and backend-related environment flags
//!
//! This module groups all VM execution and backend selection flags.
//! Use this for IDE autocomplete to discover VM/backend flags easily.
use super::{env_bool, env_flag, warn_alias_once};
// ---- LLVM harness toggle (llvmlite) ----
pub fn llvm_use_harness() -> bool {
// Phase 15: デフォルトONLLVMバックエンドはPythonハーネス使用
// NYASH_LLVM_USE_HARNESS=0 で明示的に無効化可能
match std::env::var("NYASH_LLVM_USE_HARNESS").ok().as_deref() {
Some("0") | Some("false") | Some("off") => false,
_ => true, // デフォルト: ONハーネス使用
}
}
/// LLVM opt level (primary: NYASH_LLVM_OPT_LEVEL; alias: HAKO_LLVM_OPT_LEVEL)
/// Returns string level (e.g., "0", "1", ...). Default: "0" when unset.
pub fn llvm_opt_level() -> String {
if let Some(v) = std::env::var("NYASH_LLVM_OPT_LEVEL").ok() {
return v;
}
if let Some(v) = std::env::var("HAKO_LLVM_OPT_LEVEL").ok() {
warn_alias_once("HAKO_LLVM_OPT_LEVEL", "NYASH_LLVM_OPT_LEVEL");
return v;
}
"0".to_string()
}
pub fn vm_use_py() -> bool {
std::env::var("NYASH_VM_USE_PY").ok().as_deref() == Some("1")
}
pub fn pipe_use_pyvm() -> bool {
std::env::var("NYASH_PIPE_USE_PYVM").ok().as_deref() == Some("1")
}
/// (Deprecated) use dispatch-based VM route; currently disabled.
pub fn vm_use_dispatch() -> bool {
false
}
/// Force VM fallback interpreter route (dev-only escape hatch).
pub fn vm_use_fallback() -> bool {
std::env::var("NYASH_VM_USE_FALLBACK").ok().as_deref() == Some("1")
}
/// Trace VM route selection decisions.
pub fn vm_route_trace() -> bool {
std::env::var("NYASH_VM_ROUTE_TRACE").ok().as_deref() == Some("1")
}
/// Policy: allow VM to fallback-dispatch user Instance BoxCall (dev only by default).
/// - prod: default false (disallow)
/// - dev/ci: default true (allow, with WARN)
/// Override with NYASH_VM_USER_INSTANCE_BOXCALL={0|1}
pub fn vm_allow_user_instance_boxcall() -> bool {
match std::env::var("NYASH_VM_USER_INSTANCE_BOXCALL")
.ok()
.as_deref()
.map(|v| v.to_ascii_lowercase())
{
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
_ => !using_is_prod(),
}
}
// Import using profile functions needed for vm_allow_user_instance_boxcall
fn using_is_prod() -> bool {
using_profile().eq_ignore_ascii_case("prod")
}
fn using_profile() -> String {
std::env::var("NYASH_USING_PROFILE").unwrap_or_else(|_| "dev".to_string())
}
pub fn nyvm_core_wrapper() -> bool {
env_flag("HAKO_NYVM_CORE")
.or_else(|| env_flag("NYASH_NYVM_CORE"))
.unwrap_or(false)
}
pub fn nyvm_bridge_inject_singleton() -> bool {
env_flag("HAKO_BRIDGE_INJECT_SINGLETON")
.or_else(|| env_flag("NYASH_BRIDGE_INJECT_SINGLETON"))
.unwrap_or(false)
}
pub fn nyvm_bridge_early_phi_materialize() -> bool {
env_flag("HAKO_BRIDGE_EARLY_PHI_MATERIALIZE")
.or_else(|| env_flag("NYASH_BRIDGE_EARLY_PHI_MATERIALIZE"))
.unwrap_or(false)
}
pub fn nyvm_v1_downconvert() -> bool {
env_flag("HAKO_NYVM_V1_DOWNCONVERT")
.or_else(|| env_flag("NYASH_NYVM_V1_DOWNCONVERT"))
.unwrap_or(false)
}
/// GateC(Core) route request (primary: NYASH_GATE_C_CORE; alias: HAKO_GATE_C_CORE)
pub fn gate_c_core() -> bool {
if env_bool("NYASH_GATE_C_CORE") {
return true;
}
if env_bool("HAKO_GATE_C_CORE") {
warn_alias_once("HAKO_GATE_C_CORE", "NYASH_GATE_C_CORE");
return true;
}
false
}
/// GateC(Core) strict OOB handling: when enabled, any observed OOB tag
/// (emitted by runtime during ArrayBox get/set with HAKO_OOB_STRICT=1) should
/// cause nonzero exit at the end of JSON→VM execution.
pub fn oob_strict_fail() -> bool {
env_flag("HAKO_OOB_STRICT_FAIL")
.or_else(|| env_flag("NYASH_OOB_STRICT_FAIL"))
.unwrap_or(false)
}
/// Primary verification route: return true when Hakorune VM is requested as primary.
/// Accepts HAKO_VERIFY_PRIMARY=hakovm (preferred) or legacy HAKO_ROUTE_HAKOVM=1 (deprecated, warns).
pub fn verify_primary_is_hakovm() -> bool {
if std::env::var("HAKO_VERIFY_PRIMARY").ok().as_deref() == Some("hakovm") {
return true;
}
if env_bool("HAKO_ROUTE_HAKOVM") {
warn_alias_once("HAKO_ROUTE_HAKOVM", "HAKO_VERIFY_PRIMARY=hakovm");
return true;
}
false
}