hv1 verify: add direct route (env JSON) and clean inline path; fix v1 phi incoming order; make test_runner use hv1 direct; add phase2037 phi canaries; load modules.workspace exports for alias; update docs (phase-20.38, source extensions) and CURRENT_TASK

This commit is contained in:
nyash-codex
2025-11-04 16:33:04 +09:00
parent 5a1bb549a7
commit 30aa39f50b
270 changed files with 4320 additions and 758 deletions

View File

@ -27,32 +27,77 @@ impl NyashRunner {
let mut code2 = code;
let use_ast_prelude =
crate::config::env::enable_using() && crate::config::env::using_ast_enabled();
let mut prelude_asts: Vec<nyash_rust::ast::ASTNode> = Vec::new();
if crate::config::env::enable_using() {
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(
self, &code2, filename,
) {
Ok((clean, paths)) => {
code2 = clean;
if !paths.is_empty() && !use_ast_prelude {
eprintln!("❌ using: AST prelude merge is disabled in this profile. Enable NYASH_USING_AST=1 or remove 'using' lines.");
process::exit(1);
// Always perform text-prelude merge when using+AST is enabled to ensure alias/file modules are materialized.
if use_ast_prelude {
match crate::runner::modes::common_util::resolve::merge_prelude_text(self, &code2, filename) {
Ok(merged) => {
if std::env::var("NYASH_RESOLVE_TRACE").ok().as_deref() == Some("1") {
eprintln!("[using/text-merge] applied (vm-fallback): {} bytes", merged.len());
}
code2 = merged;
}
if use_ast_prelude && !paths.is_empty() {
match crate::runner::modes::common_util::resolve::parse_preludes_to_asts(self, &paths) {
Ok(v) => prelude_asts = v,
Err(e) => { eprintln!("{}", e); process::exit(1); }
Err(e) => { eprintln!("❌ using text merge error: {}", e); process::exit(1); }
}
} else {
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(self, &code2, filename) {
Ok((_clean, paths)) => {
if !paths.is_empty() {
eprintln!("❌ using: prelude merge is disabled in this profile. Enable NYASH_USING_AST=1 or remove 'using' lines.");
process::exit(1);
}
}
}
Err(e) => {
eprintln!("{}", e);
process::exit(1);
Err(e) => { eprintln!("{}", e); process::exit(1); }
}
}
}
// Dev sugar pre-expand: @name = expr → local name = expr
code2 = crate::runner::modes::common_util::resolve::preexpand_at_local(&code2);
// Hako-friendly normalize: strip leading `local ` at line head for Nyash parser compatibility.
fn looks_like_hako_code(s: &str) -> bool {
s.contains("using selfhost.") || s.lines().any(|l| l.trim_start().starts_with("local "))
}
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; // skip '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
}
if looks_like_hako_code(&code2) {
code2 = strip_local_decl(&code2);
}
// FailFast (optin): Hako 構文を Nyash VM 経路で実行しない
// 目的: .hako は Hakorune VM、MIR は Core/LLVM に役割分離するためのガード
{
let on = match std::env::var("HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM").ok().as_deref() {
Some("0")|Some("false")|Some("off") => false,
_ => true,
};
if on {
let s = code2.as_str();
let hako_like = s.contains("static box ") || s.contains("using selfhost.") || s.contains("using hakorune.");
if hako_like {
eprintln!(
"❌ Hako-like source detected in Nyash VM path. Use Hakorune VM (v1 dispatcher) or Core/LLVM for MIR.\n hint: set HAKO_VERIFY_PRIMARY=hakovm in verify path"
);
process::exit(1);
}
}
}
// Parse main code
let main_ast = match NyashParser::parse_from_string(&code2) {
@ -62,10 +107,8 @@ impl NyashRunner {
process::exit(1);
}
};
// When using AST prelude mode, combine prelude ASTs + main AST into one Program before macro expansion
let ast_combined = if use_ast_prelude && !prelude_asts.is_empty() {
crate::runner::modes::common_util::resolve::merge_prelude_asts_with_main(prelude_asts, &main_ast)
} else { main_ast };
// AST prelude merge is retired in favor of text-based merge for language-neutral handling
let ast_combined = main_ast;
// Optional: dump AST statement kinds for quick diagnostics
if std::env::var("NYASH_AST_DUMP").ok().as_deref() == Some("1") {
use nyash_rust::ast::ASTNode;