partway through fixes, macro system needs resdesign
Some checks failed
Rust / build (push) Has been cancelled

This commit is contained in:
2026-04-08 18:02:20 +02:00
parent 0909524dee
commit 9b4c7fa7d7
76 changed files with 1391 additions and 1065 deletions

View File

@@ -6,14 +6,12 @@ use futures::{Stream, StreamExt, stream};
use never::Never;
use orchid_api_derive::Coding;
use orchid_base::{OrcRes, Sym, fmt, is, mk_errv, sym};
use orchid_extension::ToExpr;
use orchid_extension::{ExecHandle, exec};
use orchid_extension::{Expr, ExprHandle};
use orchid_extension::gen_expr::{GExpr, arg, bot, call, call_v, lam, new_atom};
use orchid_extension::gen_expr::{bot, call, call_v, lam, new_atom};
use orchid_extension::tree::{GenMember, fun, prefix};
use orchid_extension::{Atomic, OwnedAtom, OwnedVariant, TAtom};
use orchid_extension::{
Atomic, ExecHandle, Expr, ExprHandle, OwnedAtom, OwnedVariant, TAtom, ToExpr, exec,
};
use crate::macros::resolve::resolve;
use crate::macros::utils::{build_macro, mactree, mactreev};
use crate::std::reflection::sym_atom::SymAtom;
use crate::{HomoTpl, MacTok, MacTree, OrcOpt, Tpl, UntypedTuple, api};
@@ -83,78 +81,63 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
}),
build_macro(None, ["match", "match_rule", "_row", "=>"])
.rule(mactreev!("pattern::match" "...$" value 0 { "..$" rules 0 }), [
async |[value, rules]| {
exec(async move |mut h| {
let rule_lines = h
.exec::<HomoTpl<TAtom<MacTree>>>(call(
sym!(macros::resolve),
new_atom(mactree!(macros::common::semi_list "push" rules.clone();)),
))
.await?;
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
for line_mac in rule_lines.0.iter() {
let Tpl((matcher, body)) = h
.exec(call(
sym!(macros::resolve),
new_atom(mactree!(pattern::_row "push" line_mac.own().await ;)),
))
.await?;
rule_atoms.push((matcher, body));
}
let base_case = lam::<0>(bot(mk_errv(
async |mut cx, [value, rules]| {
let rule_lines: HomoTpl<TAtom<MacTree>> =
cx.exec(cx.recur(mactree!(macros::common::semi_list "push" rules.clone();))).await?;
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
for line_mac in rule_lines.0.iter() {
let Tpl((matcher, body)) =
cx.exec(cx.recur(mactree!(pattern::_row "push" line_mac.own().await ;))).await?;
rule_atoms.push((matcher, body));
}
let base_case = lam(async |_| {
bot(mk_errv(
is("No branches match").await,
"None of the patterns matches this value",
[rules.pos()],
)))
.await;
let match_expr = stream::iter(rule_atoms.into_iter().rev())
.fold(base_case, async |tail, (mat, body)| {
lam::<0>(call(sym!(pattern::match_one), (mat, arg(0), body, call(tail, arg(0)))))
.await
})
.await;
Ok(call(match_expr, resolve(value).await))
))
})
.await
.await;
let match_expr = stream::iter(rule_atoms.into_iter().rev())
.fold(base_case, |tail, (mat, body)| {
lam(async move |x| {
call(sym!(pattern::match_one), (mat, x, body, call(tail, x))).await
})
})
.await;
Ok(call(match_expr, cx.recur(value)))
},
])
.rule(mactreev!(pattern::match_rule (( "...$" pattern 0 ))), [async |[pattern]| {
resolve(mactree!(pattern::match_rule "push" pattern; )).await
.rule(mactreev!(pattern::match_rule (( "...$" pattern 0 ))), [async |cx, [pattern]| {
cx.recur(mactree!(pattern::match_rule "push" pattern; )).to_gen().await
}])
.rule(mactreev!(pattern::match_rule ( macros::common::_ )), [async |[]| {
.rule(mactreev!(pattern::match_rule ( macros::common::_ )), [async |_cx, []| {
Ok(new_atom(MatcherAtom {
keys: Vec::new(),
matcher: lam::<0>(OrcOpt(Some(Tpl(())))).await.create().await,
matcher: lam(async |_| OrcOpt(Some(Tpl(()))).to_gen().await).await.create().await,
}))
}])
.rule(mactreev!(pattern::_row ( "...$" pattern 0 pattern::=> "...$" value 1 )), [
async |[pattern, mut value]| {
exec(async move |mut h| -> OrcRes<Tpl<(TAtom<MatcherAtom>, GExpr)>> {
let Ok(pat) = h
.exec::<TAtom<MatcherAtom>>(call(
sym!(macros::resolve),
new_atom(mactree!(pattern::match_rule "push" pattern.clone();)),
))
.await
else {
return Err(mk_errv(
is("Invalid pattern").await,
format!("Could not parse {} as a match pattern", fmt(&pattern).await),
[pattern.pos()],
));
};
value = (pat.keys())
.fold(value, async |value, name| mactree!("l_" name; ( "push" value ; )))
.await;
Ok(Tpl((pat, resolve(value).await)))
})
.await
async |mut cx, [pattern, mut value]| -> OrcRes<Tpl<(TAtom<MatcherAtom>, _)>> {
let Ok(pat): OrcRes<TAtom<MatcherAtom>> =
cx.exec(cx.recur(mactree!(pattern::match_rule "push" pattern.clone();))).await
else {
return Err(mk_errv(
is("Invalid pattern").await,
format!("Could not parse {} as a match pattern", fmt(&pattern).await),
[pattern.pos()],
));
};
value = (pat.keys())
.fold(value, async |value, name| mactree!("l_" name; ( "push" value ; )))
.await;
Ok(Tpl((pat, cx.recur(value))))
},
])
.finish(),
fun(true, "ref_body", async |val| OrcOpt(Some(UntypedTuple(vec![val])))),
build_macro(None, ["ref"])
.rule(mactreev!(pattern::match_rule(pattern::ref "$" name)), [async |[name]| {
.rule(mactreev!(pattern::match_rule(pattern::ref "$" name)), [async |_cx, [name]| {
let MacTok::Name(name) = name.tok() else {
return Err(mk_errv(
is("pattern 'ref' requires a name to bind to").await,