forked from Orchid/orchid
Added directfs
Added a very rudimentary file I/O system suitable for experimenting with the language further. A better one will be designed when we have sensible error management.
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
use std::slice;
|
||||
|
||||
use chumsky::primitive::Container;
|
||||
use hashbrown::HashMap;
|
||||
|
||||
use crate::representations::project::{ProjectMod, ItemKind, ProjectEntry};
|
||||
use crate::tree::ModMember;
|
||||
use crate::utils::{pushed, unwrap_or};
|
||||
use crate::{ProjectTree, VName, Tok, NameLike};
|
||||
|
||||
use super::walk_with_links::{walk_with_links, Target};
|
||||
|
||||
pub struct AliasCache {
|
||||
data: HashMap<Vec<Tok<String>>, Option<Vec<Tok<String>>>>,
|
||||
}
|
||||
impl AliasCache {
|
||||
pub fn new() -> Self {
|
||||
Self { data: HashMap::new() }
|
||||
}
|
||||
|
||||
/// Finds the absolute nsname corresponding to the given name in the given
|
||||
/// context, if it's imported. If the name is defined locally, returns None
|
||||
/// to avoid allocating several vectors for every local variable.
|
||||
pub fn resolv_name<'a>(
|
||||
&'a mut self,
|
||||
root: &ProjectMod<VName>,
|
||||
location: &[Tok<String>],
|
||||
name: Tok<String>
|
||||
) -> Option<&'a [Tok<String>]> {
|
||||
let full_path = pushed(location, name);
|
||||
if let Some(result) = self.data.get(&full_path) {
|
||||
return result.as_deref();
|
||||
}
|
||||
let (ent, finalp) = walk_with_links(root, location.iter().cloned())
|
||||
.expect("This path should be valid");
|
||||
let m = unwrap_or!{ent => Target::Mod; panic!("Must be a module")};
|
||||
let result = m.extra.imports_from.get(&name).map(|next| {
|
||||
self.resolv_name(root, &next, name).unwrap_or(&next)
|
||||
});
|
||||
self.data.insert(full_path, result.map(|s| s.to_vec()));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Find the absolute target of a
|
||||
pub fn resolv_vec<'a>(
|
||||
&'a mut self,
|
||||
root: &ProjectMod<VName>,
|
||||
modname: &[Tok<String>],
|
||||
vname: &[Tok<String>],
|
||||
) -> Option<&'a [Tok<String>]> {
|
||||
let (name, ns) = vname.split_last().expect("name cannot be empty");
|
||||
if ns.is_empty() {
|
||||
self.resolv_name(modname, name)
|
||||
} else {
|
||||
let origin = self.resolv_vec(modname, ns)?;
|
||||
self.resolv_name(origin, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// mod alias_cache;
|
||||
mod resolve_aliases;
|
||||
mod walk_with_links;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::tree::{ModEntry, ModMember, Module};
|
||||
use crate::utils::pure_push::pushed;
|
||||
use crate::{Interner, ProjectTree, Tok, VName};
|
||||
|
||||
#[must_use]
|
||||
fn resolve_aliases_rec(
|
||||
root: &ProjectMod<VName>,
|
||||
module: &ProjectMod<VName>,
|
||||
@@ -26,7 +27,6 @@ fn resolve_aliases_rec(
|
||||
let full_name = (module.extra.path.iter()).chain(n.iter()).cloned();
|
||||
match walk_with_links(root, full_name, false) {
|
||||
Ok(rep) => Some(rep.abs_path),
|
||||
// Ok(_) => None,
|
||||
Err(e) => {
|
||||
let leftovers = e.tail.collect::<Vec<_>>();
|
||||
if !leftovers.is_empty() {
|
||||
@@ -87,6 +87,7 @@ fn resolve_aliases_rec(
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn resolve_aliases(
|
||||
project: ProjectTree<VName>,
|
||||
updated: &impl Fn(&[Tok<String>]) -> bool,
|
||||
|
||||
@@ -12,6 +12,7 @@ pub enum Target<'a, N: NameLike> {
|
||||
Leaf(&'a ProjectItem<N>),
|
||||
}
|
||||
|
||||
#[must_use = "this is the sole product of this function"]
|
||||
pub struct WalkReport<'a, N: NameLike> {
|
||||
pub target: Target<'a, N>,
|
||||
pub abs_path: VName,
|
||||
|
||||
Reference in New Issue
Block a user