pub(crate) use std::collections::BTreeSet;
pub(crate) use std::path::{Path, PathBuf};
pub(crate) use crate::diagnostic::Diagnostic;
pub(crate) use crate::span::Span;
#[derive(Clone, Debug)]
pub(crate) struct ModuleInfo {
pub(crate) name: String,
pub(crate) file_path: PathBuf,
pub(crate) source: String,
pub(crate) dependencies: Vec<String>,
}
mod resolver;
use resolver::*;
pub(crate) fn resolve_modules(entry_path: &Path) -> Result<Vec<ModuleInfo>, Vec<Diagnostic>> {
let mut resolver = ModuleResolver::new(entry_path)?;
resolver.discover_all()?;
resolver.topological_sort()
}
pub(crate) fn resolve_modules_with_deps(
entry_path: &Path,
dep_dirs: Vec<PathBuf>,
) -> Result<Vec<ModuleInfo>, Vec<Diagnostic>> {
let mut resolver = ModuleResolver::new(entry_path)?;
resolver.dep_dirs = dep_dirs;
resolver.discover_all()?;
resolver.topological_sort()
}
fn find_lib_dir(env_var: &str, dir_name: &str) -> Option<PathBuf> {
if let Ok(p) = std::env::var(env_var) {
let path = PathBuf::from(p);
if path.is_dir() {
return Some(path);
}
}
if let Ok(exe) = std::env::current_exe() {
if let Some(dir) = exe.parent() {
let path = dir.join(dir_name);
if path.is_dir() {
return Some(path);
}
if let Some(parent) = dir.parent() {
let path = parent.join(dir_name);
if path.is_dir() {
return Some(path);
}
if let Some(grandparent) = parent.parent() {
let path = grandparent.join(dir_name);
if path.is_dir() {
return Some(path);
}
}
}
}
}
if let Ok(cwd) = std::env::current_dir() {
let mut dir = cwd.as_path();
loop {
let candidate = dir.join(dir_name);
if candidate.is_dir() {
return Some(candidate);
}
match dir.parent() {
Some(parent) => dir = parent,
None => break,
}
}
}
None
}
pub(crate) fn find_stdlib_dir() -> Option<PathBuf> {
find_lib_dir("TRIDENT_STDLIB", "std")
}
pub(crate) fn find_os_dir() -> Option<PathBuf> {
if let Some(dir) = find_lib_dir("TRIDENT_OSLIB", "os") {
return Some(dir);
}
if let Ok(p) = std::env::var("TRIDENT_EXTLIB") {
let path = PathBuf::from(p);
if path.is_dir() {
return Some(path);
}
}
None
}
fn legacy_stdlib_fallback(name: &str) -> Option<&'static str> {
match name {
"std.assert" => Some("vm.core.assert"),
"std.convert" => Some("vm.core.convert"),
"std.field" => Some("vm.core.field"),
"std.u32" => Some("vm.core.u32"),
"std.io" => Some("vm.io.io"),
"std.mem" => Some("vm.io.mem"),
"std.storage" => Some("std.io.storage"),
"std.hash" => Some("vm.crypto.hash"),
"std.merkle" => Some("std.crypto.merkle"),
"std.auth" => Some("std.crypto.auth"),
"std.core.field" => Some("vm.core.field"),
"std.core.convert" => Some("vm.core.convert"),
"std.core.u32" => Some("vm.core.u32"),
"std.core.assert" => Some("vm.core.assert"),
"std.io.io" => Some("vm.io.io"),
"std.io.mem" => Some("vm.io.mem"),
"std.crypto.hash" => Some("vm.crypto.hash"),
"std.xfield" => Some("os.neptune.xfield"),
"std.kernel" => Some("os.neptune.kernel"),
"std.utxo" => Some("os.neptune.utxo"),
"ext.triton.xfield" => Some("os.neptune.xfield"),
"ext.triton.kernel" => Some("os.neptune.kernel"),
"ext.triton.utxo" => Some("os.neptune.utxo"),
"ext.triton.proof" => Some("os.neptune.proof"),
"ext.triton.recursive" => Some("os.neptune.recursive"),
"neptune.ext.kernel" => Some("os.neptune.kernel"),
"neptune.ext.utxo" => Some("os.neptune.utxo"),
"neptune.ext.xfield" => Some("os.neptune.xfield"),
"neptune.ext.proof" => Some("os.neptune.proof"),
"neptune.ext.recursive" => Some("os.neptune.recursive"),
_ if name.starts_with("ext.") => {
None }
_ => None,
}
}
#[cfg(test)]
mod tests;