use orchid_extension::gen_expr::new_atom; use orchid_extension::tree::{GenMember, fun, prefix}; use orchid_extension::{TAtom, exec}; use substack::Substack; use crate::macros::lower::lower; use crate::macros::mactree::MacTree; use crate::macros::resolve::resolve; use crate::macros::utils::{build_macro, mactree, mactreev}; use crate::{HomoTpl, UntypedTuple}; pub async fn gen_macro_lib() -> Vec { prefix("macros", [ fun(true, "resolve", async |tpl: TAtom| { exec(async move |mut h| new_atom(resolve(&mut h, tpl.own().await).await)).await }), fun(true, "lower", async |mt: TAtom| lower(&mt.own().await, Substack::Bottom).await), prefix("common", [ build_macro(None, ["..", "_", "="]).finish(), build_macro(Some(30), ["+"]) .rule( mactreev!("...$" lhs 1 "macros::common::+" "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::add::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(Some(30), ["-"]) .rule( mactreev!("...$" lhs 1 "macros::common::-" "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::sub::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(Some(20), ["*"]) .rule( mactreev!("...$" lhs 1 "macros::common::*" "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::mul::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(Some(20), ["/"]) .rule( mactreev!("...$" lhs 1 "macros::common::/" "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::div::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(Some(20), ["%"]) .rule( mactreev!("...$" lhs 1 "macros::common::%" "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::mod::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(Some(10), ["."]) .rule( mactreev!("...$" lhs 1 "macros::common::." "...$" rhs 0), async |mut cx, [lhs, rhs]| { Ok(mactree!("std::ops::get::resolve" "push" cx.recur(lhs).await; "push" cx.recur(rhs).await;)) }, ) .finish(), build_macro(None, ["comma_list", ","]) .rule( mactreev!("macros::common::comma_list" ( "...$" head 0 "macros::common::," "...$" tail 1 )), async |mut cx, [head, tail]| { let mut tail: HomoTpl> = cx.recur_call(mactree!("macros::common::comma_list" "push" tail ;)).await?; tail.0.insert(0, cx.exec(new_atom(head)).await?); Ok(mactree!("Val" tail;)) }, ) .rule( mactreev!("macros::common::comma_list" ( "...$" final_tail 0 )), async |_cx, [tail]| Ok(mactree!("Val" HomoTpl(vec![new_atom(tail)]);)), ) .rule(mactreev!("macros::common::comma_list"()), async |_cx, []| { Ok(mactree!("Val" UntypedTuple(Vec::new());)) }) .finish(), build_macro(None, ["semi_list", ";"]) .rule( mactreev!("macros::common::semi_list" ( "...$" head 0 "macros::common::;" "...$" tail 1 )), async |mut cx, [head, tail]| { let mut tail: HomoTpl> = cx.recur_call(mactree!("macros::common::semi_list" "push" tail ;)).await?; tail.0.insert(0, cx.exec(new_atom(head)).await?); Ok(mactree!("Val" tail)) }, ) .rule( mactreev!("macros::common::semi_list" ( "...$" final_tail 0 )), async |_cx, [tail]| Ok(mactree!("Val" HomoTpl(vec![new_atom(tail)]))), ) .rule(mactreev!("macros::common::semi_list"()), async |_cx, []| { Ok(mactree!("Val" UntypedTuple(Vec::new()))) }) .finish(), ]), ]) }