Files
orchid/orchid-std/src/macros/macro_lib.rs

70 lines
2.6 KiB
Rust

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<GenMember> {
prefix("macros", [
fun(true, "resolve", async |tpl: TAtom<MacTree>| 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::<HomoTpl<TAtom<MacTree>>>(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::<HomoTpl<TAtom<MacTree>>>(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(),
]),
])
}