Span trace utilities and runner source hint

This commit is contained in:
nyash-codex
2025-11-24 14:17:02 +09:00
parent 3154903121
commit 466e636af6
106 changed files with 4597 additions and 958 deletions

View File

@ -113,14 +113,12 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
};
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
&code,
&e,
);
process::exit(1);
}
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename, &code, &e,
);
process::exit(1);
}
};
// Optional macro expansion dump (no-op expansion for now)
let ast2 = if crate::r#macro::enabled() {
@ -144,14 +142,12 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
};
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
&code,
&e,
);
process::exit(1);
}
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename, &code, &e,
);
process::exit(1);
}
};
let expanded = if crate::r#macro::enabled() {
let a = crate::r#macro::maybe_expand_and_dump(&ast, false);

View File

@ -159,7 +159,13 @@ impl NyashRunner {
if let Ok(ast0) = NyashParser::parse_from_string(code) {
let ast = crate::r#macro::maybe_expand_and_dump(&ast0, false);
let mut mc = MirCompiler::new();
if let Ok(cr) = mc.compile(ast) {
if let Ok(cr) =
crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mc,
ast,
None,
)
{
let mut vm = VM::new();
let _ = vm.execute_module(&cr.module);
}
@ -191,7 +197,13 @@ impl NyashRunner {
if let Ok(ast0) = NyashParser::parse_from_string(code) {
let ast = crate::r#macro::maybe_expand_and_dump(&ast0, false);
let mut mc = MirCompiler::new();
if let Ok(cr) = mc.compile(ast) {
if let Ok(cr) =
crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mc,
ast,
None,
)
{
let mut vm = VM::new();
let _ = vm.execute_module(&cr.module);
}
@ -214,7 +226,12 @@ impl NyashRunner {
let ast0 = NyashParser::parse_from_string(code).map_err(|e| format!("vm parse: {}", e))?;
let ast = crate::r#macro::maybe_expand_and_dump(&ast0, false);
let mut mc = MirCompiler::new();
let cr = mc.compile(ast).map_err(|e| format!("vm compile: {}", e))?;
let cr = crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mc,
ast,
None,
)
.map_err(|e| format!("vm compile: {}", e))?;
let mut vm = VM::new();
let out = vm
.execute_module(&cr.module)

View File

@ -71,9 +71,7 @@ fn extract_line_col(err: &ParseError) -> (Option<usize>, Option<usize>) {
ParseError::UnsupportedNamespace { line, .. } => (Some(*line), None),
ParseError::ExpectedIdentifier { line } => (Some(*line), None),
ParseError::TokenizeError(te) => match te {
TokenizeError::UnexpectedCharacter { line, column, .. } => {
(Some(*line), Some(*column))
}
TokenizeError::UnexpectedCharacter { line, column, .. } => (Some(*line), Some(*column)),
TokenizeError::UnterminatedString { line }
| TokenizeError::InvalidNumber { line }
| TokenizeError::UnterminatedComment { line } => (Some(*line), None),

View File

@ -13,6 +13,7 @@ pub mod io;
pub mod plugin_guard;
pub mod provider_registry;
pub mod pyvm;
pub mod source_hint;
pub mod resolve;
pub mod selfhost;
pub mod selfhost_exe;

View File

@ -353,10 +353,12 @@ pub fn collect_using_and_strip(
}
} else {
// ⚠️ Phase 0.3: User-friendly "Did you mean?" suggestions
let similar: Vec<_> = using_ctx.aliases.keys()
let similar: Vec<_> = using_ctx
.aliases
.keys()
.filter(|k| {
k.to_lowercase().contains(&target_unquoted.to_lowercase()) ||
target_unquoted.to_lowercase().contains(&k.to_lowercase())
k.to_lowercase().contains(&target_unquoted.to_lowercase())
|| target_unquoted.to_lowercase().contains(&k.to_lowercase())
})
.take(3)
.collect();
@ -374,9 +376,13 @@ pub fn collect_using_and_strip(
}
if using_ctx.aliases.is_empty() {
err_msg.push_str("\n\n⚠️ No aliases loaded (check TOML parse errors above)");
err_msg
.push_str("\n\n⚠️ No aliases loaded (check TOML parse errors above)");
} else {
err_msg.push_str(&format!("\n\nAvailable modules: {} aliases", using_ctx.aliases.len()));
err_msg.push_str(&format!(
"\n\nAvailable modules: {} aliases",
using_ctx.aliases.len()
));
}
err_msg.push_str("\n\n📝 Suggestions:");

View File

@ -0,0 +1,17 @@
use crate::mir::{MirCompileResult, MirCompiler};
use crate::ast::ASTNode;
/// Compile AST with a source filename hint, reducing call-site duplication.
/// Falls back to regular compile when filename is None or empty.
pub fn compile_with_source_hint(
compiler: &mut MirCompiler,
ast: ASTNode,
filename: Option<&str>,
) -> Result<MirCompileResult, String> {
if let Some(f) = filename {
if !f.is_empty() {
return compiler.compile_with_source(ast, Some(f));
}
}
compiler.compile_with_source(ast, None)
}

View File

@ -72,9 +72,7 @@ impl NyashRunner {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
code_ref,
&e,
filename, code_ref, &e,
);
// Enhanced context: list merged prelude files if any (from text-merge path)
let preludes =
@ -107,7 +105,11 @@ impl NyashRunner {
// Compile to MIR
let mut mir_compiler = MirCompiler::new();
let compile_result = match mir_compiler.compile(ast) {
let compile_result = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mir_compiler,
ast,
Some(filename),
) {
Ok(result) => result,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);
@ -290,7 +292,8 @@ impl NyashRunner {
println!("🔧 Mock LLVM Backend Execution:");
println!(" Build with --features llvm-inkwell-legacy for Rust/inkwell backend, or set NYASH_LLVM_OBJ_OUT and NYASH_LLVM_USE_HARNESS=1 for harness.");
// NamingBox SSOT: Select entry (arity-aware, Main.main → main fallback)
let entry = crate::runner::modes::common_util::entry_selection::select_entry_function(&module);
let entry =
crate::runner::modes::common_util::entry_selection::select_entry_function(&module);
if let Some(main_func) = module.functions.get(&entry) {
for (_bid, block) in &main_func.blocks {
for inst in &block.instructions {

View File

@ -22,9 +22,7 @@ impl NyashRunner {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
&code,
&e,
filename, &code, &e,
);
process::exit(1);
}
@ -34,7 +32,11 @@ impl NyashRunner {
// Compile to MIR (opt passes configurable)
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile_result = match mir_compiler.compile(ast) {
let compile_result = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mir_compiler,
ast,
Some(filename),
) {
Ok(result) => result,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);

View File

@ -44,7 +44,11 @@ impl NyashRunner {
// Compile to MIR (opt passes configurable)
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile_result = match mir_compiler.compile(ast) {
let compile_result = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mir_compiler,
ast,
Some(filename),
) {
Ok(result) => result,
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
};

View File

@ -133,23 +133,25 @@ pub fn execute_pyvm_only(runner: &NyashRunner, filename: &str) {
if crate::config::env::env_bool("NYASH_PYVM_DUMP_CODE") {
eprintln!("[pyvm-code]\n{}", code);
}
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
&code,
&e,
);
process::exit(1);
}
};
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename, &code, &e,
);
process::exit(1);
}
};
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
let ast = crate::runner::modes::macro_child::normalize_core_pass(&ast);
// Compile to MIR (respect default optimizer setting)
let mut mir_compiler = MirCompiler::with_options(true);
let mut compile_result = match mir_compiler.compile(ast) {
let mut compile_result = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mir_compiler,
ast,
Some(filename),
) {
Ok(result) => result,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);

View File

@ -194,7 +194,9 @@ impl NyashRunner {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename, &code_final, &e,
filename,
&code_final,
&e,
);
// Enhanced context: list merged prelude files if any
let preludes =
@ -407,7 +409,11 @@ impl NyashRunner {
// Compile to MIR
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile = match compiler.compile(ast) {
let compile = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut compiler,
ast,
Some(filename),
) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);

View File

@ -116,9 +116,7 @@ impl NyashRunner {
Ok(ast) => ast,
Err(e) => {
crate::runner::modes::common_util::diag::print_parse_error_with_context(
filename,
&code2,
&e,
filename, &code2, &e,
);
process::exit(1);
}
@ -271,7 +269,11 @@ impl NyashRunner {
}
}
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile = match compiler.compile(ast) {
let compile = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut compiler,
ast,
Some(filename),
) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);
@ -357,7 +359,7 @@ impl NyashRunner {
impl NyashRunner {
/// Small helper to continue fallback execution once AST is prepared
#[allow(dead_code)]
fn execute_vm_fallback_from_ast(&self, _filename: &str, ast: nyash_rust::ast::ASTNode) {
fn execute_vm_fallback_from_ast(&self, filename: &str, ast: nyash_rust::ast::ASTNode) {
use crate::{
backend::MirInterpreter,
box_factory::{BoxFactory, RuntimeError},
@ -471,7 +473,11 @@ impl NyashRunner {
}
// Compile to MIR and execute via interpreter
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
let module = match compiler.compile(ast) {
let module = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut compiler,
ast,
Some(filename),
) {
Ok(r) => r.module,
Err(e) => {
eprintln!("❌ MIR compilation error: {}", e);

View File

@ -30,7 +30,11 @@ impl NyashRunner {
// Compile to MIR
let mut mir_compiler = MirCompiler::new();
let compile_result = match mir_compiler.compile(ast) {
let compile_result = match crate::runner::modes::common_util::source_hint::compile_with_source_hint(
&mut mir_compiler,
ast,
Some(filename),
) {
Ok(result) => result,
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
};

View File

@ -27,13 +27,7 @@ pub(super) fn build_stage1_args(groups: &CliGroups) -> Stage1Args {
// Prefer new env (NYASH_STAGE1_*) and fall back to legacy names to keep compatibility.
let source = std::env::var("NYASH_STAGE1_INPUT")
.ok()
.or_else(|| {
groups
.input
.file
.as_ref()
.cloned()
})
.or_else(|| groups.input.file.as_ref().cloned())
.or_else(|| std::env::var("STAGE1_SOURCE").ok())
.or_else(|| std::env::var("STAGE1_INPUT").ok());
@ -43,12 +37,11 @@ pub(super) fn build_stage1_args(groups: &CliGroups) -> Stage1Args {
let emit_program = matches!(
mode_env.as_deref(),
Some("emit-program") | Some("emit-program-json")
) || std::env::var("STAGE1_EMIT_PROGRAM_JSON")
.ok()
.as_deref()
== Some("1");
let emit_mir = matches!(mode_env.as_deref(), Some("emit-mir") | Some("emit-mir-json"))
|| std::env::var("STAGE1_EMIT_MIR_JSON").ok().as_deref() == Some("1");
) || std::env::var("STAGE1_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1");
let emit_mir = matches!(
mode_env.as_deref(),
Some("emit-mir") | Some("emit-mir-json")
) || std::env::var("STAGE1_EMIT_MIR_JSON").ok().as_deref() == Some("1");
let mut args: Vec<String> = Vec::new();
let mut source_env: Option<String> = None;

View File

@ -23,23 +23,11 @@ pub(super) fn configure_stage1_env(
// Unified Stage-1 env (NYASH_STAGE1_*) — derive from legacy if unset to keep compatibility.
if std::env::var("NYASH_STAGE1_MODE").is_err() {
if std::env::var("STAGE1_EMIT_PROGRAM_JSON")
.ok()
.as_deref()
== Some("1")
{
if std::env::var("STAGE1_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1") {
cmd.env("NYASH_STAGE1_MODE", "emit-program");
} else if std::env::var("STAGE1_EMIT_MIR_JSON")
.ok()
.as_deref()
== Some("1")
{
} else if std::env::var("STAGE1_EMIT_MIR_JSON").ok().as_deref() == Some("1") {
cmd.env("NYASH_STAGE1_MODE", "emit-mir");
} else if std::env::var("NYASH_USE_STAGE1_CLI")
.ok()
.as_deref()
== Some("1")
{
} else if std::env::var("NYASH_USE_STAGE1_CLI").ok().as_deref() == Some("1") {
cmd.env("NYASH_STAGE1_MODE", "run");
}
}

View File

@ -33,11 +33,7 @@ impl NyashRunner {
}
// Guard: skip if child invocation
if std::env::var("NYASH_STAGE1_CLI_CHILD")
.ok()
.as_deref()
== Some("1")
{
if std::env::var("NYASH_STAGE1_CLI_CHILD").ok().as_deref() == Some("1") {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("2") {
eprintln!("[stage1-bridge/trace] skip: NYASH_STAGE1_CLI_CHILD=1");
}
@ -45,11 +41,7 @@ impl NyashRunner {
}
// Guard: skip if not enabled
if std::env::var("NYASH_USE_STAGE1_CLI")
.ok()
.as_deref()
!= Some("1")
{
if std::env::var("NYASH_USE_STAGE1_CLI").ok().as_deref() != Some("1") {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("2") {
eprintln!("[stage1-bridge/trace] skip: NYASH_USE_STAGE1_CLI!=1");
}
@ -83,8 +75,8 @@ impl NyashRunner {
std::path::PathBuf::from("target/release/nyash")
});
let mut cmd = std::process::Command::new(exe);
let entry_fn = std::env::var("NYASH_ENTRY")
.unwrap_or_else(|_| "Stage1CliMain.main/0".to_string());
let entry_fn =
std::env::var("NYASH_ENTRY").unwrap_or_else(|_| "Stage1CliMain.main/0".to_string());
cmd.arg(&entry).arg("--");
for a in &args_result.args {
cmd.arg(a);