Added support for defining macros in Rust within the macro system

Also fixed a lot of bugs
This commit is contained in:
2025-09-30 21:23:16 +02:00
parent 7971a2b4eb
commit b77653f841
52 changed files with 849 additions and 502 deletions

View File

@@ -1,58 +1,47 @@
use hashbrown::HashMap;
use itertools::Itertools;
use itertools::{Itertools, chain};
use orchid_base::error::Reporter;
use orchid_base::sym;
use orchid_extension::atom::TypAtom;
use orchid_base::{clone, sym};
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::gen_expr::{atom, call, sym_ref};
use orchid_extension::func_atom::Lambda;
use orchid_extension::gen_expr::{call, sym_ref};
use orchid_extension::reflection::{ReflMemKind, refl};
use orchid_extension::tree::{GenMember, comments, fun, prefix};
use orchid_extension::tree::{GenMember, MemKind, fun, lazy, prefix};
use substack::Substack;
use crate::Int;
use crate::macros::instantiate_tpl::InstantiateTplCall;
use crate::macros::macro_line::{Macro, Matcher};
use crate::macros::mactree::{LowerCtx, MacTree};
use crate::macros::recur_state::RecurState;
use crate::MacTok;
use crate::macros::macro_value::{Macro, Matcher};
use crate::macros::mactree::{LowerCtx, MacTree, Ph};
use crate::macros::resolve::{ResolveCtx, resolve};
use crate::macros::utils::{mactree, mactreev, mk_macro};
pub fn gen_macro_lib() -> Vec<GenMember> {
prefix("macros", [
comments(
["This is an internal function, you can't obtain a value of its argument type.", "hidden"],
fun(true, "instantiate_tpl", |tpl: TypAtom<MacTree>, right: Int| async move {
InstantiateTplCall {
tpl: own(tpl).await,
argc: right.0.try_into().unwrap(),
argv: Vec::new(),
}
}),
),
fun(true, "resolve", |tpl: TypAtom<MacTree>| async move {
call([
sym_ref(sym!(macros::resolve_recur; tpl.untyped.ctx().i()).await),
atom(RecurState::Bottom),
tpl.untyped.ex().to_expr().await,
])
}),
fun(true, "lower", |tpl: TypAtom<MacTree>| async move {
fun(true, "lower", |tpl: TAtom<MacTree>| async move {
let ctx = LowerCtx { sys: tpl.untyped.ctx().clone(), rep: &Reporter::new() };
let res = own(tpl).await.lower(ctx, Substack::Bottom).await;
if let Some(e) = Reporter::new().errv() { Err(e) } else { Ok(res) }
}),
fun(true, "resolve_recur", |state: TypAtom<RecurState>, tpl: TypAtom<MacTree>| async move {
exec("macros::resolve_recur", async move |mut h| {
fun(true, "recur", async |tpl: TAtom<MacTree>| {
call(sym_ref(sym!(macros::lower; tpl.i()).await), [call(
sym_ref(sym!(macros::resolve; tpl.i()).await),
[tpl.to_expr().await],
)])
}),
fun(true, "resolve", |tpl: TAtom<MacTree>| async move {
exec("macros::resolve", async move |mut h| {
let ctx = tpl.ctx().clone();
let root = refl(&ctx);
let tpl = own(tpl.clone()).await;
let mut macros = HashMap::new();
for n in tpl.glossary() {
if let Ok(ReflMemKind::Const) = root.get_by_path(n).await.map(|m| m.kind()) {
let Ok(mac) = h.exec::<TypAtom<Macro>>(sym_ref(n.clone())).await else { continue };
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(n.clone())).await else { continue };
let mac = own(mac).await;
macros.entry(mac.0.own_kws[0].clone()).or_insert(mac);
macros.entry(mac.canonical_name(&ctx).await).or_insert(mac);
}
}
let mut named = HashMap::new();
@@ -69,7 +58,7 @@ pub fn gen_macro_lib() -> Vec<GenMember> {
}
}
let priod = priod.into_iter().sorted_unstable_by_key(|(p, _)| *p).map(|(_, r)| r).collect();
let mut rctx = ResolveCtx { h, recur: own(state).await, ctx: ctx.clone(), named, priod };
let mut rctx = ResolveCtx { h, ctx: ctx.clone(), named, priod };
let resolve_res = resolve(&mut rctx, &tpl).await;
std::mem::drop(rctx);
match resolve_res {
@@ -79,5 +68,30 @@ pub fn gen_macro_lib() -> Vec<GenMember> {
})
.await
}),
// TODO test whether any of this worked
lazy(true, "common", async |_, ctx| {
let add_macro = {
clone!(ctx);
mk_macro(Some(1), ["+"], [(
mactreev!(ctx.i(); "...$" lhs 0 macros::common::+ "...$" rhs 1),
Lambda::new("std::number::add", async move |lhs: TAtom<MacTree>, rhs: TAtom<MacTree>| {
mactree!(ctx.i(); std::number::add
(macros::recur "'" lhs.ex();)
(macros::recur "'" rhs.ex();)
)
}),
)])
};
let mul_macro = mk_macro(Some(2), ["*"], [(
mactreev!(ctx.i(); "...$" lhs 0 macros::common::* "...$" rhs 1),
Lambda::new("std::number::mul", async |lhs: TAtom<MacTree>, rhs: TAtom<MacTree>| {
mactree!(lhs.ctx().i(); std::number::mul
(macros::recur "'" lhs.ex();)
(macros::recur "'" rhs.ex();)
)
}),
)]);
MemKind::Mod { members: chain!(add_macro, mul_macro).collect_vec() }
}),
])
}