exec working up to halt
clean shutdown doesn't for some reason
This commit is contained in:
119
orchid-host/src/sys_parser.rs
Normal file
119
orchid-host/src/sys_parser.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use futures::FutureExt;
|
||||
use futures::future::join_all;
|
||||
use itertools::Itertools;
|
||||
use orchid_base::error::{OrcErrv, OrcRes};
|
||||
use orchid_base::interner::{Interner, Tok};
|
||||
use orchid_base::location::SrcRange;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::parse::Comment;
|
||||
use orchid_base::reqnot::Requester;
|
||||
use orchid_base::tree::ttv_from_api;
|
||||
use substack::Substack;
|
||||
|
||||
use crate::api;
|
||||
use crate::expr::ExprParseCtx;
|
||||
use crate::expr_store::ExprStore;
|
||||
use crate::parse::HostParseCtx;
|
||||
use crate::parsed::{
|
||||
Item, ItemKind, ParsTokTree, ParsedMember, ParsedMemberKind, ParsedModule, tt_to_api,
|
||||
};
|
||||
use crate::system::System;
|
||||
|
||||
pub struct Parser {
|
||||
pub(crate) system: System,
|
||||
pub(crate) idx: u16,
|
||||
}
|
||||
type ModPath<'a> = Substack<'a, Tok<String>>;
|
||||
|
||||
impl Parser {
|
||||
pub async fn parse(
|
||||
&self,
|
||||
ctx: &impl HostParseCtx,
|
||||
path: ModPath<'_>,
|
||||
line: Vec<ParsTokTree>,
|
||||
exported: bool,
|
||||
comments: Vec<Comment>,
|
||||
callback: &mut impl AsyncFnMut(ModPath<'_>, Vec<ParsTokTree>) -> OrcRes<Vec<Item>>,
|
||||
) -> OrcRes<Vec<Item>> {
|
||||
let src_path = line.first().expect("cannot be empty").sr.path();
|
||||
let line = join_all(
|
||||
(line.into_iter())
|
||||
.map(|t| async { tt_to_api(&mut self.system.ext().exprs().clone(), t).await }),
|
||||
)
|
||||
.await;
|
||||
let mod_path = ctx.src_path().suffix(path.unreverse(), self.system.i()).await;
|
||||
let comments = comments.iter().map(Comment::to_api).collect_vec();
|
||||
let req = api::ParseLine {
|
||||
idx: self.idx,
|
||||
module: mod_path.to_api(),
|
||||
src: src_path.to_api(),
|
||||
exported,
|
||||
sys: self.system.id(),
|
||||
comments,
|
||||
line,
|
||||
};
|
||||
match self.system.reqnot().request(req).await {
|
||||
Ok(parsed_v) => {
|
||||
let mut ext_exprs = self.system.ext().exprs().clone();
|
||||
conv(parsed_v, path, callback, &mut ConvCtx {
|
||||
i: self.system.i(),
|
||||
mod_path: &mod_path,
|
||||
ext_exprs: &mut ext_exprs,
|
||||
pctx: &mut ExprParseCtx { ctx: self.system.ctx(), exprs: self.system.ext().exprs() },
|
||||
src_path: &src_path,
|
||||
sys: &self.system,
|
||||
})
|
||||
.await
|
||||
},
|
||||
Err(e) => Err(OrcErrv::from_api(&e, &self.system.ctx().i).await),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ConvCtx<'a> {
|
||||
sys: &'a System,
|
||||
mod_path: &'a Sym,
|
||||
src_path: &'a Sym,
|
||||
i: &'a Interner,
|
||||
ext_exprs: &'a mut ExprStore,
|
||||
pctx: &'a mut ExprParseCtx<'a>,
|
||||
}
|
||||
async fn conv(
|
||||
parsed_v: Vec<api::ParsedLine>,
|
||||
module: Substack<'_, Tok<String>>,
|
||||
callback: &'_ mut impl AsyncFnMut(Substack<'_, Tok<String>>, Vec<ParsTokTree>) -> OrcRes<Vec<Item>>,
|
||||
ctx: &mut ConvCtx<'_>,
|
||||
) -> OrcRes<Vec<Item>> {
|
||||
let mut items = Vec::new();
|
||||
for parsed in parsed_v {
|
||||
let (name, exported, kind) = match parsed.kind {
|
||||
api::ParsedLineKind::Member(api::ParsedMember { name, exported, kind }) =>
|
||||
(name, exported, kind),
|
||||
api::ParsedLineKind::Recursive(rec) => {
|
||||
let tokens = ttv_from_api(rec, ctx.ext_exprs, ctx.pctx, ctx.src_path, ctx.i).await;
|
||||
items.extend(callback(module.clone(), tokens).await?);
|
||||
continue;
|
||||
},
|
||||
};
|
||||
let name = ctx.i.ex(name).await;
|
||||
let mkind = match kind {
|
||||
api::ParsedMemberKind::Module { lines, use_prelude } => {
|
||||
let items = conv(lines, module.push(name.clone()), callback, ctx).boxed_local().await?;
|
||||
ParsedMemberKind::Mod(ParsedModule::new(use_prelude, items))
|
||||
},
|
||||
api::ParsedMemberKind::Constant(cid) => {
|
||||
ctx.sys.0.const_paths.insert(cid, ctx.mod_path.suffix(module.unreverse(), ctx.i).await);
|
||||
ParsedMemberKind::Const(cid, ctx.sys.clone())
|
||||
},
|
||||
};
|
||||
items.push(Item {
|
||||
comments: join_all(
|
||||
parsed.comments.iter().map(|c| Comment::from_api(c, ctx.src_path.clone(), ctx.i)),
|
||||
)
|
||||
.await,
|
||||
sr: SrcRange::from_api(&parsed.source_range, ctx.i).await,
|
||||
kind: ItemKind::Member(ParsedMember { name, exported, kind: mkind }),
|
||||
})
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
Reference in New Issue
Block a user