/*! * Hako-like source detection and minimal normalization helpers. * * - looks_like_hako_code: heuristics to detect Hako surface in Nyash path * - strip_local_decl: drop leading `local ` at line head for Nyash parser compatibility * - fail_fast_on_hako: env-gated policy (default ON) to fail fast on Hako-like source in Nyash VM path */ /// Heuristic detection of Hako-like source (development-only convenience) pub fn looks_like_hako_code(s: &str) -> bool { s.contains("using selfhost.") || s.contains("using hakorune.") || s.lines().any(|l| l.trim_start().starts_with("local ")) } /// Remove leading `local ` declarations at line head to keep Nyash parser stable pub fn strip_local_decl(s: &str) -> String { let mut out = String::with_capacity(s.len()); for line in s.lines() { let leading = line.len() - line.trim_start().len(); let (indent, rest) = line.split_at(leading); if rest.starts_with("local ") || rest.starts_with("local\t") { let bytes = rest.as_bytes(); let mut i = 5; // after 'local' while i < bytes.len() && (bytes[i] == b' ' || bytes[i] == b'\t') { i += 1; break; } out.push_str(indent); out.push_str(&rest[i..]); out.push('\n'); } else { out.push_str(line); out.push('\n'); } } out } /// Policy toggle: fail fast when Hako-like code enters Nyash VM path /// Default: ON (true) pub fn fail_fast_on_hako() -> bool { match std::env::var("HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM").ok().as_deref() { Some("0") | Some("false") | Some("off") => false, _ => true, } }