exec working up to halt

clean shutdown doesn't for some reason
This commit is contained in:
2025-09-09 16:30:49 +02:00
parent e339350505
commit ce08021e79
36 changed files with 460 additions and 399 deletions

View File

@@ -10,6 +10,7 @@ use futures::{FutureExt, StreamExt, stream};
use hashbrown::HashMap;
use hashbrown::hash_map::Entry;
use itertools::Itertools;
use memo_map::MemoMap;
use orchid_base::clone;
use orchid_base::error::{OrcRes, Reporter, mk_errv};
use orchid_base::interner::Tok;
@@ -26,7 +27,7 @@ use crate::system::System;
pub struct RootData {
pub root: Module,
pub consts: HashMap<Sym, Expr>,
pub consts: MemoMap<Sym, Expr>,
pub ctx: Ctx,
}
#[derive(Clone)]
@@ -36,23 +37,25 @@ impl Root {
pub fn new(ctx: Ctx) -> Self {
Root(Rc::new(RwLock::new(RootData {
root: Module::default(),
consts: HashMap::default(),
consts: MemoMap::default(),
ctx,
})))
}
#[must_use]
pub async fn from_api(api: api::Module, sys: &System) -> Self {
let mut consts = HashMap::new();
let mut tfac = TreeFromApiCtx { consts: &mut consts, path: sys.i().i(&[][..]).await, sys };
let consts = MemoMap::new();
let mut tfac = TreeFromApiCtx { consts: &consts, path: sys.i().i(&[][..]).await, sys };
let root = Module::from_api(api, &mut tfac).await;
Root(Rc::new(RwLock::new(RootData { root, consts, ctx: sys.ctx().clone() })))
}
pub async fn merge(&self, new: &Root) -> Result<Self, MergeErr> {
let this = self.0.read().await;
let that = new.0.read().await;
let mut consts =
this.consts.iter().chain(&that.consts).map(|(k, v)| (k.clone(), v.clone())).collect();
let root = this.root.merge(&that.root, this.ctx.clone(), &mut consts).await?;
let this = self.0.write().await;
let that = new.0.write().await;
let consts = MemoMap::new();
for (k, v) in this.consts.iter().chain(that.consts.iter()) {
consts.insert(k.clone(), v.clone());
}
let root = this.root.merge(&that.root, this.ctx.clone(), &consts).await?;
Ok(Self(Rc::new(RwLock::new(RootData { root, consts, ctx: this.ctx.clone() }))))
}
#[must_use]
@@ -60,11 +63,11 @@ impl Root {
let mut ref_this = self.0.write().await;
let this = &mut *ref_this;
let mut deferred_consts = HashMap::new();
let mut consts = this.consts.clone();
let consts = this.consts.clone();
let mut tfpctx = FromParsedCtx {
pars_root: parsed,
deferred_consts: &mut deferred_consts,
consts: &mut consts,
consts: &consts,
pars_prefix: pars_prefix.clone(),
root: &this.root,
ctx: &this.ctx,
@@ -79,7 +82,7 @@ impl Root {
)]);
module = Module { imports: HashMap::new(), members }
}
let root = (this.root.merge(&module, this.ctx.clone(), &mut consts).await)
let root = (this.root.merge(&module, this.ctx.clone(), &consts).await)
.expect("Merge conflict between parsed and existing module");
let new = Root(Rc::new(RwLock::new(RootData { root, consts, ctx: this.ctx.clone() })));
*this.ctx.root.write().await = new.downgrade();
@@ -93,7 +96,7 @@ impl Root {
new
}
pub async fn get_const_value(&self, name: Sym, pos: Pos) -> OrcRes<Expr> {
let this = &mut *self.0.write().await;
let this = &*self.0.read().await;
// shortcut for previously visited
if let Some(val) = this.consts.get(&name) {
return Ok(val.clone());
@@ -101,7 +104,7 @@ impl Root {
// load the node, then check if this "walk" call added it to the map
let ctx = this.ctx.clone();
let module =
walk(&this.root, false, name.iter().cloned(), &mut (ctx.clone(), &mut this.consts)).await;
walk(&this.root, false, name.iter().cloned(), &mut (ctx.clone(), &this.consts)).await;
if let Some(val) = this.consts.get(&name) {
return Ok(val.clone());
}
@@ -140,14 +143,14 @@ impl Default for WeakRoot {
pub struct TreeFromApiCtx<'a> {
pub sys: &'a System,
pub consts: &'a mut HashMap<Sym, Expr>,
pub consts: &'a MemoMap<Sym, Expr>,
pub path: Tok<Vec<Tok<String>>>,
}
impl<'a> TreeFromApiCtx<'a> {
#[must_use]
pub async fn push<'c>(&'c mut self, name: Tok<String>) -> TreeFromApiCtx<'c> {
pub async fn push<'c>(&'c self, name: Tok<String>) -> TreeFromApiCtx<'c> {
let path = self.sys.ctx().i.i(&self.path.iter().cloned().chain([name]).collect_vec()).await;
TreeFromApiCtx { path, consts: &mut *self.consts, sys: self.sys }
TreeFromApiCtx { path, consts: self.consts, sys: self.sys }
}
}
@@ -208,7 +211,7 @@ impl Module {
Ok(abs_path) => {
let names_res = match abs_path.strip_prefix(&ctx.pars_prefix[..]) {
None => {
let mut tree_ctx = (ctx.ctx.clone(), &mut *ctx.consts);
let mut tree_ctx = (ctx.ctx.clone(), ctx.consts);
resolv_glob(&path, ctx.root, &abs_path, pos, &ctx.ctx.i, &mut tree_ctx).await
},
Some(sub_tgt) => {
@@ -322,7 +325,7 @@ impl Module {
&self,
other: &Module,
ctx: Ctx,
consts: &mut HashMap<Sym, Expr>,
consts: &MemoMap<Sym, Expr>,
) -> Result<Module, MergeErr> {
if !self.imports.is_empty() || !other.imports.is_empty() {
return Err(MergeErr { path: VPath::new([]), kind: MergeErrKind::Imports });
@@ -385,12 +388,12 @@ pub struct FromParsedCtx<'a> {
root: &'a Module,
rep: &'a Reporter,
ctx: &'a Ctx,
consts: &'a mut HashMap<Sym, Expr>,
consts: &'a MemoMap<Sym, Expr>,
deferred_consts: &'a mut HashMap<Sym, (api::SysId, api::ParsedConstId)>,
}
impl Tree for Module {
type Ctx<'a> = (Ctx, &'a mut HashMap<Sym, Expr>);
type Ctx<'a> = (Ctx, &'a MemoMap<Sym, Expr>);
async fn child(
&self,
key: Tok<String>,
@@ -420,7 +423,7 @@ pub struct Member {
}
impl Member {
#[must_use]
pub async fn kind<'a>(&'a self, ctx: Ctx, consts: &mut HashMap<Sym, Expr>) -> &'a MemberKind {
pub async fn kind<'a>(&'a self, ctx: Ctx, consts: &MemoMap<Sym, Expr>) -> &'a MemberKind {
(self.kind.get_or_init(async {
let handle = self.lazy.borrow_mut().take().expect("If kind is uninit, lazy must be Some");
handle.run(ctx, consts).await
@@ -437,7 +440,7 @@ impl MemberKind {
#[must_use]
async fn from_parsed(parsed: &ParsedMemberKind, path: Sym, ctx: &mut FromParsedCtx<'_>) -> Self {
match parsed {
ParsedMemberKind::DeferredConst(id, sys) => {
ParsedMemberKind::Const(id, sys) => {
ctx.deferred_consts.insert(path, (sys.id(), *id));
MemberKind::Const
},
@@ -454,12 +457,13 @@ pub struct LazyMemberHandle {
}
impl LazyMemberHandle {
#[must_use]
pub async fn run(self, ctx: Ctx, consts: &mut HashMap<Sym, Expr>) -> MemberKind {
pub async fn run(self, ctx: Ctx, consts: &MemoMap<Sym, Expr>) -> MemberKind {
let sys = ctx.system_inst(self.sys).await.expect("Missing system for lazy member");
match sys.get_tree(self.id).await {
api::MemberKind::Const(c) => {
let mut pctx = ExprParseCtx { ctx: &ctx, exprs: sys.ext().exprs() };
consts.insert(self.path, Expr::from_api(&c, PathSetBuilder::new(), &mut pctx).await);
let expr = Expr::from_api(&c, PathSetBuilder::new(), &mut pctx).await;
consts.insert(self.path, expr);
MemberKind::Const
},
api::MemberKind::Module(m) => MemberKind::Module(