Pattern matching works now

This commit is contained in:
2025-11-27 22:47:02 +01:00
parent 4f989271c5
commit ecf151158d
22 changed files with 146 additions and 150 deletions

View File

@@ -89,47 +89,57 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
matcher,
}),
build_macro(None, ["match", "match_rule", "_row", "=>"])
.rule(mactreev!("pattern::match" { "..$" rules 0 }), [async |[rules]| {
exec(async move |mut h| {
let rule_lines = h
.exec::<TAtom<Tuple>>(call(sym_ref(sym!(macros::resolve; i())), [
mactree!(macros::common::semi_list "push" rules.clone();).to_gen().await,
]))
.await?;
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
for line_exprh in rule_lines.iter() {
let line_mac = h
.exec::<TAtom<MacTree>>(Expr::from_handle(ExprHandle::from_ticket(*line_exprh).await))
.await?;
let Tpl((matcher, body)) = h
.exec(call(sym_ref(sym!(macros::resolve; i())), [
mactree!(pattern::_row "push" own(&line_mac).await ;).to_gen().await,
.rule(mactreev!("pattern::match" "...$" value 0 { "..$" rules 0 }), [
async |[value, rules]| {
exec(async move |mut h| {
let rule_lines = h
.exec::<TAtom<Tuple>>(call(sym_ref(sym!(macros::resolve; i())), [
mactree!(macros::common::semi_list "push" rules.clone();).to_gen().await,
]))
.await?;
rule_atoms.push((matcher, body));
}
let base_case = lambda(0, [bot(mk_errv(
i().i("No branches match").await,
"None of the pattern provided matches this value",
[rules.pos()],
))]);
let match_expr = stream::iter(rule_atoms.into_iter().rev())
.fold(base_case, async |tail, (mat, body)| {
lambda(0, [call(sym_ref(sym!(pattern::match_one; i())), [
mat.to_gen().await,
arg(0),
body.to_gen().await,
call(tail, [arg(0)]),
])])
})
.await;
Ok(match_expr)
})
.await
}])
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
for line_exprh in rule_lines.iter() {
let line_mac = h
.exec::<TAtom<MacTree>>(Expr::from_handle(
ExprHandle::from_ticket(*line_exprh).await,
))
.await?;
let Tpl((matcher, body)) = h
.exec(call(sym_ref(sym!(macros::resolve; i())), [
mactree!(pattern::_row "push" own(&line_mac).await ;).to_gen().await,
]))
.await?;
rule_atoms.push((matcher, body));
}
let base_case = lambda(0, [bot(mk_errv(
i().i("No branches match").await,
"None of the patterns matches this value",
[rules.pos()],
))]);
let match_expr = stream::iter(rule_atoms.into_iter().rev())
.fold(base_case, async |tail, (mat, body)| {
lambda(0, [call(sym_ref(sym!(pattern::match_one; i())), [
mat.to_gen().await,
arg(0),
body.to_gen().await,
call(tail, [arg(0)]),
])])
})
.await;
Ok(call(match_expr, [resolve(value).await]))
})
.await
},
])
.rule(mactreev!(pattern::match_rule (( "...$" pattern 0 ))), [async |[pattern]| {
resolve(mactree!(pattern::match_rule "push" pattern; )).await
}])
.rule(mactreev!(pattern::match_rule ( macros::common::_ )), [async |[]| {
Ok(MatcherAtom {
keys: Vec::new(),
matcher: lambda(0, [OrcOpt(Some(Tpl(()))).to_gen().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)>> {