Updated macro system to process and return mactree and then lower it separately to gexpr
Some checks failed
Rust / build (push) Has been cancelled

This commit is contained in:
2026-04-11 11:00:22 +00:00
parent 9b4c7fa7d7
commit b44f3c1832
14 changed files with 460 additions and 469 deletions

View File

@@ -16,7 +16,7 @@ use task_local::task_local;
use crate::gen_expr::GExpr;
use crate::tree::{GenTok, GenTokTree};
use crate::{Expr, ToExpr, api, request, sys_id};
use crate::{ExecHandle, Expr, ToExpr, TryFromExpr, api, exec, request, sys_id};
/// [PTokTree] without [orchid_base::Pos] metadata
pub type PTok = Token<Expr, Never>;
@@ -118,7 +118,7 @@ impl<'a> ParsCtx<'a> {
pub fn module(&self) -> Sym { self.module.clone() }
}
type BoxConstCallback = Box<dyn FnOnce(ConstCtx) -> LocalBoxFuture<'static, GExpr>>;
type BoxConstCallback = Box<dyn for<'a> FnOnce(ConstCtx<'a>) -> LocalBoxFuture<'a, GExpr>>;
task_local! {
static CONST_TBL: RefCell<HashMap<NonZero<u64>, BoxConstCallback>>;
@@ -143,14 +143,15 @@ impl ParsedLine {
/// Define a constant. The callback is only called later if the constant is
/// referenced, and it can call [crate::refl] to base its value on the module
/// tree or use its argument for context-specific queries
pub fn cnst<'a, R: ToExpr + 'static, F: AsyncFnOnce(ConstCtx) -> R + 'static>(
pub fn cnst<'a, R: ToExpr + 'static, F: for<'b> AsyncFnOnce(ConstCtx<'b>) -> R + 'static>(
sr: &SrcRange,
comments: impl IntoIterator<Item = &'a Comment>,
exported: bool,
name: IStr,
f: F,
) -> Self {
let cb = Box::new(|ctx| async move { f(ctx).await.to_gen().await }.boxed_local());
let cb: BoxConstCallback =
Box::new(|ctx| async move { f(ctx).await.to_gen().await }.boxed_local());
let kind = ParsedLineKind::Mem(ParsedMem { name, exported, kind: ParsedMemKind::Const(cb) });
let comments = comments.into_iter().cloned().collect();
ParsedLine { comments, sr: sr.clone(), kind }
@@ -241,11 +242,11 @@ pub enum ParsedMemKind {
}
/// Enable a generated constant to query about its environment
#[derive(Clone)]
pub struct ConstCtx {
pub struct ConstCtx<'a> {
constid: api::ParsedConstId,
exec: ExecHandle<'a>,
}
impl ConstCtx {
impl<'a> ConstCtx<'a> {
/// Resolve a set of local names into the full names they would point to if
/// they were globally bound. Errors produced at this stage are soft, as the
/// names may still be found to be locally bound within the expression
@@ -272,10 +273,14 @@ impl ConstCtx {
pub async fn names_n<const N: usize>(&self, names: [&Sym; N]) -> [OrcRes<Sym>; N] {
self.names(names).collect::<Vec<_>>().await.try_into().expect("Lengths must match")
}
pub async fn exec<R: TryFromExpr>(&mut self, val: impl ToExpr) -> OrcRes<R> {
self.exec.exec(val).await
}
pub fn handle(&mut self) -> &mut ExecHandle<'a> { &mut self.exec }
}
pub(crate) async fn get_const(id: api::ParsedConstId) -> GExpr {
let cb = CONST_TBL
.with(|ent| ent.borrow_mut().remove(&id.0).expect("Bad ID or double read of parsed const"));
cb(ConstCtx { constid: id }).await
exec(async move |exec| cb(ConstCtx { constid: id, exec }).await).await
}