use crate::{
common::{ Operator, Keyword, },
token::{ Token, TokenKind, TokenData, },
};
pub unsafe trait SyncPredicate {
unsafe fn sync (&mut self, token: &Token) -> bool;
}
unsafe impl<F> SyncPredicate for F
where F: FnMut (&Token) -> bool
{
#[inline]
unsafe fn sync (&mut self, token: &Token) -> bool { self(token) }
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn token_kind (kind: TokenKind) -> impl SyncPredicate {
move |token: &Token| token.kind() == kind
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn token_data (data: TokenData) -> impl SyncPredicate {
move |token: &Token| token.data == data
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn any_token_data_of (data: &'static [TokenData]) -> impl SyncPredicate {
move |token: &Token| data.contains(&token.data)
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn operator (op: Operator) -> impl SyncPredicate {
token_data(TokenData::Operator(op))
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn any_operator () -> impl SyncPredicate {
move |token: &Token| matches!(token, Token { data: TokenData::Operator(_), .. })
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn any_operator_of (operators: &'static [Operator]) -> impl SyncPredicate {
move |token: &Token| token.is_any_operator_of(operators).is_some()
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn keyword (kw: Keyword) -> impl SyncPredicate {
token_data(TokenData::Keyword(kw))
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn any_keyword () -> impl SyncPredicate {
move |token: &Token| matches!(token, Token { data: TokenData::Keyword(_), .. })
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn any_keyword_of (keywords: &'static [Keyword]) -> impl SyncPredicate {
move |token: &Token| token.is_any_keyword_of(keywords).is_some()
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn or<Pl, Pr> (mut left: Pl, mut right: Pr) -> impl SyncPredicate
where Pl: SyncPredicate,
Pr: SyncPredicate,
{
move |token: &Token| unsafe { left.sync(token) || right.sync(token) }
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn and<Pl, Pr> (mut left: Pl, mut right: Pr) -> impl SyncPredicate
where Pl: SyncPredicate,
Pr: SyncPredicate,
{
move |token: &Token| unsafe { left.sync(token) && right.sync(token) }
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn close_pair<Pl, Pr> (mut left: Pl, mut right: Pr) -> impl SyncPredicate
where Pl: SyncPredicate,
Pr: SyncPredicate,
{
let mut open_pair_count = 1;
move |token: &Token| {
if unsafe { left.sync(token) } { open_pair_count += 1 }
else if unsafe { right.sync(token) } { open_pair_count -= 1 }
open_pair_count == 0
}
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn close_pair_or<Pl, Pr, Pi> (mut left: Pl, mut right: Pr, mut interior: Pi) -> impl SyncPredicate
where Pl: SyncPredicate,
Pr: SyncPredicate,
Pi: SyncPredicate,
{
let mut open_pair_count = 1;
move |token: &Token| {
if unsafe { left.sync(token) } { open_pair_count += 1 }
else if unsafe { right.sync(token) } { open_pair_count -= 1 }
open_pair_count == 0 || (open_pair_count == 1 && unsafe { interior.sync(token) })
}
}
#[must_use = "sync_predicate::* functions return a synchronization predicate that must be passed to the Parser in a synchronization call, and do not perform the synchronization themselves"]
pub fn external<Pl, Pr, Pe> (mut left: Pl, mut right: Pr, mut interior: Pe) -> impl SyncPredicate
where Pl: SyncPredicate,
Pr: SyncPredicate,
Pe: SyncPredicate,
{
let mut open_pair_count = 0;
move |token: &Token| {
if unsafe { left.sync(token) } { open_pair_count += 1 }
else if unsafe { right.sync(token) } { open_pair_count -= 1 }
open_pair_count == 0 && unsafe { interior.sync(token) }
}
}