feat: using system完全実装+旧スモークテストアーカイブ完了
✅ using nyashstd完全動作(ChatGPT実装) - builtin:nyashstd自動解決 - 環境変数不要でデフォルト有効 - console.log等の基本機能完備 ✅ Fixture plugin追加(テスト用最小構成) ✅ v2スモークテスト構造への移行 ✅ 旧tools/test/smoke/削除(100+ファイル) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -4,9 +4,16 @@
|
||||
#[allow(dead_code)]
|
||||
pub fn run_pyvm_harness(module: &crate::mir::MirModule, tag: &str) -> Result<i32, String> {
|
||||
let py3 = which::which("python3").map_err(|e| format!("python3 not found: {}", e))?;
|
||||
let runner = std::path::Path::new("tools/pyvm_runner.py");
|
||||
if !runner.exists() {
|
||||
return Err(format!("PyVM runner not found: {}", runner.display()));
|
||||
// Resolve runner path relative to CWD or NYASH_ROOT fallback
|
||||
let mut runner_buf = std::path::PathBuf::from("tools/pyvm_runner.py");
|
||||
if !runner_buf.exists() {
|
||||
if let Ok(root) = std::env::var("NYASH_ROOT") {
|
||||
let alt = std::path::Path::new(&root).join("tools/pyvm_runner.py");
|
||||
if alt.exists() { runner_buf = alt; }
|
||||
}
|
||||
}
|
||||
if !runner_buf.exists() {
|
||||
return Err(format!("PyVM runner not found: tools/pyvm_runner.py (cwd) or $NYASH_ROOT/tools/pyvm_runner.py"));
|
||||
}
|
||||
let tmp_dir = std::path::Path::new("tmp");
|
||||
let _ = std::fs::create_dir_all(tmp_dir);
|
||||
@ -38,7 +45,7 @@ pub fn run_pyvm_harness(module: &crate::mir::MirModule, tag: &str) -> Result<i32
|
||||
}
|
||||
let status = cmd
|
||||
.args([
|
||||
runner.to_string_lossy().as_ref(),
|
||||
runner_buf.to_string_lossy().as_ref(),
|
||||
"--in",
|
||||
&mir_json_path.display().to_string(),
|
||||
"--entry",
|
||||
@ -59,9 +66,15 @@ pub fn run_pyvm_harness(module: &crate::mir::MirModule, tag: &str) -> Result<i32
|
||||
#[allow(dead_code)]
|
||||
pub fn run_pyvm_harness_lib(module: &nyash_rust::mir::MirModule, tag: &str) -> Result<i32, String> {
|
||||
let py3 = which::which("python3").map_err(|e| format!("python3 not found: {}", e))?;
|
||||
let runner = std::path::Path::new("tools/pyvm_runner.py");
|
||||
if !runner.exists() {
|
||||
return Err(format!("PyVM runner not found: {}", runner.display()));
|
||||
let mut runner_buf = std::path::PathBuf::from("tools/pyvm_runner.py");
|
||||
if !runner_buf.exists() {
|
||||
if let Ok(root) = std::env::var("NYASH_ROOT") {
|
||||
let alt = std::path::Path::new(&root).join("tools/pyvm_runner.py");
|
||||
if alt.exists() { runner_buf = alt; }
|
||||
}
|
||||
}
|
||||
if !runner_buf.exists() {
|
||||
return Err(format!("PyVM runner not found: tools/pyvm_runner.py (cwd) or $NYASH_ROOT/tools/pyvm_runner.py"));
|
||||
}
|
||||
let tmp_dir = std::path::Path::new("tmp");
|
||||
let _ = std::fs::create_dir_all(tmp_dir);
|
||||
@ -91,7 +104,7 @@ pub fn run_pyvm_harness_lib(module: &nyash_rust::mir::MirModule, tag: &str) -> R
|
||||
}
|
||||
let status = cmd
|
||||
.args([
|
||||
runner.to_string_lossy().as_ref(),
|
||||
runner_buf.to_string_lossy().as_ref(),
|
||||
"--in",
|
||||
&mir_json_path.display().to_string(),
|
||||
"--entry",
|
||||
|
||||
@ -102,6 +102,8 @@ pub fn strip_using_and_register(
|
||||
if t.starts_with("using ") {
|
||||
crate::cli_v!("[using] stripped line: {}", line);
|
||||
let rest0 = t.strip_prefix("using ").unwrap().trim();
|
||||
// Strip trailing inline comments
|
||||
let rest0 = rest0.split('#').next().unwrap_or(rest0).trim();
|
||||
let rest0 = rest0.strip_suffix(';').unwrap_or(rest0).trim();
|
||||
let (target, alias) = if let Some(pos) = rest0.find(" as ") {
|
||||
(rest0[..pos].trim().to_string(), Some(rest0[pos + 4..].trim().to_string()))
|
||||
@ -158,6 +160,7 @@ pub fn strip_using_and_register(
|
||||
&using_ctx.pending_modules,
|
||||
&using_ctx.using_paths,
|
||||
&using_ctx.aliases,
|
||||
&using_ctx.packages,
|
||||
ctx_dir,
|
||||
strict,
|
||||
verbose,
|
||||
@ -174,6 +177,24 @@ pub fn strip_using_and_register(
|
||||
crate::runtime::modules_registry::set(alias.clone(), Box::new(sb));
|
||||
let sb2 = crate::box_trait::StringBox::new(value.clone());
|
||||
crate::runtime::modules_registry::set(ns.clone(), Box::new(sb2));
|
||||
// Optional: autoload dylib when using kind="dylib" and NYASH_USING_DYLIB_AUTOLOAD=1
|
||||
if value.starts_with("dylib:") && std::env::var("NYASH_USING_DYLIB_AUTOLOAD").ok().as_deref() == Some("1") {
|
||||
let lib_path = value.trim_start_matches("dylib:");
|
||||
// Derive lib name from file stem (strip leading 'lib')
|
||||
let p = std::path::Path::new(lib_path);
|
||||
if let Some(stem) = p.file_stem().and_then(|s| s.to_str()) {
|
||||
let mut lib_name = stem.to_string();
|
||||
if lib_name.starts_with("lib") { lib_name = lib_name.trim_start_matches("lib").to_string(); }
|
||||
// Determine box list from using packages (prefer [using.<ns>].bid)
|
||||
let mut boxes: Vec<String> = Vec::new();
|
||||
if let Some(pkg) = using_ctx.packages.get(&ns) {
|
||||
if let Some(b) = &pkg.bid { boxes.push(b.clone()); }
|
||||
}
|
||||
if verbose { eprintln!("[using] autoload dylib: {} as {} boxes=[{}]", lib_path, lib_name, boxes.join(",")); }
|
||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||
let _ = host.read().unwrap().load_library_direct(&lib_name, lib_path, &boxes);
|
||||
}
|
||||
}
|
||||
} else if trace {
|
||||
eprintln!("[using] still unresolved: {} as {}", ns, alias);
|
||||
}
|
||||
@ -186,13 +207,31 @@ pub fn strip_using_and_register(
|
||||
&using_ctx.pending_modules,
|
||||
&using_ctx.using_paths,
|
||||
&using_ctx.aliases,
|
||||
&using_ctx.packages,
|
||||
ctx_dir,
|
||||
strict,
|
||||
verbose,
|
||||
) {
|
||||
Ok(value) => {
|
||||
let sb = crate::box_trait::StringBox::new(value.clone());
|
||||
crate::runtime::modules_registry::set(ns, Box::new(sb));
|
||||
let ns_clone = ns.clone();
|
||||
crate::runtime::modules_registry::set(ns_clone, Box::new(sb));
|
||||
// Optional: autoload dylib when using kind="dylib"
|
||||
if value.starts_with("dylib:") && std::env::var("NYASH_USING_DYLIB_AUTOLOAD").ok().as_deref() == Some("1") {
|
||||
let lib_path = value.trim_start_matches("dylib:");
|
||||
let p = std::path::Path::new(lib_path);
|
||||
if let Some(stem) = p.file_stem().and_then(|s| s.to_str()) {
|
||||
let mut lib_name = stem.to_string();
|
||||
if lib_name.starts_with("lib") { lib_name = lib_name.trim_start_matches("lib").to_string(); }
|
||||
let mut boxes: Vec<String> = Vec::new();
|
||||
if let Some(pkg) = using_ctx.packages.get(&ns) {
|
||||
if let Some(b) = &pkg.bid { boxes.push(b.clone()); }
|
||||
}
|
||||
if verbose { eprintln!("[using] autoload dylib: {} as {} boxes=[{}]", lib_path, lib_name, boxes.join(",")); }
|
||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||
let _ = host.read().unwrap().load_library_direct(&lib_name, lib_path, &boxes);
|
||||
}
|
||||
}
|
||||
Some(value)
|
||||
}
|
||||
Err(e) => return Err(format!("using: {}", e)),
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
pub mod bench;
|
||||
pub mod llvm;
|
||||
pub mod mir;
|
||||
pub mod vm_fallback;
|
||||
#[cfg(feature = "vm-legacy")]
|
||||
pub mod vm;
|
||||
pub mod pyvm;
|
||||
|
||||
@ -182,10 +182,19 @@ impl NyashRunner {
|
||||
}
|
||||
|
||||
// Optional: PyVM path. When NYASH_VM_USE_PY=1, emit MIR(JSON) and delegate execution to tools/pyvm_runner.py
|
||||
// Safety valve: if runner is not found or fails to launch, gracefully fall back to Rust VM
|
||||
if std::env::var("NYASH_VM_USE_PY").ok().as_deref() == Some("1") {
|
||||
match super::common_util::pyvm::run_pyvm_harness_lib(&module_vm, "vm") {
|
||||
Ok(code) => { process::exit(code); }
|
||||
Err(e) => { eprintln!("❌ PyVM error: {}", e); process::exit(1); }
|
||||
Err(e) => {
|
||||
// Fallback unless explicitly required
|
||||
if std::env::var("NYASH_VM_REQUIRE_PY").ok().as_deref() == Some("1") {
|
||||
eprintln!("❌ PyVM error: {}", e);
|
||||
process::exit(1);
|
||||
} else {
|
||||
eprintln!("[vm] PyVM unavailable ({}). Falling back to Rust VM…", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
55
src/runner/modes/vm_fallback.rs
Normal file
55
src/runner/modes/vm_fallback.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use super::super::NyashRunner;
|
||||
use crate::{parser::NyashParser, mir::MirCompiler, backend::MirInterpreter};
|
||||
use std::{fs, process};
|
||||
|
||||
impl NyashRunner {
|
||||
/// Lightweight VM fallback using the in-crate MIR interpreter.
|
||||
/// - Respects using preprocessing done earlier in the pipeline
|
||||
/// - Relies on global plugin host initialized by runner
|
||||
pub(crate) fn execute_vm_fallback_interpreter(&self, filename: &str) {
|
||||
// Read source
|
||||
let code = match fs::read_to_string(filename) {
|
||||
Ok(s) => s,
|
||||
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
|
||||
};
|
||||
// Using preprocessing (strip + autoload)
|
||||
let mut code2 = code;
|
||||
if crate::config::env::enable_using() {
|
||||
match crate::runner::modes::common_util::resolve::strip_using_and_register(self, &code2, filename) {
|
||||
Ok(s) => { code2 = s; }
|
||||
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);
|
||||
|
||||
// Parse -> expand macros -> compile MIR
|
||||
let ast = match NyashParser::parse_from_string(&code2) {
|
||||
Ok(ast) => ast,
|
||||
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
|
||||
};
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
|
||||
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
|
||||
let compile = match compiler.compile(ast) {
|
||||
Ok(c) => c,
|
||||
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||
};
|
||||
|
||||
// Optional barrier-elision for parity with VM path
|
||||
let mut module_vm = compile.module.clone();
|
||||
if std::env::var("NYASH_VM_ESCAPE_ANALYSIS").ok().as_deref() == Some("1") {
|
||||
let removed = crate::mir::passes::escape::escape_elide_barriers_vm(&mut module_vm);
|
||||
if removed > 0 { crate::cli_v!("[VM-fallback] escape_elide_barriers: removed {} barriers", removed); }
|
||||
}
|
||||
|
||||
// Execute via MIR interpreter
|
||||
let mut vm = MirInterpreter::new();
|
||||
match vm.execute_module(&module_vm) {
|
||||
Ok(_ret) => { /* interpreter already prints via println/console in program */ }
|
||||
Err(e) => {
|
||||
eprintln!("❌ VM fallback error: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user