task_local context over context objects

- interner impls logically separate from API in orchid-base (default host interner still in base for testing)
- error reporting, logging, and a variety of other features passed down via context in extension, not yet in host to maintain library-ish profile, should consider options
- no global spawn mechanic, the host has a spawn function but extensions only get a stash for enqueuing async work in sync callbacks which is then explicitly, manually, and with strict order popped and awaited
- still deadlocks nondeterministically for some ungodly reason
This commit is contained in:
2026-01-01 14:54:29 +00:00
parent 06debb3636
commit 32d6237dc5
92 changed files with 2507 additions and 2223 deletions

View File

@@ -6,12 +6,13 @@ use hashbrown::{HashMap, HashSet};
use itertools::Itertools;
use orchid_base::error::mk_errv;
use orchid_base::format::fmt;
use orchid_base::interner::is;
use orchid_base::location::Pos;
use orchid_base::logging::logger;
use orchid_base::name::{NameLike, Sym, VPath};
use orchid_base::tree::Paren;
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_extension::context::{ctx, i};
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::{ExecHandle, exec};
use orchid_extension::gen_expr::{GExpr, arg, bot, call, lambda, sym_ref};
@@ -26,17 +27,16 @@ use crate::{MacTok, MacTree};
pub async fn resolve(val: MacTree) -> GExpr {
exec(async move |mut h| {
let ctx = ctx();
// if ctx.logger().is_active() {
writeln!(ctx.logger(), "Macro-resolving {}", fmt(&val, &i()).await);
writeln!(logger(), "Macro-resolving {}", fmt(&val).await);
// }
let root = refl();
let mut macros = HashMap::new();
for n in val.glossary() {
let (foot, body) = n.split_last_seg();
let new_name = VPath::new(body.iter().cloned())
.name_with_suffix(i().i(&format!("__macro__{foot}")).await)
.to_sym(&i())
.name_with_suffix(is(&format!("__macro__{foot}")).await)
.to_sym()
.await;
if let Ok(ReflMemKind::Const) = root.get_by_path(&new_name).await.map(|m| m.kind()) {
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(new_name)).await else { continue };
@@ -67,12 +67,7 @@ pub async fn resolve(val: MacTree) -> GExpr {
}
let mut rctx = ResolveCtx { h, exclusive, priod };
let gex = resolve_one(&mut rctx, Substack::Bottom, &val).await;
writeln!(
ctx.logger(),
"Macro-resolution over {}\nreturned {}",
fmt(&val, &i()).await,
fmt(&gex, &i()).await
);
writeln!(logger(), "Macro-resolution over {}\nreturned {}", fmt(&val).await, fmt(&gex).await);
gex
})
.await
@@ -110,7 +105,7 @@ async fn resolve_one(
MacTok::Lambda(arg, body) => {
let MacTok::Name(name) = &*arg.tok else {
return bot(mk_errv(
i().i("Syntax error after macros").await,
is("Syntax error after macros").await,
"This token ends up as a binding, consider replacing it with a name",
[arg.pos()],
));
@@ -121,8 +116,8 @@ async fn resolve_one(
},
MacTok::S(Paren::Round, body) => resolve_seq(ctx, arg_stk, body.clone(), value.pos()).await,
MacTok::S(..) => bot(mk_errv(
i().i("Leftover [] or {} not matched by macro").await,
format!("{} was not matched by any macro", fmt(value, &i()).await),
is("Leftover [] or {} not matched by macro").await,
format!("{} was not matched by any macro", fmt(value).await),
[value.pos()],
)),
}
@@ -150,7 +145,7 @@ async fn resolve_seq(
) -> GExpr {
if val.items.is_empty() {
return bot(mk_errv(
i().i("Empty sequence").await,
is("Empty sequence").await,
"() or (\\arg ) left after macro execution. \
This is usually caused by an incomplete call to a macro with bad error detection",
[fallback_pos],
@@ -224,7 +219,7 @@ async fn resolve_seq(
Err((lran, rran))
}
});
let mac_conflict_tk = i().i("Macro conflict").await;
let mac_conflict_tk = is("Macro conflict").await;
let error = conflict_sets
.filter(|r| 1 < r.len())
.map(|set| {
@@ -289,5 +284,5 @@ async fn mk_body_call(mac: &Macro, rule: &Rule, state: &MatchState<'_>, pos: Pos
MacTok::S(Paren::Round, MacTreeSeq::new(vec.iter().cloned())).at(Pos::None).to_gen().await,
});
}
call(sym_ref(mac.0.module.suffix([rule.body.clone()], &i()).await), call_args).at(pos.clone())
call(sym_ref(mac.0.module.suffix([rule.body.clone()]).await), call_args).at(pos.clone())
}