Fixed match, and enabled macro keywords to share names with constants
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
let my_tuple = option::some t[1, 2]
|
let my_tuple = option::some t[1, 2]
|
||||||
|
|
||||||
let main = match my_tuple {
|
let main = match my_tuple {
|
||||||
option::of t[ref head, ..] => head;
|
option::some t[ref head, ..] => head;
|
||||||
option::empty => "foo";
|
option::none => "foo";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ use orchid_extension::atom::TAtom;
|
|||||||
use orchid_extension::atom_owned::own;
|
use orchid_extension::atom_owned::own;
|
||||||
use orchid_extension::context::i;
|
use orchid_extension::context::i;
|
||||||
use orchid_extension::conv::ToExpr;
|
use orchid_extension::conv::ToExpr;
|
||||||
|
use orchid_extension::coroutine_exec::exec;
|
||||||
use orchid_extension::gen_expr::{call, sym_ref};
|
use orchid_extension::gen_expr::{call, sym_ref};
|
||||||
use orchid_extension::tree::{GenMember, fun, prefix};
|
use orchid_extension::tree::{GenMember, fun, prefix};
|
||||||
|
|
||||||
use crate::macros::mactree::MacTree;
|
use crate::macros::mactree::MacTree;
|
||||||
use crate::macros::resolve::resolve;
|
use crate::macros::resolve::resolve;
|
||||||
use crate::macros::utils::{build_macro, mactree, mactreev};
|
use crate::macros::utils::{build_macro, mactree, mactreev};
|
||||||
|
use crate::{HomoTpl, UntypedTuple};
|
||||||
|
|
||||||
pub async fn gen_macro_lib() -> Vec<GenMember> {
|
pub async fn gen_macro_lib() -> Vec<GenMember> {
|
||||||
prefix("macros", [
|
prefix("macros", [
|
||||||
@@ -30,35 +32,37 @@ pub async fn gen_macro_lib() -> Vec<GenMember> {
|
|||||||
.rule(
|
.rule(
|
||||||
mactreev!(macros::common::comma_list ( "...$" head 0 macros::common::, "...$" tail 1)),
|
mactreev!(macros::common::comma_list ( "...$" head 0 macros::common::, "...$" tail 1)),
|
||||||
[async |[head, tail]| {
|
[async |[head, tail]| {
|
||||||
call(sym_ref(sym!(std::tuple::cat; i())), [
|
exec(async |mut h| {
|
||||||
call(sym_ref(sym!(std::tuple::one; i())), [head.to_gen().await]),
|
let recur = resolve(mactree!(macros::common::comma_list "push" tail ;)).await;
|
||||||
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]| {
|
.rule(mactreev!(macros::common::comma_list ( "...$" final_tail 0 )), [async |[tail]| {
|
||||||
call(sym_ref(sym!(std::tuple::one; i())), [tail.to_gen().await])
|
HomoTpl(vec![tail.to_gen().await])
|
||||||
}])
|
|
||||||
.rule(mactreev!(macros::common::comma_list()), [async |[]| {
|
|
||||||
sym_ref(sym!(std::tuple::empty; i()))
|
|
||||||
}])
|
}])
|
||||||
|
.rule(mactreev!(macros::common::comma_list()), [async |[]| UntypedTuple(Vec::new())])
|
||||||
.finish(),
|
.finish(),
|
||||||
build_macro(None, ["semi_list", ";"])
|
build_macro(None, ["semi_list", ";"])
|
||||||
.rule(
|
.rule(
|
||||||
mactreev!(macros::common::semi_list ( "...$" head 0 macros::common::; "...$" tail 1)),
|
mactreev!(macros::common::semi_list ( "...$" head 0 macros::common::; "...$" tail 1)),
|
||||||
[async |[head, tail]| {
|
[async |[head, tail]| {
|
||||||
call(sym_ref(sym!(std::tuple::cat; i())), [
|
exec(async |mut h| {
|
||||||
call(sym_ref(sym!(std::tuple::one; i())), [head.to_gen().await]),
|
let recur = resolve(mactree!(macros::common::semi_list "push" tail ;)).await;
|
||||||
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]| {
|
.rule(mactreev!(macros::common::semi_list ( "...$" final_tail 0 )), [async |[tail]| {
|
||||||
call(sym_ref(sym!(std::tuple::one; i())), [tail.to_gen().await])
|
HomoTpl(vec![tail.to_gen().await])
|
||||||
}])
|
|
||||||
.rule(mactreev!(macros::common::semi_list()), [async |[]| {
|
|
||||||
sym_ref(sym!(std::tuple::empty; i()))
|
|
||||||
}])
|
}])
|
||||||
|
.rule(mactreev!(macros::common::semi_list()), [async |[]| UntypedTuple(Vec::new())])
|
||||||
.finish(),
|
.finish(),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use async_fn_stream::stream;
|
||||||
use async_once_cell::OnceCell;
|
use async_once_cell::OnceCell;
|
||||||
use futures::{StreamExt, stream};
|
use futures::StreamExt;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use orchid_base::error::{OrcRes, Reporter, mk_errv};
|
use orchid_base::error::{OrcRes, Reporter, mk_errv};
|
||||||
use orchid_base::parse::{
|
use orchid_base::parse::{
|
||||||
@@ -14,7 +14,7 @@ use orchid_base::{clone, sym};
|
|||||||
use orchid_extension::atom::TAtom;
|
use orchid_extension::atom::TAtom;
|
||||||
use orchid_extension::context::i;
|
use orchid_extension::context::i;
|
||||||
use orchid_extension::conv::{ToExpr, TryFromExpr};
|
use orchid_extension::conv::{ToExpr, TryFromExpr};
|
||||||
use orchid_extension::gen_expr::{atom, call, sym_ref};
|
use orchid_extension::gen_expr::{call, sym_ref};
|
||||||
use orchid_extension::parser::{PSnippet, ParsCtx, ParsedLine, Parser};
|
use orchid_extension::parser::{PSnippet, ParsCtx, ParsedLine, Parser};
|
||||||
|
|
||||||
use crate::macros::let_line::{dealias_mac_v, parse_tokv};
|
use crate::macros::let_line::{dealias_mac_v, parse_tokv};
|
||||||
@@ -142,43 +142,37 @@ impl Parser for MacroLine {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
let mac_cell = Rc::new(OnceCell::new());
|
let mac_cell = Rc::new(OnceCell::new());
|
||||||
let rules = Rc::new(RefCell::new(Some(rules)));
|
let rules = Rc::new(rules);
|
||||||
for (kw, sr) in &*keywords {
|
for (kw, sr) in &*keywords {
|
||||||
clone!(mac_cell, rules, module, macro_name, prio);
|
clone!(mac_cell, rules, module, macro_name, prio);
|
||||||
lines.push(ParsedLine::cnst(&sr.clone(), &comments, true, kw.clone(), async move |cctx| {
|
let kw_key = i().i(&format!("__macro__{kw}")).await;
|
||||||
let mac = mac_cell
|
lines.push(ParsedLine::cnst(&sr.clone(), &comments, true, kw_key, async move |cctx| {
|
||||||
.get_or_init(async {
|
let mac_future = async {
|
||||||
let rep = Reporter::new();
|
let rep = Reporter::new();
|
||||||
let rules = rules.borrow_mut().take().expect("once cell initializer runs");
|
let rules = stream(async |mut h| {
|
||||||
let rules = stream::iter(rules)
|
for (body, ph_names, pattern_rel) in rules.iter() {
|
||||||
.then(|(body_name, placeholders, pattern_rel)| {
|
let pattern = dealias_mac_v(pattern_rel, &cctx, &rep).await;
|
||||||
let cctx = &cctx;
|
let ph_names = ph_names.iter().map(|(ph, _)| ph.name.clone()).collect_vec();
|
||||||
let rep = &rep;
|
match Matcher::new(pattern.clone()).await {
|
||||||
async move {
|
Ok(matcher) =>
|
||||||
let pattern = dealias_mac_v(&pattern_rel, cctx, rep).await;
|
h.emit(Rule { body: body.clone(), matcher, pattern, ph_names }).await,
|
||||||
let pattern_res = Matcher::new(pattern.clone()).await;
|
Err(e) => rep.report(e),
|
||||||
let placeholders = placeholders.into_iter().map(|(ph, _)| ph.name).collect_vec();
|
}
|
||||||
match pattern_res {
|
}
|
||||||
Ok(matcher) => Some(Rule { body_name, matcher, pattern, placeholders }),
|
})
|
||||||
Err(e) => {
|
.collect::<Vec<_>>()
|
||||||
rep.report(e);
|
.await;
|
||||||
None
|
match rep.errv() {
|
||||||
},
|
Some(e) => Err(e),
|
||||||
}
|
None => Ok(Macro(Rc::new(MacroData {
|
||||||
}
|
|
||||||
})
|
|
||||||
.flat_map(stream::iter)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.await;
|
|
||||||
Macro(Rc::new(MacroData {
|
|
||||||
canonical_name: module.suffix([macro_name], &i()).await,
|
canonical_name: module.suffix([macro_name], &i()).await,
|
||||||
module,
|
module,
|
||||||
prio: prio.map(|i| i.0 as u64),
|
prio: prio.map(|i| i.0 as u64),
|
||||||
rules,
|
rules,
|
||||||
}))
|
}))),
|
||||||
})
|
}
|
||||||
.await;
|
};
|
||||||
atom(mac.clone())
|
mac_cell.get_or_init(mac_future).await.clone().to_gen().await
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Ok(lines)
|
Ok(lines)
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ pub struct Macro(pub Rc<MacroData>);
|
|||||||
pub struct Rule {
|
pub struct Rule {
|
||||||
pub pattern: MacTreeSeq,
|
pub pattern: MacTreeSeq,
|
||||||
pub matcher: Matcher,
|
pub matcher: Matcher,
|
||||||
pub placeholders: Vec<Tok<String>>,
|
pub ph_names: Vec<Tok<String>>,
|
||||||
pub body_name: Tok<String>,
|
pub body: Tok<String>,
|
||||||
}
|
}
|
||||||
impl Atomic for Macro {
|
impl Atomic for Macro {
|
||||||
type Data = ();
|
type Data = ();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use itertools::Itertools;
|
|||||||
use orchid_base::error::mk_errv;
|
use orchid_base::error::mk_errv;
|
||||||
use orchid_base::format::fmt;
|
use orchid_base::format::fmt;
|
||||||
use orchid_base::location::Pos;
|
use orchid_base::location::Pos;
|
||||||
use orchid_base::name::Sym;
|
use orchid_base::name::{NameLike, Sym, VPath};
|
||||||
use orchid_base::tree::Paren;
|
use orchid_base::tree::Paren;
|
||||||
use orchid_extension::atom::TAtom;
|
use orchid_extension::atom::TAtom;
|
||||||
use orchid_extension::atom_owned::own;
|
use orchid_extension::atom_owned::own;
|
||||||
@@ -24,17 +24,22 @@ use crate::macros::mactree::MacTreeSeq;
|
|||||||
use crate::macros::rule::state::{MatchState, StateEntry};
|
use crate::macros::rule::state::{MatchState, StateEntry};
|
||||||
use crate::{MacTok, MacTree};
|
use crate::{MacTok, MacTree};
|
||||||
|
|
||||||
pub async fn resolve(tpl: MacTree) -> GExpr {
|
pub async fn resolve(val: MacTree) -> GExpr {
|
||||||
exec(async move |mut h| {
|
exec(async move |mut h| {
|
||||||
let ctx = ctx();
|
let ctx = ctx();
|
||||||
// if ctx.logger().is_active() {
|
// if ctx.logger().is_active() {
|
||||||
writeln!(ctx.logger(), "Macro-resolving {}", fmt(&tpl, &i()).await);
|
writeln!(ctx.logger(), "Macro-resolving {}", fmt(&val, &i()).await);
|
||||||
// }
|
// }
|
||||||
let root = refl();
|
let root = refl();
|
||||||
let mut macros = HashMap::new();
|
let mut macros = HashMap::new();
|
||||||
for n in tpl.glossary() {
|
for n in val.glossary() {
|
||||||
if let Ok(ReflMemKind::Const) = root.get_by_path(n).await.map(|m| m.kind()) {
|
let (foot, body) = n.split_last_seg();
|
||||||
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(n.clone())).await else { continue };
|
let new_name = VPath::new(body.iter().cloned())
|
||||||
|
.name_with_suffix(i().i(&format!("__macro__{foot}")).await)
|
||||||
|
.to_sym(&i())
|
||||||
|
.await;
|
||||||
|
if let Ok(ReflMemKind::Const) = root.get_by_path(&new_name).await.map(|m| m.kind()) {
|
||||||
|
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(new_name)).await else { continue };
|
||||||
let mac = own(&mac).await;
|
let mac = own(&mac).await;
|
||||||
macros.entry(mac.0.canonical_name.clone()).or_insert(mac);
|
macros.entry(mac.0.canonical_name.clone()).or_insert(mac);
|
||||||
}
|
}
|
||||||
@@ -45,7 +50,7 @@ pub async fn resolve(tpl: MacTree) -> GExpr {
|
|||||||
for (_, mac) in macros.iter() {
|
for (_, mac) in macros.iter() {
|
||||||
let mut record = FilteredMacroRecord { mac, rules: Vec::new() };
|
let mut record = FilteredMacroRecord { mac, rules: Vec::new() };
|
||||||
for (rule_i, rule) in mac.0.rules.iter().enumerate() {
|
for (rule_i, rule) in mac.0.rules.iter().enumerate() {
|
||||||
if rule.pattern.glossary.is_subset(tpl.glossary()) {
|
if rule.pattern.glossary.is_subset(val.glossary()) {
|
||||||
record.rules.push(rule_i);
|
record.rules.push(rule_i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +66,14 @@ pub async fn resolve(tpl: MacTree) -> GExpr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut rctx = ResolveCtx { h, exclusive, priod };
|
let mut rctx = ResolveCtx { h, exclusive, priod };
|
||||||
resolve_one(&mut rctx, Substack::Bottom, &tpl).await
|
let gex = resolve_one(&mut rctx, Substack::Bottom, &val).await;
|
||||||
|
writeln!(
|
||||||
|
ctx.logger(),
|
||||||
|
"Macro-resolution over {}\nreturned {}",
|
||||||
|
fmt(&val, &i()).await,
|
||||||
|
fmt(&gex, &i()).await
|
||||||
|
);
|
||||||
|
gex
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -270,13 +282,12 @@ async fn resolve_seq(
|
|||||||
|
|
||||||
async fn mk_body_call(mac: &Macro, rule: &Rule, state: &MatchState<'_>, pos: Pos) -> GExpr {
|
async fn mk_body_call(mac: &Macro, rule: &Rule, state: &MatchState<'_>, pos: Pos) -> GExpr {
|
||||||
let mut call_args = vec![];
|
let mut call_args = vec![];
|
||||||
for name in rule.placeholders.iter() {
|
for name in rule.ph_names.iter() {
|
||||||
call_args.push(match state.get(name).expect("Missing state entry for placeholder") {
|
call_args.push(match state.get(name).expect("Missing state entry for placeholder") {
|
||||||
StateEntry::Scalar(scal) => (**scal).clone().to_gen().await,
|
StateEntry::Scalar(scal) => (**scal).clone().to_gen().await,
|
||||||
StateEntry::Vec(vec) =>
|
StateEntry::Vec(vec) =>
|
||||||
MacTok::S(Paren::Round, MacTreeSeq::new(vec.iter().cloned())).at(Pos::None).to_gen().await,
|
MacTok::S(Paren::Round, MacTreeSeq::new(vec.iter().cloned())).at(Pos::None).to_gen().await,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
call(sym_ref(mac.0.module.suffix([rule.body_name.clone()], &i()).await), call_args)
|
call(sym_ref(mac.0.module.suffix([rule.body.clone()], &i()).await), call_args).at(pos.clone())
|
||||||
.at(pos.clone())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ pub async fn gen_std_macro_lib() -> Vec<GenMember> {
|
|||||||
fun(false, "is_none_body", async |val: OrcOpt<Expr>| {
|
fun(false, "is_none_body", async |val: OrcOpt<Expr>| {
|
||||||
if val.0.is_none() { OrcOpt(Some(Tpl(()))) } else { OrcOpt(None) }
|
if val.0.is_none() { OrcOpt(Some(Tpl(()))) } else { OrcOpt(None) }
|
||||||
}),
|
}),
|
||||||
build_macro(None, ["of", "empty"])
|
build_macro(None, ["some", "none"])
|
||||||
.rule(mactreev!(pattern::match_rule ( std::option::of "...$" sub_pattern 0)), [
|
.rule(mactreev!(pattern::match_rule ( std::option::some "...$" sub_pattern 0)), [
|
||||||
|[sub]: [_; _]| {
|
|[sub]: [_; _]| {
|
||||||
exec(async move |mut h| {
|
exec(async move |mut h| {
|
||||||
let sub = h
|
let sub = h
|
||||||
@@ -47,7 +47,7 @@ pub async fn gen_std_macro_lib() -> Vec<GenMember> {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.rule(mactreev!(pattern::match_rule(std::option::empty)), [|[]: [_; _]| {
|
.rule(mactreev!(pattern::match_rule(std::option::none)), [|[]: [_; _]| {
|
||||||
exec(async |mut h| {
|
exec(async |mut h| {
|
||||||
Ok(MatcherAtom {
|
Ok(MatcherAtom {
|
||||||
keys: vec![],
|
keys: vec![],
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl MacroBuilder {
|
|||||||
pub(crate) fn finish(self) -> Vec<GenMember> {
|
pub(crate) fn finish(self) -> Vec<GenMember> {
|
||||||
let Self { own_kws, prio, patterns, body_consts } = self;
|
let Self { own_kws, prio, patterns, body_consts } = self;
|
||||||
let name = own_kws[0];
|
let name = own_kws[0];
|
||||||
let main_const = lazy(true, name, async move |path| {
|
let main_const = lazy(true, &format!("__macro__{name}"), async move |path| {
|
||||||
let module = (Sym::new(path.split_last_seg().1.iter().cloned(), &i()).await)
|
let module = (Sym::new(path.split_last_seg().1.iter().cloned(), &i()).await)
|
||||||
.expect("Default macro in global root");
|
.expect("Default macro in global root");
|
||||||
MemKind::Const(
|
MemKind::Const(
|
||||||
@@ -120,8 +120,8 @@ impl MacroBuilder {
|
|||||||
h.emit(Rule {
|
h.emit(Rule {
|
||||||
matcher: Matcher::new(pattern.clone()).await.unwrap(),
|
matcher: Matcher::new(pattern.clone()).await.unwrap(),
|
||||||
pattern,
|
pattern,
|
||||||
placeholders,
|
ph_names: placeholders,
|
||||||
body_name: i().i(&format!("({name})::{counter}")).await,
|
body: i().i(&format!("({name})::{counter}")).await,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
@@ -134,9 +134,9 @@ impl MacroBuilder {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
let kw_consts = own_kws[1..].iter().flat_map(|kw| {
|
let kw_consts = own_kws[1..].iter().flat_map(|kw| {
|
||||||
lazy(true, kw, async |path| {
|
lazy(true, &format!("__macro__{kw}"), async move |path| {
|
||||||
let main_const_name = VPath::new(path.split_last_seg().1.iter().cloned())
|
let main_const_name = VPath::new(path.split_last_seg().1.iter().cloned())
|
||||||
.name_with_suffix(i().i(name).await)
|
.name_with_suffix(i().i(&format!("__macro__{name}")).await)
|
||||||
.to_sym(&i())
|
.to_sym(&i())
|
||||||
.await;
|
.await;
|
||||||
MemKind::Const(sym_ref(main_const_name))
|
MemKind::Const(sym_ref(main_const_name))
|
||||||
|
|||||||
Reference in New Issue
Block a user