forked from Orchid/orchid
Macro system done in theory
too afraid to begin debugging, resting for a moment
This commit is contained in:
@@ -4,31 +4,33 @@ use std::ops::RangeInclusive;
|
||||
|
||||
use futures::FutureExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use orchid_base::error::{OrcErr, OrcRes, mk_err};
|
||||
use orchid_base::error::{OrcErrv, OrcRes, Reporter, mk_errv};
|
||||
use orchid_base::interner::{Interner, Tok};
|
||||
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::parser::PTokTree;
|
||||
use crate::system::SysCtx;
|
||||
use crate::tree::GenTokTree;
|
||||
|
||||
pub async fn err_cascade(i: &Interner) -> OrcErr {
|
||||
mk_err(
|
||||
i.i("An error cascading from a recursive call").await,
|
||||
"This error is a sentinel for the extension library.\
|
||||
it should not be emitted by the extension.",
|
||||
[Pos::None.into()],
|
||||
)
|
||||
pub async fn ekey_cascade(i: &Interner) -> Tok<String> {
|
||||
i.i("An error cascading from a recursive call").await
|
||||
}
|
||||
pub async fn ekey_not_applicable(i: &Interner) -> Tok<String> {
|
||||
i.i("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.";
|
||||
|
||||
pub async fn err_cascade(i: &Interner) -> OrcErrv {
|
||||
mk_errv(ekey_cascade(i).await, MSG_INTERNAL_ERROR, [Pos::None])
|
||||
}
|
||||
|
||||
pub async fn err_not_applicable(i: &Interner) -> OrcErr {
|
||||
mk_err(
|
||||
i.i("Pseudo-error to communicate that the current branch in a dispatch doesn't apply").await,
|
||||
&*err_cascade(i).await.message,
|
||||
[Pos::None.into()],
|
||||
)
|
||||
pub async fn err_not_applicable(i: &Interner) -> OrcErrv {
|
||||
mk_errv(ekey_not_applicable(i).await, MSG_INTERNAL_ERROR, [Pos::None])
|
||||
}
|
||||
|
||||
pub struct LexContext<'a> {
|
||||
@@ -36,16 +38,22 @@ pub struct LexContext<'a> {
|
||||
pub text: &'a Tok<String>,
|
||||
pub id: api::ParsId,
|
||||
pub pos: u32,
|
||||
pub src: Sym,
|
||||
pub(crate) src: Sym,
|
||||
pub(crate) rep: &'a Reporter,
|
||||
}
|
||||
impl<'a> LexContext<'a> {
|
||||
pub async fn recurse(&self, tail: &'a str) -> OrcRes<(&'a str, GenTokTree)> {
|
||||
pub fn src(&self) -> &Sym { &self.src }
|
||||
/// This function returns [PTokTree] because it can never return
|
||||
/// [orchid_base::tree::Token::NewExpr]. You can use
|
||||
/// [crate::parser::p_tree2gen] to convert this to [crate::tree::GenTokTree]
|
||||
/// 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) = self.ctx.reqnot().request(api::SubLex { pos: start, id: self.id }).await else {
|
||||
return Err(err_cascade(self.ctx.i()).await.into());
|
||||
return Err(err_cascade(self.ctx.i()).await);
|
||||
};
|
||||
let tree =
|
||||
GenTokTree::from_api(&lx.tree, &mut self.ctx.clone(), &mut (), &self.src, self.ctx.i()).await;
|
||||
PTokTree::from_api(&lx.tree, &mut self.ctx.clone(), &mut (), &self.src, self.ctx.i()).await;
|
||||
Ok((&self.text[lx.pos as usize..], tree))
|
||||
}
|
||||
|
||||
@@ -57,8 +65,10 @@ impl<'a> LexContext<'a> {
|
||||
pub fn pos_lt(&self, len: impl TryInto<u32, Error: fmt::Debug>, tail: &'a str) -> SrcRange {
|
||||
SrcRange::new(self.pos(tail) - len.try_into().unwrap()..self.pos(tail), &self.src)
|
||||
}
|
||||
|
||||
pub fn i(&self) -> &Interner { self.ctx.i() }
|
||||
}
|
||||
impl ParseCtx for LexContext<'_> {
|
||||
fn i(&self) -> &Interner { self.ctx.i() }
|
||||
fn rep(&self) -> &Reporter { self.rep }
|
||||
}
|
||||
|
||||
pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
|
||||
Reference in New Issue
Block a user