First steps for the macro system

This commit is contained in:
2025-08-01 18:32:55 +02:00
parent f87185ef88
commit 051b5e666f
18 changed files with 356 additions and 166 deletions

View File

@@ -2,6 +2,7 @@ use std::fmt;
use std::rc::Rc;
use itertools::Itertools;
use orchid_base::error::OrcRes;
use orchid_base::interner::Interner;
use orchid_base::location::Pos;
use orchid_base::name::Sym;
@@ -20,21 +21,21 @@ pub fn last_is_vec(pattern: &[MacTree]) -> bool { vec_attrs(pattern.last().unwra
pub struct NamedMatcher(AnyMatcher);
impl NamedMatcher {
pub async fn new(pattern: &[MacTree], i: &Interner) -> Self {
pub async fn new(pattern: &[MacTree], i: &Interner) -> OrcRes<Self> {
assert!(
matches!(pattern.first().map(|tree| &*tree.tok), Some(MacTok::Name(_))),
"Named matchers must begin with a name"
);
match last_is_vec(pattern) {
true => Self(mk_any(pattern)),
Ok(Self(match last_is_vec(pattern) {
true => mk_any(pattern, i).await,
false => {
let kind = PhKind::Vector { priority: 0, at_least_one: false };
let tok = MacTok::Ph(Ph { name: i.i("::after").await, kind });
let suffix = [MacTree { pos: Pos::None, tok: Rc::new(tok) }];
Self(mk_any(&pattern.iter().chain(&suffix).cloned().collect_vec()))
mk_any(&pattern.iter().chain(&suffix).cloned().collect_vec(), i).await
},
}
}?))
}
/// Also returns the tail, if any, which should be matched further
/// Note that due to how priod works below, the main usable information from
@@ -62,12 +63,12 @@ impl fmt::Debug for NamedMatcher {
pub struct PriodMatcher(VecMatcher);
impl PriodMatcher {
pub fn new(pattern: &[MacTree]) -> Self {
pub async fn new(pattern: &[MacTree], i: &Interner) -> OrcRes<Self> {
assert!(
pattern.first().and_then(vec_attrs).is_some() && pattern.last().and_then(vec_attrs).is_some(),
"Prioritized matchers must start and end with a vectorial",
);
Self(mk_vec(pattern))
Ok(Self(mk_vec(pattern, i).await?))
}
/// tokens before the offset always match the prefix
pub fn apply<'a>(