use orchid_base::sym; use orchid_extension::atom::TAtom; use orchid_extension::atom_owned::own; use orchid_extension::context::i; use orchid_extension::conv::ToExpr; use orchid_extension::coroutine_exec::exec; use orchid_extension::gen_expr::{call, sym_ref}; use orchid_extension::tree::{GenMember, fun, prefix}; 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| resolve(own(&tpl).await).await), // TODO test whether any of this worked prefix("common", [ build_macro(None, ["..", "_"]).finish(), build_macro(Some(1), ["+"]) .rule(mactreev!("...$" lhs 0 macros::common::+ "...$" rhs 1), [async |[lhs, rhs]| { call(sym_ref(sym!(std::number::add; i())), [resolve(lhs).await, resolve(rhs).await]) }]) .finish(), build_macro(Some(2), ["*"]) .rule(mactreev!("...$" lhs 0 macros::common::* "...$" rhs 1), [async |[lhs, rhs]| { call(sym_ref(sym!(std::number::mul; i())), [resolve(lhs).await, resolve(rhs).await]) }]) .finish(), build_macro(None, ["comma_list", ","]) .rule( mactreev!(macros::common::comma_list ( "...$" head 0 macros::common::, "...$" tail 1)), [async |[head, tail]| { exec(async |mut h| { let recur = resolve(mactree!(macros::common::comma_list "push" tail ;)).await; let mut tail = h.exec::>>(recur).await?; tail.0.insert(0, h.exec(head).await?); Ok(tail) }) .await }], ) .rule(mactreev!(macros::common::comma_list ( "...$" final_tail 0 )), [async |[tail]| { HomoTpl(vec![tail.to_gen().await]) }]) .rule(mactreev!(macros::common::comma_list()), [async |[]| UntypedTuple(Vec::new())]) .finish(), build_macro(None, ["semi_list", ";"]) .rule( mactreev!(macros::common::semi_list ( "...$" head 0 macros::common::; "...$" tail 1)), [async |[head, tail]| { exec(async |mut h| { let recur = resolve(mactree!(macros::common::semi_list "push" tail ;)).await; let mut tail = h.exec::>>(recur).await?; tail.0.insert(0, h.exec(head).await?); Ok(tail) }) .await }], ) .rule(mactreev!(macros::common::semi_list ( "...$" final_tail 0 )), [async |[tail]| { HomoTpl(vec![tail.to_gen().await]) }]) .rule(mactreev!(macros::common::semi_list()), [async |[]| UntypedTuple(Vec::new())]) .finish(), ]), ]) }