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

123 lines
3.9 KiB
Rust

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<GenMember> {
prefix("macros", [
fun(true, "resolve", async |tpl: TAtom<MacTree>| {
exec(async move |mut h| new_atom(resolve(&mut h, tpl.own().await).await)).await
}),
fun(true, "lower", async |mt: TAtom<MacTree>| 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<TAtom<MacTree>> =
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<TAtom<MacTree>> =
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(),
]),
])
}