use nepali_core::{Parser, Stmt};
use std::collections::HashSet;
use std::fs;
use std::path::{Path, PathBuf};
pub fn load(entry_path: &Path) -> Result<Vec<Stmt>, String> {
let mut visited = HashSet::new();
let mut out = Vec::new();
load_into(entry_path, &mut visited, &mut out)?;
Ok(out)
}
fn load_into(
path: &Path,
visited: &mut HashSet<PathBuf>,
out: &mut Vec<Stmt>,
) -> Result<(), String> {
let canonical = path
.canonicalize()
.map_err(|e| format!("cannot resolve {}: {e}", path.display()))?;
if !visited.insert(canonical.clone()) {
return Ok(()); }
let src = fs::read_to_string(&canonical)
.map_err(|e| format!("cannot read {}: {e}", canonical.display()))?;
let mut parser = Parser::new(&src);
let program = parser
.parse_program()
.map_err(|e| format!("{}: parse error: {e}", canonical.display()))?;
let dir = canonical
.parent()
.map(Path::to_path_buf)
.unwrap_or_else(|| PathBuf::from("."));
for stmt in program {
match stmt {
Stmt::Import(import_path) => {
load_into(&dir.join(&import_path), visited, out)?;
}
other => out.push(other),
}
}
Ok(())
}