Span trace utilities and runner source hint
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:");
|
||||
|
||||
17
src/runner/modes/common_util/source_hint.rs
Normal file
17
src/runner/modes/common_util/source_hint.rs
Normal 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)
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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); }
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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); }
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user