partway through fixes, macro system needs resdesign
Some checks failed
Rust / build (push) Has been cancelled
Some checks failed
Rust / build (push) Has been cancelled
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user