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:
@@ -1,27 +1,24 @@
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::future::Future;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use futures::FutureExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use orchid_base::error::{OrcErrv, OrcRes, Reporter, mk_errv};
|
||||
use orchid_base::interner::{Interner, Tok};
|
||||
use orchid_base::error::{OrcErrv, OrcRes, mk_errv};
|
||||
use orchid_base::interner::{IStr, is};
|
||||
use orchid_base::location::{Pos, SrcRange};
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::parse::ParseCtx;
|
||||
use orchid_base::reqnot::Requester;
|
||||
|
||||
use crate::api;
|
||||
use crate::context::{ctx, i};
|
||||
use crate::entrypoint::request;
|
||||
use crate::expr::BorrowedExprStore;
|
||||
use crate::parser::PTokTree;
|
||||
use crate::tree::GenTokTree;
|
||||
|
||||
pub async fn ekey_cascade() -> Tok<String> {
|
||||
i().i("An error cascading from a recursive call").await
|
||||
}
|
||||
pub async fn ekey_not_applicable() -> Tok<String> {
|
||||
i().i("Pseudo-error to communicate that the current branch in a dispatch doesn't apply").await
|
||||
pub async fn ekey_cascade() -> IStr { is("An error cascading from a recursive call").await }
|
||||
pub async fn ekey_not_applicable() -> IStr {
|
||||
is("Pseudo-error to communicate that the current branch in a dispatch doesn't apply").await
|
||||
}
|
||||
const MSG_INTERNAL_ERROR: &str = "This error is a sentinel for the extension library.\
|
||||
it should not be emitted by the extension.";
|
||||
@@ -36,23 +33,20 @@ pub async fn err_not_applicable() -> OrcErrv {
|
||||
|
||||
pub struct LexContext<'a> {
|
||||
pub(crate) exprs: &'a BorrowedExprStore,
|
||||
pub text: &'a Tok<String>,
|
||||
pub text: &'a IStr,
|
||||
pub id: api::ParsId,
|
||||
pub pos: u32,
|
||||
i: Interner,
|
||||
pub(crate) src: Sym,
|
||||
pub(crate) rep: &'a Reporter,
|
||||
}
|
||||
impl<'a> LexContext<'a> {
|
||||
pub fn new(
|
||||
exprs: &'a BorrowedExprStore,
|
||||
text: &'a Tok<String>,
|
||||
text: &'a IStr,
|
||||
id: api::ParsId,
|
||||
pos: u32,
|
||||
src: Sym,
|
||||
rep: &'a Reporter,
|
||||
) -> Self {
|
||||
Self { exprs, i: i(), id, pos, rep, src, text }
|
||||
Self { exprs, id, pos, src, text }
|
||||
}
|
||||
pub fn src(&self) -> &Sym { &self.src }
|
||||
/// This function returns [PTokTree] because it can never return
|
||||
@@ -61,10 +55,10 @@ impl<'a> LexContext<'a> {
|
||||
/// for embedding in the return value.
|
||||
pub async fn recurse(&self, tail: &'a str) -> OrcRes<(&'a str, PTokTree)> {
|
||||
let start = self.pos(tail);
|
||||
let Some(lx) = ctx().reqnot().request(api::SubLex { pos: start, id: self.id }).await else {
|
||||
let Some(lx) = request(api::SubLex { pos: start, id: self.id }).await else {
|
||||
return Err(err_cascade().await);
|
||||
};
|
||||
let tree = PTokTree::from_api(&lx.tree, &mut { self.exprs }, &mut (), &self.src, &i()).await;
|
||||
let tree = PTokTree::from_api(&lx.tree, &mut { self.exprs }, &mut (), &self.src).await;
|
||||
Ok((&self.text[lx.pos as usize..], tree))
|
||||
}
|
||||
|
||||
@@ -77,12 +71,8 @@ impl<'a> LexContext<'a> {
|
||||
SrcRange::new(self.pos(tail) - len.try_into().unwrap()..self.pos(tail), &self.src)
|
||||
}
|
||||
}
|
||||
impl ParseCtx for LexContext<'_> {
|
||||
fn i(&self) -> &Interner { &self.i }
|
||||
fn rep(&self) -> &Reporter { self.rep }
|
||||
}
|
||||
|
||||
pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
pub trait Lexer: Debug + Send + Sync + Sized + Default + 'static {
|
||||
const CHAR_FILTER: &'static [RangeInclusive<char>];
|
||||
fn lex<'a>(
|
||||
tail: &'a str,
|
||||
@@ -90,7 +80,7 @@ pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
) -> impl Future<Output = OrcRes<(&'a str, GenTokTree)>>;
|
||||
}
|
||||
|
||||
pub trait DynLexer: Send + Sync + 'static {
|
||||
pub trait DynLexer: Debug + Send + Sync + 'static {
|
||||
fn char_filter(&self) -> &'static [RangeInclusive<char>];
|
||||
fn lex<'a>(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user