Preparation for sharing

- rustfmt
- clippy
- comments
- README
This commit is contained in:
2023-05-25 19:14:24 +01:00
parent e99ade92ba
commit bc2714aad8
144 changed files with 3734 additions and 3243 deletions

View File

@@ -2,38 +2,41 @@ use std::rc::Rc;
use hashbrown::HashMap;
use crate::pipeline::error::ProjectError;
use crate::interner::{Token, Interner};
use crate::utils::iter::{box_once, box_empty};
use crate::utils::{Substack, pushed};
use crate::ast::{Expr, Constant};
use crate::pipeline::source_loader::{LoadedSourceTable, LoadedSource};
use crate::representations::tree::{Module, ModMember, ModEntry};
use crate::representations::sourcefile::{FileEntry, Member, absolute_path};
use super::collect_ops::InjectedOperatorsFn;
use super::{collect_ops, ProjectTree, ProjectExt};
use super::parse_file::parse_file;
use super::{collect_ops, ProjectExt, ProjectTree};
use crate::ast::{Constant, Expr};
use crate::interner::{Interner, Tok};
use crate::pipeline::error::ProjectError;
use crate::pipeline::source_loader::{LoadedSource, LoadedSourceTable};
use crate::representations::sourcefile::{absolute_path, FileEntry, Member};
use crate::representations::tree::{ModEntry, ModMember, Module};
use crate::utils::iter::{box_empty, box_once};
use crate::utils::{pushed, Substack};
#[derive(Debug)]
struct ParsedSource<'a> {
path: Vec<Token<String>>,
path: Vec<Tok<String>>,
loaded: &'a LoadedSource,
parsed: Vec<FileEntry>
parsed: Vec<FileEntry>,
}
pub fn split_path<'a>(path: &'a [Token<String>], proj: &'a ProjectTree)
-> (&'a [Token<String>], &'a [Token<String>])
{
let (end, body) = if let Some(s) = path.split_last() {s}
else {return (&[], &[])};
let mut module = proj.0.walk(body, false).expect("invalid path cannot be split");
pub fn split_path<'a>(
path: &'a [Tok<String>],
proj: &'a ProjectTree,
) -> (&'a [Tok<String>], &'a [Tok<String>]) {
let (end, body) = if let Some(s) = path.split_last() {
s
} else {
return (&[], &[]);
};
let mut module =
proj.0.walk(body, false).expect("invalid path cannot be split");
if let ModMember::Sub(m) = &module.items[end].member {
module = m.clone();
}
let file = module.extra.file.as_ref()
.map(|s| &path[..s.len()])
.unwrap_or(&path[..]);
let file =
module.extra.file.as_ref().map(|s| &path[..s.len()]).unwrap_or(path);
let subpath = &path[file.len()..];
(file, subpath)
}
@@ -41,7 +44,7 @@ pub fn split_path<'a>(path: &'a [Token<String>], proj: &'a ProjectTree)
/// Convert normalized, prefixed source into a module
fn source_to_module(
// level
path: Substack<Token<String>>,
path: Substack<Tok<String>>,
preparsed: &Module<impl Clone, impl Clone>,
// data
data: Vec<FileEntry>,
@@ -50,35 +53,38 @@ fn source_to_module(
filepath_len: usize,
) -> Rc<Module<Expr, ProjectExt>> {
let path_v = path.iter().rev_vec_clone();
let imports = data.iter()
.filter_map(|ent| if let FileEntry::Import(impv) = ent {
Some(impv.iter())
} else {None})
let imports = data
.iter()
.filter_map(|ent| {
if let FileEntry::Import(impv) = ent {
Some(impv.iter())
} else {
None
}
})
.flatten()
.cloned()
.collect::<Vec<_>>();
let imports_from = imports.iter()
let imports_from = imports
.iter()
.map(|imp| {
let mut imp_path_v = i.r(imp.path).clone();
imp_path_v.push(imp.name.expect("imports normalized"));
let mut abs_path = absolute_path(
&path_v,
&imp_path_v,
i, &|n| preparsed.items.contains_key(&n)
).expect("tested in preparsing");
let mut abs_path =
absolute_path(&path_v, &imp_path_v, i).expect("tested in preparsing");
let name = abs_path.pop().expect("importing the global context");
(name, i.i(&abs_path))
})
.collect::<HashMap<_, _>>();
let exports = data.iter()
let exports = data
.iter()
.flat_map(|ent| {
let mk_ent = |name| (name, i.i(&pushed(&path_v, name)));
match ent {
FileEntry::Export(names)
=> Box::new(names.iter().copied().map(mk_ent)),
FileEntry::Export(names) => Box::new(names.iter().copied().map(mk_ent)),
FileEntry::Exported(mem) => match mem {
Member::Constant(constant) => box_once(mk_ent(constant.name)),
Member::Namespace(name, _) => box_once(mk_ent(*name)),
Member::Namespace(ns) => box_once(mk_ent(ns.name)),
Member::Rule(rule) => {
let mut names = Vec::new();
for e in rule.source.iter() {
@@ -89,13 +95,14 @@ fn source_to_module(
})
}
Box::new(names.into_iter())
}
}
_ => box_empty()
},
},
_ => box_empty(),
}
})
.collect::<HashMap<_, _>>();
let rules = data.iter()
let rules = data
.iter()
.filter_map(|ent| match ent {
FileEntry::Exported(Member::Rule(rule)) => Some(rule),
FileEntry::Internal(Member::Rule(rule)) => Some(rule),
@@ -103,38 +110,51 @@ fn source_to_module(
})
.cloned()
.collect::<Vec<_>>();
let items = data.into_iter()
let items = data
.into_iter()
.filter_map(|ent| match ent {
FileEntry::Exported(Member::Namespace(name, body)) => {
let prep_member = &preparsed.items[&name].member;
let new_prep = if let ModMember::Sub(s) = prep_member {s.as_ref()}
else { panic!("preparsed missing a submodule") };
FileEntry::Exported(Member::Namespace(ns)) => {
let prep_member = &preparsed.items[&ns.name].member;
let new_prep = if let ModMember::Sub(s) = prep_member {
s.as_ref()
} else {
panic!("preparsed missing a submodule")
};
let module = source_to_module(
path.push(name),
new_prep, body, i, filepath_len
path.push(ns.name),
new_prep,
ns.body,
i,
filepath_len,
);
let member = ModMember::Sub(module);
Some((name, ModEntry{ exported: true, member }))
}
FileEntry::Internal(Member::Namespace(name, body)) => {
let prep_member = &preparsed.items[&name].member;
let new_prep = if let ModMember::Sub(s) = prep_member {s.as_ref()}
else { panic!("preparsed missing a submodule") };
Some((ns.name, ModEntry { exported: true, member }))
},
FileEntry::Internal(Member::Namespace(ns)) => {
let prep_member = &preparsed.items[&ns.name].member;
let new_prep = if let ModMember::Sub(s) = prep_member {
s.as_ref()
} else {
panic!("preparsed missing a submodule")
};
let module = source_to_module(
path.push(name),
new_prep, body, i, filepath_len
path.push(ns.name),
new_prep,
ns.body,
i,
filepath_len,
);
let member = ModMember::Sub(module);
Some((name, ModEntry{ exported: false, member }))
}
FileEntry::Exported(Member::Constant(Constant{ name, value })) => {
Some((ns.name, ModEntry { exported: false, member }))
},
FileEntry::Exported(Member::Constant(Constant { name, value })) => {
let member = ModMember::Item(value);
Some((name, ModEntry{ exported: true, member }))
}
FileEntry::Internal(Member::Constant(Constant{ name, value })) => {
Some((name, ModEntry { exported: true, member }))
},
FileEntry::Internal(Member::Constant(Constant { name, value })) => {
let member = ModMember::Item(value);
Some((name, ModEntry{ exported: false, member }))
}
Some((name, ModEntry { exported: false, member }))
},
_ => None,
})
.collect::<HashMap<_, _>>();
@@ -150,15 +170,15 @@ fn source_to_module(
imports_from,
exports,
rules,
file: Some(path_v[..filepath_len].to_vec())
}
file: Some(path_v[..filepath_len].to_vec()),
},
})
}
fn files_to_module(
path: Substack<Token<String>>,
path: Substack<Tok<String>>,
files: &[ParsedSource],
i: &Interner
i: &Interner,
) -> Rc<Module<Expr, ProjectExt>> {
let lvl = path.len();
let path_v = path.iter().rev_vec_clone();
@@ -167,19 +187,22 @@ fn files_to_module(
path,
files[0].loaded.preparsed.0.as_ref(),
files[0].parsed.clone(),
i, path.len()
)
i,
path.len(),
);
}
let items = files.group_by(|a, b| a.path[lvl] == b.path[lvl]).into_iter()
let items = files
.group_by(|a, b| a.path[lvl] == b.path[lvl])
.map(|files| {
let namespace = files[0].path[lvl];
let subpath = path.push(namespace);
let module = files_to_module(subpath, files, i);
let member = ModMember::Sub(module);
(namespace, ModEntry{ exported: true, member })
(namespace, ModEntry { exported: true, member })
})
.collect::<HashMap<_, _>>();
let exports: HashMap<_, _> = items.keys()
let exports: HashMap<_, _> = items
.keys()
.copied()
.map(|name| (name, i.i(&pushed(&path_v, name))))
.collect();
@@ -188,38 +211,44 @@ fn files_to_module(
// i.extern_all(&path_v[..]).join("::"),
// exports.keys().map(|t| i.r(*t)).join(", ")
// );
Rc::new(Module{
Rc::new(Module {
items,
imports: vec![],
extra: ProjectExt {
exports,
imports_from: HashMap::new(),
rules: vec![], file: None,
}
rules: vec![],
file: None,
},
})
}
pub fn build_tree<'a>(
pub fn build_tree(
files: LoadedSourceTable,
i: &Interner,
prelude: &[FileEntry],
injected: &impl InjectedOperatorsFn,
) -> Result<ProjectTree, Rc<dyn ProjectError>> {
let ops_cache = collect_ops::mk_cache(&files, i, injected);
let mut entries = files.iter()
.map(|(path, loaded)| Ok((
i.r(*path),
loaded,
parse_file(*path, &files, &ops_cache, i, prelude)?
)))
let mut entries = files
.iter()
.map(|(path, loaded)| {
Ok((
i.r(*path),
loaded,
parse_file(*path, &files, &ops_cache, i, prelude)?,
))
})
.collect::<Result<Vec<_>, Rc<dyn ProjectError>>>()?;
// sort by similarity, then longest-first
entries.sort_unstable_by(|a, b| a.0.cmp(&b.0).reverse());
let files = entries.into_iter()
.map(|(path, loaded, parsed)| ParsedSource{
loaded, parsed,
path: path.clone()
entries.sort_unstable_by(|a, b| a.0.cmp(b.0).reverse());
let files = entries
.into_iter()
.map(|(path, loaded, parsed)| ParsedSource {
loaded,
parsed,
path: path.clone(),
})
.collect::<Vec<_>>();
Ok(ProjectTree(files_to_module(Substack::Bottom, &files, i)))
}
}