Fixed match, and enabled macro keywords to share names with constants

This commit is contained in:
2025-11-30 02:30:42 +01:00
parent ecf151158d
commit 4e4dc381ea
7 changed files with 82 additions and 73 deletions

View File

@@ -1,8 +1,8 @@
use std::cell::RefCell;
use std::rc::Rc;
use async_fn_stream::stream;
use async_once_cell::OnceCell;
use futures::{StreamExt, stream};
use futures::StreamExt;
use itertools::Itertools;
use orchid_base::error::{OrcRes, Reporter, mk_errv};
use orchid_base::parse::{
@@ -14,7 +14,7 @@ use orchid_base::{clone, sym};
use orchid_extension::atom::TAtom;
use orchid_extension::context::i;
use orchid_extension::conv::{ToExpr, TryFromExpr};
use orchid_extension::gen_expr::{atom, call, sym_ref};
use orchid_extension::gen_expr::{call, sym_ref};
use orchid_extension::parser::{PSnippet, ParsCtx, ParsedLine, Parser};
use crate::macros::let_line::{dealias_mac_v, parse_tokv};
@@ -142,43 +142,37 @@ impl Parser for MacroLine {
}))
}
let mac_cell = Rc::new(OnceCell::new());
let rules = Rc::new(RefCell::new(Some(rules)));
let rules = Rc::new(rules);
for (kw, sr) in &*keywords {
clone!(mac_cell, rules, module, macro_name, prio);
lines.push(ParsedLine::cnst(&sr.clone(), &comments, true, kw.clone(), async move |cctx| {
let mac = mac_cell
.get_or_init(async {
let rep = Reporter::new();
let rules = rules.borrow_mut().take().expect("once cell initializer runs");
let rules = stream::iter(rules)
.then(|(body_name, placeholders, pattern_rel)| {
let cctx = &cctx;
let rep = &rep;
async move {
let pattern = dealias_mac_v(&pattern_rel, cctx, rep).await;
let pattern_res = Matcher::new(pattern.clone()).await;
let placeholders = placeholders.into_iter().map(|(ph, _)| ph.name).collect_vec();
match pattern_res {
Ok(matcher) => Some(Rule { body_name, matcher, pattern, placeholders }),
Err(e) => {
rep.report(e);
None
},
}
}
})
.flat_map(stream::iter)
.collect::<Vec<_>>()
.await;
Macro(Rc::new(MacroData {
let kw_key = i().i(&format!("__macro__{kw}")).await;
lines.push(ParsedLine::cnst(&sr.clone(), &comments, true, kw_key, async move |cctx| {
let mac_future = async {
let rep = Reporter::new();
let rules = stream(async |mut h| {
for (body, ph_names, pattern_rel) in rules.iter() {
let pattern = dealias_mac_v(pattern_rel, &cctx, &rep).await;
let ph_names = ph_names.iter().map(|(ph, _)| ph.name.clone()).collect_vec();
match Matcher::new(pattern.clone()).await {
Ok(matcher) =>
h.emit(Rule { body: body.clone(), matcher, pattern, ph_names }).await,
Err(e) => rep.report(e),
}
}
})
.collect::<Vec<_>>()
.await;
match rep.errv() {
Some(e) => Err(e),
None => Ok(Macro(Rc::new(MacroData {
canonical_name: module.suffix([macro_name], &i()).await,
module,
prio: prio.map(|i| i.0 as u64),
rules,
}))
})
.await;
atom(mac.clone())
}))),
}
};
mac_cell.get_or_init(mac_future).await.clone().to_gen().await
}))
}
Ok(lines)