forked from Orchid/orchid
Returned from Italy
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::path::PathBuf;
|
||||
use async_stream::stream;
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use hashbrown::HashMap;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::pure_seq::pushed;
|
||||
|
||||
use crate::api;
|
||||
use crate::system::System;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DeclMod(Rc<HashMap<Tok<String>, DeclFS>>);
|
||||
impl DeclMod {
|
||||
pub async fn from_api(
|
||||
api: &std::collections::HashMap<api::TStr, api::EagerVfs>,
|
||||
owner: System,
|
||||
) -> Self {
|
||||
let item_stream = stream! {
|
||||
for (key, value) in api {
|
||||
yield (
|
||||
owner.i().ex(*key).await,
|
||||
DeclFS::from_api(value, owner.clone()).boxed_local().await
|
||||
)
|
||||
}
|
||||
};
|
||||
Self(Rc::new(item_stream.collect().await))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DeclFS {
|
||||
Lazy(System, api::VfsId),
|
||||
Eager(DeclMod),
|
||||
Path(PathBuf),
|
||||
}
|
||||
impl DeclFS {
|
||||
pub async fn from_api(api: &api::EagerVfs, owner: System) -> Self {
|
||||
match api {
|
||||
api::EagerVfs::Eager(items) => Self::Eager(DeclMod::from_api(items, owner.clone()).await),
|
||||
api::EagerVfs::Lazy(id) => Self::Lazy(owner.clone(), *id),
|
||||
}
|
||||
}
|
||||
pub fn merge(&self, other: &Self) -> Result<Self, Vec<Tok<String>>> {
|
||||
let (Self::Eager(m1), Self::Eager(m2)) = (self, other) else { return Err(Vec::new()) };
|
||||
let mut mix = m1.0.iter().map(|(k, v)| (k.clone(), v.clone())).collect::<HashMap<_, _>>();
|
||||
for (key, value) in m2.0.iter() {
|
||||
match mix.entry(key.clone()) {
|
||||
hashbrown::hash_map::Entry::Vacant(ent) => {
|
||||
ent.insert(value.clone());
|
||||
},
|
||||
hashbrown::hash_map::Entry::Occupied(mut ent) => match ent.get().merge(value) {
|
||||
Err(e) => return Err(pushed(e, key.clone())),
|
||||
Ok(new) => {
|
||||
ent.insert(new);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(Self::Eager(DeclMod(Rc::new(mix))))
|
||||
}
|
||||
/// Walk through eager fs. Returns if the path ends, if it hits anything other
|
||||
/// than eager, or if the path is invalid.
|
||||
pub fn walk<'a, 'b>(&'a self, path: &'b [Tok<String>]) -> (&'a DeclFS, &'b [Tok<String>]) {
|
||||
let mut cur = self;
|
||||
for (i, step) in path.iter().enumerate() {
|
||||
match self {
|
||||
fs @ (DeclFS::Path(_) | DeclFS::Lazy(..)) => return (fs, &path[i..]),
|
||||
fs @ DeclFS::Eager(m) => match &m.0.get(step) {
|
||||
None => return (fs, &path[i..]),
|
||||
Some(next) => cur = next,
|
||||
},
|
||||
}
|
||||
}
|
||||
(cur, &[])
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn load_code(fs: &DeclFS, systems: &[System], path: &[Tok<String>]) -> OrcRes<Parsed
|
||||
|
||||
pub async fn gather_fs(systems: &[System]) -> Result<DeclFS, Sym> {
|
||||
let (head, tail) = systems.split_first().expect("Empty system list");
|
||||
let mut vfs = head.vfs().await;
|
||||
for sys in tail {
|
||||
match vfs.merge(&sys.vfs().await) {
|
||||
Err(e) => return Err(Sym::new(e.iter().rev().cloned(), head.i()).await.unwrap()),
|
||||
Ok(next) => vfs = next,
|
||||
}
|
||||
}
|
||||
Ok(vfs)
|
||||
}
|
||||
@@ -7,7 +7,6 @@ pub mod execute;
|
||||
pub mod expr;
|
||||
pub mod expr_store;
|
||||
pub mod extension;
|
||||
pub mod fs;
|
||||
pub mod lex;
|
||||
pub mod parse;
|
||||
pub mod parsed;
|
||||
|
||||
@@ -23,11 +23,11 @@ pub struct HostParseCtxImpl<'a> {
|
||||
pub ctx: Ctx,
|
||||
pub src: Sym,
|
||||
pub systems: &'a [System],
|
||||
pub reporter: &'a Reporter,
|
||||
pub rep: &'a Reporter,
|
||||
}
|
||||
|
||||
impl ParseCtx for HostParseCtxImpl<'_> {
|
||||
fn reporter(&self) -> &Reporter { self.reporter }
|
||||
fn reporter(&self) -> &Reporter { self.rep }
|
||||
fn i(&self) -> &Interner { &self.ctx.i }
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,10 @@ impl ParsedModule {
|
||||
(self.items.iter())
|
||||
.filter_map(|it| if let ItemKind::Import(i) = &it.kind { Some(i) } else { None })
|
||||
}
|
||||
pub fn default_item(self, name: Tok<String>, sr: SrcRange) -> Item {
|
||||
let mem = ParsedMember { exported: true, name, kind: ParsedMemberKind::Mod(self) };
|
||||
Item { comments: vec![], sr, kind: ItemKind::Member(mem) }
|
||||
}
|
||||
}
|
||||
impl Tree for ParsedModule {
|
||||
type Ctx<'a> = ();
|
||||
|
||||
@@ -27,7 +27,6 @@ use crate::dealias::{absolute_path, walk};
|
||||
use crate::expr::{ExprParseCtx, ExprWillPanic};
|
||||
use crate::expr_store::ExprStore;
|
||||
use crate::extension::{Extension, WeakExtension};
|
||||
use crate::fs::{DeclFS, DeclMod};
|
||||
use crate::parsed::{Item, ItemKind, ParsTokTree, ParsedMember, ParsedMemberKind, ParsedModule};
|
||||
use crate::tree::Root;
|
||||
|
||||
@@ -40,7 +39,6 @@ struct SystemInstData {
|
||||
lex_filter: api::CharFilter,
|
||||
id: api::SysId,
|
||||
line_types: Vec<Tok<String>>,
|
||||
vfs: std::collections::HashMap<api::TStr, api::EagerVfs>,
|
||||
pub(crate) const_paths: MemoMap<api::ParsedConstId, Sym>,
|
||||
}
|
||||
impl Drop for SystemInstData {
|
||||
@@ -79,10 +77,6 @@ impl System {
|
||||
#[must_use]
|
||||
pub fn has_lexer(&self) -> bool { !self.0.lex_filter.0.is_empty() }
|
||||
#[must_use]
|
||||
pub async fn vfs(&self) -> DeclFS {
|
||||
DeclFS::Eager(DeclMod::from_api(&self.0.vfs, self.clone()).await)
|
||||
}
|
||||
#[must_use]
|
||||
pub fn can_lex(&self, c: char) -> bool { char_filter_match(&self.0.lex_filter, c) }
|
||||
/// Have this system lex a part of the source. It is assumed that
|
||||
/// [Self::can_lex] was called and returned true.
|
||||
@@ -255,7 +249,6 @@ impl SystemCtor {
|
||||
ext: ext.clone(),
|
||||
ctx: ext.ctx().clone(),
|
||||
lex_filter: sys_inst.lex_filter,
|
||||
vfs: sys_inst.vfs,
|
||||
line_types: join_all(sys_inst.line_types.iter().map(|m| Tok::from_api(*m, &ext.ctx().i)))
|
||||
.await,
|
||||
id,
|
||||
|
||||
Reference in New Issue
Block a user