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:
2023-09-17 16:37:39 +01:00
parent 1078835e8b
commit 7396078304
84 changed files with 563 additions and 721 deletions

View File

@@ -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)
}
}
}

View File

@@ -1,4 +1,3 @@
// mod alias_cache;
mod resolve_aliases;
mod walk_with_links;

View File

@@ -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,

View File

@@ -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,