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:
Selfhosting Dev
2025-09-24 21:45:27 +09:00
parent 6755d9bde1
commit c0978634d9
150 changed files with 2119 additions and 3214 deletions

View File

@ -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",

View File

@ -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)),

View File

@ -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;

View File

@ -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);
}
}
}
}

View 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);
}
}
}
}