exec working up to halt
clean shutdown doesn't for some reason
This commit is contained in:
@@ -11,7 +11,6 @@ use futures::lock::Mutex;
|
||||
use futures::{FutureExt, SinkExt, StreamExt, stream, stream_select};
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
use orchid_api::{ExtMsgSet, IntReq};
|
||||
use orchid_api_traits::{Decode, UnderRoot, enc_vec};
|
||||
use orchid_base::builtin::{ExtInit, ExtPort, Spawner};
|
||||
use orchid_base::char_filter::{char_filter_match, char_filter_union, mk_char_filter};
|
||||
@@ -29,9 +28,9 @@ use trait_set::trait_set;
|
||||
use crate::api;
|
||||
use crate::atom::{AtomCtx, AtomDynfo, AtomTypeId};
|
||||
use crate::atom_owned::take_atom;
|
||||
use crate::expr::{Expr, ExprHandle};
|
||||
use crate::expr::{BorrowedExprStore, Expr, ExprHandle};
|
||||
use crate::lexer::{LexContext, ekey_cascade, ekey_not_applicable};
|
||||
use crate::parser::{PTok, PTokTree, ParsCtx, get_const, linev_into_api};
|
||||
use crate::parser::{PTokTree, ParsCtx, get_const, linev_into_api};
|
||||
use crate::system::{SysCtx, atom_by_idx};
|
||||
use crate::system_ctor::{CtedObj, DynSystemCtor};
|
||||
use crate::tree::{LazyMemberFactory, TreeIntoApiCtxImpl};
|
||||
@@ -124,7 +123,7 @@ pub fn extension_init(
|
||||
}));
|
||||
let init_ctx = {
|
||||
clone!(interner_weak, spawner, logger);
|
||||
move |id: api::SysId, cted: CtedObj, reqnot: ReqNot<ExtMsgSet>| {
|
||||
move |id: api::SysId, cted: CtedObj, reqnot: ReqNot<api::ExtMsgSet>| {
|
||||
clone!(interner_weak, spawner, logger; async move {
|
||||
let interner_rc =
|
||||
interner_weak.upgrade().expect("System construction order while shutting down");
|
||||
@@ -242,49 +241,62 @@ pub fn extension_init(
|
||||
let text = Tok::from_api(text, &i).await;
|
||||
let src = Sym::from_api(src, sys_ctx.i()).await;
|
||||
let rep = Reporter::new();
|
||||
let ctx = LexContext { id, pos, text: &text, src, ctx: sys_ctx.clone(), rep: &rep };
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
let trigger_char = text.chars().nth(pos as usize).unwrap();
|
||||
let ekey_na = ekey_not_applicable(&i).await;
|
||||
let ekey_cascade = ekey_cascade(&i).await;
|
||||
let lexers = sys_ctx.cted().inst().dyn_lexers();
|
||||
for lx in lexers.iter().filter(|l| char_filter_match(l.char_filter(), trigger_char)) {
|
||||
let ctx = LexContext {
|
||||
id,
|
||||
pos,
|
||||
text: &text,
|
||||
src: src.clone(),
|
||||
ctx: sys_ctx.clone(),
|
||||
rep: &rep,
|
||||
exprs: &expr_store,
|
||||
};
|
||||
match lx.lex(&text[pos as usize..], &ctx).await {
|
||||
Err(e) if e.any(|e| *e == ekey_na) => continue,
|
||||
Err(e) => {
|
||||
let eopt = e.keep_only(|e| *e != ekey_cascade).map(|e| Err(e.to_api()));
|
||||
expr_store.dispose().await;
|
||||
return hand.handle(&lex, &eopt).await;
|
||||
},
|
||||
Ok((s, expr)) => {
|
||||
let expr = expr.into_api(&mut (), &mut (sys_ctx, &hand)).await;
|
||||
let pos = (text.len() - s.len()) as u32;
|
||||
expr_store.dispose().await;
|
||||
return hand.handle(&lex, &Some(Ok(api::LexedExpr { pos, expr }))).await;
|
||||
},
|
||||
}
|
||||
}
|
||||
writeln!(logger, "Got notified about n/a character '{trigger_char}'");
|
||||
expr_store.dispose().await;
|
||||
hand.handle(&lex, &None).await
|
||||
},
|
||||
api::HostExtReq::ParseLine(pline) => {
|
||||
let api::ParseLine { module, src, exported, comments, sys, line } = &pline;
|
||||
let mut ctx = get_ctx(*sys).await;
|
||||
let api::ParseLine { module, src, exported, comments, sys, line, idx } = &pline;
|
||||
let ctx = get_ctx(*sys).await;
|
||||
let parsers = ctx.cted().inst().dyn_parsers();
|
||||
let src = Sym::from_api(*src, ctx.i()).await;
|
||||
let comments =
|
||||
join_all(comments.iter().map(|c| Comment::from_api(c, src.clone(), &i))).await;
|
||||
let line: Vec<PTokTree> = ttv_from_api(line, &mut ctx, &mut (), &src, &i).await;
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
let mut from_api_ctx = (ctx.clone(), &expr_store);
|
||||
let line: Vec<PTokTree> =
|
||||
ttv_from_api(line, &mut from_api_ctx, &mut (), &src, &i).await;
|
||||
let snip = Snippet::new(line.first().expect("Empty line"), &line);
|
||||
let (head, tail) = snip.pop_front().unwrap();
|
||||
let name = if let PTok::Name(n) = &head.tok { n } else { panic!("No line head") };
|
||||
let parser =
|
||||
parsers.iter().find(|p| p.line_head() == **name).expect("No parser candidate");
|
||||
let parser = parsers[*idx as usize];
|
||||
let module = Sym::from_api(*module, ctx.i()).await;
|
||||
let reporter = Reporter::new();
|
||||
let pctx = ParsCtx::new(ctx.clone(), module, &reporter);
|
||||
let parse_res = parser.parse(pctx, *exported, comments, tail).await;
|
||||
let parse_res = parser.parse(pctx, *exported, comments, snip).await;
|
||||
let o_line = match reporter.merge(parse_res) {
|
||||
Err(e) => Err(e.to_api()),
|
||||
Ok(t) => Ok(linev_into_api(t, ctx.clone(), &hand).await),
|
||||
};
|
||||
expr_store.dispose().await;
|
||||
hand.handle(&pline, &o_line).await
|
||||
},
|
||||
api::HostExtReq::FetchParsedConst(ref fpc @ api::FetchParsedConst { id, sys }) => {
|
||||
@@ -297,6 +309,7 @@ pub fn extension_init(
|
||||
let atom_req = atom_req.clone();
|
||||
with_atom_record(&get_ctx, atom, async move |nfo, ctx, id, buf| {
|
||||
let actx = AtomCtx(buf, atom.drop, ctx.clone());
|
||||
|
||||
match &atom_req {
|
||||
api::AtomReq::SerializeAtom(ser) => {
|
||||
let mut buf = enc_vec(&id).await;
|
||||
@@ -327,16 +340,23 @@ pub fn extension_init(
|
||||
hand.handle(fwded, &some.then_some(reply)).await
|
||||
},
|
||||
api::AtomReq::CallRef(call @ api::CallRef(_, arg)) => {
|
||||
// SAFETY: function calls own their argument implicitly
|
||||
let expr_handle = unsafe { ExprHandle::from_args(ctx.clone(), *arg) };
|
||||
let ret = nfo.call_ref(actx, Expr::from_handle(Rc::new(expr_handle))).await;
|
||||
hand.handle(call, &ret.api_return(ctx.clone(), &hand).await).await
|
||||
// SAFETY: function calls borrow their argument implicitly
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
let expr_handle = ExprHandle::borrowed(ctx.clone(), *arg, &expr_store);
|
||||
let ret = nfo.call_ref(actx, Expr::from_handle(expr_handle.clone())).await;
|
||||
expr_handle.drop_one().await;
|
||||
let api_expr = ret.api_return(ctx.clone(), &hand).await;
|
||||
expr_store.dispose().await;
|
||||
hand.handle(call, &api_expr).await
|
||||
},
|
||||
api::AtomReq::FinalCall(call @ api::FinalCall(_, arg)) => {
|
||||
// SAFETY: function calls own their argument implicitly
|
||||
let expr_handle = unsafe { ExprHandle::from_args(ctx.clone(), *arg) };
|
||||
let ret = nfo.call(actx, Expr::from_handle(Rc::new(expr_handle))).await;
|
||||
hand.handle(call, &ret.api_return(ctx.clone(), &hand).await).await
|
||||
// SAFETY: function calls borrow their argument implicitly
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
let expr_handle = ExprHandle::borrowed(ctx.clone(), *arg, &expr_store);
|
||||
let ret = nfo.call(actx, Expr::from_handle(expr_handle.clone())).await;
|
||||
let api_expr = ret.api_return(ctx.clone(), &hand).await;
|
||||
expr_store.dispose().await;
|
||||
hand.handle(call, &api_expr).await
|
||||
},
|
||||
api::AtomReq::Command(cmd @ api::Command(_)) => match nfo.command(actx).await {
|
||||
Err(e) => hand.handle(cmd, &Err(e.to_api())).await,
|
||||
@@ -358,8 +378,7 @@ pub fn extension_init(
|
||||
let ctx = get_ctx(*sys).await;
|
||||
// SAFETY: deserialization implicitly grants ownership to previously owned exprs
|
||||
let refs = (refs.iter())
|
||||
.map(|tk| unsafe { ExprHandle::from_args(ctx.clone(), *tk) })
|
||||
.map(|handle| Expr::from_handle(Rc::new(handle)))
|
||||
.map(|tk| Expr::from_handle(ExprHandle::deserialize(ctx.clone(), *tk)))
|
||||
.collect_vec();
|
||||
let id = AtomTypeId::decode(Pin::new(&mut read)).await;
|
||||
let inst = ctx.cted().inst();
|
||||
@@ -373,7 +392,7 @@ pub fn extension_init(
|
||||
},
|
||||
);
|
||||
*interner_cell.borrow_mut() =
|
||||
Some(Interner::new_replica(rn.clone().map(|ir: IntReq| ir.into_root())));
|
||||
Some(Interner::new_replica(rn.clone().map(|ir: api::IntReq| ir.into_root())));
|
||||
spawner(Box::pin(clone!(spawner; async move {
|
||||
let mut streams = stream_select! { in_recv.map(Some), exit_recv.map(|_| None) };
|
||||
while let Some(item) = streams.next().await {
|
||||
|
||||
Reference in New Issue
Block a user