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

@@ -2,10 +2,10 @@ use std::rc::Rc;
use hashbrown::HashMap;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::interner::is;
use orchid_base::parse::{Comment, Parsed, expect_end, try_pop_no_fluff};
use orchid_base::sym;
use orchid_base::tree::Token;
use orchid_extension::context::i;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::gen_expr::{call, sym_ref};
use orchid_extension::parser::{PSnippet, ParsCtx, ParsedLine, Parser};
@@ -23,11 +23,11 @@ impl Parser for AsProtoParser {
cmts: Vec<Comment>,
line: PSnippet<'a>,
) -> OrcRes<Vec<ParsedLine>> {
let Parsed { output: body_tt, tail } = try_pop_no_fluff(&pcx, line).await?;
expect_end(&pcx, tail).await?;
let Parsed { output: body_tt, tail } = try_pop_no_fluff(line).await?;
expect_end(tail).await?;
if exported {
return Err(mk_errv(
i().i("Exported internal line").await,
is("Exported internal line").await,
"as_proto cannot be exported, the type shares the enclosing module's visibility",
[line.sr().pos()],
));
@@ -36,20 +36,20 @@ impl Parser for AsProtoParser {
let mut impls = Vec::new();
parse_impls(&pcx, &mut lines, &mut impls, body_tt).await?;
let id = pcx.module();
let proto_tag_name = i().i("__protocol_tag__").await;
let proto_tag_path = id.suffix([proto_tag_name.clone()], &i()).await;
let proto_tag_name = is("__protocol_tag__").await;
let proto_tag_path = id.suffix([proto_tag_name.clone()]).await;
lines.push(ParsedLine::cnst(&line.sr(), &cmts, true, proto_tag_name, async |_ccx| {
exec(async move |mut h| {
let mut new_impls = HashMap::new();
for (k, v) in impls {
new_impls.insert(k.clone(), h.register(sym_ref(id.suffix([v], &i()).await)).await);
new_impls.insert(k.clone(), h.register(sym_ref(id.suffix([v]).await)).await);
}
Tag { id, impls: Rc::new(new_impls) }
})
.await
}));
lines.push(ParsedLine::cnst(&line.sr(), [], false, i().i("resolve").await, async move |_| {
call(sym_ref(sym!(std::protocol::resolve; i())), [sym_ref(proto_tag_path)])
lines.push(ParsedLine::cnst(&line.sr(), [], false, is("resolve").await, async move |_| {
call(sym_ref(sym!(std::protocol::resolve)), [sym_ref(proto_tag_path)])
}));
Ok(lines)
}
@@ -65,9 +65,9 @@ impl Parser for ProtoParser {
cmts: Vec<Comment>,
line: PSnippet<'a>,
) -> OrcRes<Vec<ParsedLine>> {
let Parsed { output: name_tt, tail } = try_pop_no_fluff(&ctx, line).await?;
let Parsed { output: name_tt, tail } = try_pop_no_fluff(line).await?;
let Token::Name(name) = &name_tt.tok else {
return Err(mk_errv(i().i("missing name for type").await, "A type needs a name", [name_tt
return Err(mk_errv(is("missing name for type").await, "A type needs a name", [name_tt
.sr()
.pos()]));
};