September-october commit

- manual parser
- stl refinements
- all language constructs are now Send
This commit is contained in:
2023-10-11 18:27:50 +01:00
parent 56679dcc01
commit 86e520e8b8
127 changed files with 1666 additions and 1872 deletions

View File

@@ -13,7 +13,7 @@ use crate::sourcefile::{
};
use crate::tree::{ModEntry, ModMember, Module};
use crate::utils::get_or::get_or_default;
use crate::utils::pure_push::pushed_ref;
use crate::utils::pure_seq::pushed_ref;
use crate::{Tok, VName};
#[must_use = "A submodule may not be integrated into the tree"]
@@ -28,7 +28,7 @@ pub struct TreeReport {
pub fn build_tree(
path: &VName,
source: Vec<FileEntry>,
Module { entries, extra }: PreMod,
Module { entries, .. }: PreMod,
imports: ImpMod,
prelude: &[FileEntry],
) -> ProjectResult<TreeReport> {
@@ -56,20 +56,11 @@ pub fn build_tree(
MemberKind::Constant(Constant { name, value }) => {
consts.insert(name, value /* .prefix(path, &|_| false) */);
},
MemberKind::Operators(_) => (),
MemberKind::Rule(rule) => rule_fragments.push(rule),
},
}
}
let mod_details = extra.details().expect("Directories handled elsewhere");
let rules = (mod_details.patterns.iter())
.zip(rule_fragments.into_iter())
.map(|(p, Rule { prio, template: t, .. })| {
// let p = p.iter().map(|e| e.prefix(path, &|_| false)).collect();
// let t = t.into_iter().map(|e| e.prefix(path, &|_| false)).collect();
Rule { pattern: p.clone(), prio, template: t }
})
.collect();
let rules = rule_fragments;
let (pre_subs, pre_items) = (entries.into_iter())
.partition_map::<HashMap<_, _>, HashMap<_, _>, _, _, _>(
|(k, ModEntry { exported, member })| match member {
@@ -98,7 +89,7 @@ pub fn build_tree(
Ok((k, ModEntry { exported, member }))
})
.chain((pre_items.into_iter()).map(
|(k, (exported, PreItem { has_value, is_op, location }))| {
|(k, (exported, PreItem { has_value, location }))| {
let item = match imports_from.get(&k) {
Some(_) if has_value => {
// Local value cannot be assigned to imported key
@@ -112,12 +103,10 @@ pub fn build_tree(
},
None => {
let k = consts.remove(&k).map_or(ItemKind::None, ItemKind::Const);
ProjectItem { is_op, kind: k }
},
Some(report) => ProjectItem {
is_op: is_op | report.is_op,
kind: ItemKind::Alias(report.source.clone()),
ProjectItem { kind: k }
},
Some(report) =>
ProjectItem { kind: ItemKind::Alias(report.source.clone()) },
};
Ok((k, ModEntry { exported, member: ModMember::Item(item) }))
},
@@ -129,7 +118,6 @@ pub fn build_tree(
exported: false,
member: ModMember::Item(ProjectItem {
kind: ItemKind::Alias(from.source.clone()),
is_op: from.is_op,
}),
})
});

View File

@@ -11,7 +11,7 @@ use crate::representations::project::ImpReport;
use crate::sourcefile::{absolute_path, Import};
use crate::tree::{ErrKind, ModEntry, ModMember, Module, WalkError};
use crate::utils::boxed_iter::{box_chain, box_once};
use crate::utils::pure_push::pushed_ref;
use crate::utils::pure_seq::pushed_ref;
use crate::utils::{unwrap_or, BoxedIter};
use crate::{Interner, ProjectTree, Tok, VName};
@@ -65,17 +65,13 @@ pub fn assert_visible_overlay<'a>(
})
}
pub fn process_donor_module<'a, TItem: Clone>(
module: &'a Module<TItem, impl Clone>,
pub fn process_donor_module<TItem: Clone>(
module: &Module<TItem, impl Clone>,
abs_path: Rc<VName>,
is_op: impl Fn(&TItem) -> bool + 'a,
) -> impl Iterator<Item = (Tok<String>, VName, bool)> + 'a {
(module.entries.iter()).filter(|(_, ent)| ent.exported).map(
move |(n, ent)| {
let is_op = ent.item().map_or(false, &is_op);
(n.clone(), pushed_ref(abs_path.as_ref(), n.clone()), is_op)
},
)
) -> impl Iterator<Item = (Tok<String>, VName)> + '_ {
(module.entries.iter())
.filter(|(_, ent)| ent.exported)
.map(move |(n, _)| (n.clone(), pushed_ref(abs_path.as_ref(), n.clone())))
}
pub fn import_tree(
@@ -99,14 +95,7 @@ pub fn import_tree(
// println!("Old root: {:#?}", &prev_root.0);
panic!("{}", e.at(location))
})?;
let is_op = (root.0.walk1_ref(&[], &abs_path, false))
.map(|(ent, _)| ent.item().map_or(false, |i| i.is_op))
.or_else(|e| if e.kind == ErrKind::Missing {
(prev_root.0.walk1_ref(&[], &abs_path, false))
.map(|(ent, _)| ent.item().map_or(false, |i| i.is_op))
} else {Err(e)})
.map_err(|e| e.at(location))?;
box_once((name.clone(), abs_path, is_op))
box_once((name.clone(), abs_path))
} else {
let rc_path = Rc::new(abs_path);
// wildcard imports are validated
@@ -116,8 +105,7 @@ pub fn import_tree(
let new_imports = match (root.0).walk_ref(&[], &rc_path, false) {
Err(e) if e.kind == ErrKind::Missing => Err(e),
Err(e) => return Err(e.at(location)),
Ok(module)
=> Ok(process_donor_module(module, rc_path.clone(), |i| i.is_op))
Ok(module) => Ok(process_donor_module(module, rc_path.clone()))
};
let old_m = match (prev_root.0).walk_ref(&[], &rc_path, false) {
Err(e) if e.kind != ErrKind::Missing => return Err(e.at(location)),
@@ -134,7 +122,7 @@ pub fn import_tree(
},
Ok(old_m) => old_m,
};
let it1 = process_donor_module(old_m, rc_path.clone(), |i| i.is_op);
let it1 = process_donor_module(old_m, rc_path.clone());
match new_imports {
Err(_) => Box::new(it1),
Ok(it2) => box_chain!(it1, it2)
@@ -144,10 +132,10 @@ pub fn import_tree(
// leaf sets flattened to leaves
.flatten_ok()
// translated to entries
.map_ok(|(name, source, is_op)| {
.map_ok(|(name, source)| {
(name, ModEntry {
exported: false, // this is irrelevant but needed
member: ModMember::Item(ImpReport { source, is_op }),
member: ModMember::Item(ImpReport { source }),
})
})
.chain(

View File

@@ -1,5 +1,3 @@
use std::rc::Rc;
use hashbrown::HashMap;
use itertools::Itertools;
@@ -7,15 +5,14 @@ use super::build_tree::{build_tree, TreeReport};
use super::import_tree::{import_tree, ImpMod};
use crate::error::ProjectResult;
use crate::pipeline::source_loader::{
LoadedSourceTable, PreExtra, PreItem, PreMod, Preparsed,
LoadedSourceTable, PreExtra, PreMod, Preparsed,
};
use crate::representations::project::{ImpReport, ProjectExt, ProjectMod};
use crate::representations::project::{ProjectExt, ProjectMod};
use crate::sourcefile::FileEntry;
use crate::tree::{ModEntry, ModMember, Module};
use crate::utils::never::{always, unwrap_always};
use crate::utils::pure_push::pushed_ref;
use crate::utils::pure_seq::pushed_ref;
use crate::utils::unwrap_or;
use crate::{parse, Interner, ProjectTree, Tok, VName};
use crate::{Interner, ProjectTree, Tok, VName};
pub fn rebuild_file(
path: Vec<Tok<String>>,
@@ -23,35 +20,12 @@ pub fn rebuild_file(
imports: ImpMod,
source: &LoadedSourceTable,
prelude: &[FileEntry],
i: &Interner,
) -> ProjectResult<ProjectMod<VName>> {
let file = match &pre.extra {
PreExtra::Dir => panic!("Dir should not hand this node off"),
PreExtra::Submod(_) => panic!("should not have received this"),
PreExtra::File(f) => f,
};
let mut ops = Vec::new();
unwrap_always(imports.search_all((), &mut |_, module, ()| {
ops.extend(
(module.entries.iter())
.filter(|(_, ent)| {
matches!(ent.member, ModMember::Item(ImpReport { is_op: true, .. }))
})
.map(|(name, _)| name.clone()),
);
always(())
}));
unwrap_always(pre.search_all((), &mut |_, module, ()| {
ops.extend(
(module.entries.iter())
.filter(|(_, ent)| {
matches!(ent.member, ModMember::Item(PreItem { is_op: true, .. }))
})
.map(|(name, _)| name.clone()),
);
always(())
}));
let ctx = parse::ParsingContext::new(&ops, i, Rc::new(path.clone()));
let src = source.get(&file.name).unwrap_or_else(|| {
panic!(
"{} should have been preparsed already. Preparsed files are {}",
@@ -62,13 +36,11 @@ pub fn rebuild_file(
.join(", ")
)
});
let entries = parse::parse2(&src.text, ctx)?;
let TreeReport { entries: items, rules, imports_from } =
let entries = src.entries.clone();
let TreeReport { entries, rules, imports_from } =
build_tree(&path, entries, pre, imports, prelude)?;
Ok(Module {
entries: items,
extra: ProjectExt { file: Some(path.clone()), path, imports_from, rules },
})
let file = Some(path.clone());
Ok(Module { entries, extra: ProjectExt { file, path, imports_from, rules } })
}
pub fn rebuild_dir(
@@ -77,15 +49,14 @@ pub fn rebuild_dir(
mut imports: ImpMod,
source: &LoadedSourceTable,
prelude: &[FileEntry],
i: &Interner,
) -> ProjectResult<ProjectMod<VName>> {
match pre.extra {
PreExtra::Dir => (),
PreExtra::File(_) =>
return rebuild_file(path, pre, imports, source, prelude, i),
return rebuild_file(path, pre, imports, source, prelude),
PreExtra::Submod(_) => panic!("Dirs contain dirs and files"),
}
let items = (pre.entries.into_iter())
let entries = (pre.entries.into_iter())
.map(|(name, entry)| {
match imports.entries.remove(&name).map(|e| e.member) {
Some(ModMember::Sub(impmod)) => (name, entry, impmod),
@@ -97,12 +68,8 @@ pub fn rebuild_dir(
let pre = unwrap_or!(member => ModMember::Sub;
panic!("Dirs can only contain submodules")
);
Ok((name, ModEntry {
exported,
member: ModMember::Sub(rebuild_dir(
path, pre, impmod, source, prelude, i,
)?),
}))
let module = rebuild_dir(path, pre, impmod, source, prelude)?;
Ok((name, ModEntry { exported, member: ModMember::Sub(module) }))
})
.collect::<Result<HashMap<_, _>, _>>()?;
Ok(Module {
@@ -112,7 +79,7 @@ pub fn rebuild_dir(
rules: Vec::new(),
file: None,
},
entries: items,
entries,
})
}
@@ -126,6 +93,6 @@ pub fn rebuild_tree(
) -> ProjectResult<ProjectTree<VName>> {
let imports =
import_tree(Vec::new(), &preparsed.0, &preparsed, prev_root, i)?;
rebuild_dir(Vec::new(), preparsed.0, imports, source, prelude, i)
rebuild_dir(Vec::new(), preparsed.0, imports, source, prelude)
.map(ProjectTree)
}