use std::fmt;
use crate::ast::{DeclKind, Expr, Modifier, PatchItem, Point, Stmt};
use crate::parser::{PResult, Parser};
pub struct Word {
pub text: &'static str,
pub doc: &'static str,
pub reserved: bool,
pub roles: &'static [Role],
}
pub type Starts = Option<fn(&Parser) -> bool>;
#[derive(Clone, Copy)]
pub enum Role {
Decl {
starts: Starts,
parse: fn(&mut Parser) -> PResult<DeclKind>,
},
Stmt {
parse: fn(&mut Parser) -> PResult<Stmt>,
},
Prefix {
starts: Starts,
parse: fn(&mut Parser) -> PResult<Expr>,
},
Infix {
level: Level,
parse: fn(&mut Parser, Expr) -> PResult<Expr>,
},
Modifier(Modifier),
BuiltinType,
PatchItem {
parse: fn(&mut Parser) -> PResult<PatchItem>,
},
Point {
parse: fn(&mut Parser) -> PResult<Point>,
},
Part,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Level {
Coalesce,
Or,
And,
Equality,
Compare,
Range,
Sum,
Product,
Switch,
}
impl Word {
pub fn role<T>(&self, pick: impl Fn(&Role) -> Option<T>) -> Option<T> {
self.roles.iter().find_map(pick)
}
pub fn is_type(&self) -> bool {
self.roles.iter().any(|r| matches!(r, Role::BuiltinType))
}
}
impl PartialEq for Word {
fn eq(&self, other: &Word) -> bool {
self.text == other.text
}
}
impl fmt::Debug for Word {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "`{}`", self.text)
}
}
pub fn reserved(text: &str) -> Option<&'static Word> {
ALL.iter().copied().find(|w| w.reserved && w.text == text)
}
pub fn named(text: &str) -> Option<&'static Word> {
ALL.iter().copied().find(|w| w.text == text)
}
macro_rules! words {
($($file:ident $(= $path:literal)?),* $(,)?) => {
$($(#[path = $path])? pub mod $file;)*
pub static ALL: &[&Word] = &[$(&$file::WORD),*];
};
}
words! {
using, global, namespace, module = "words/mod_word.rs", r#macro, class, r#struct, record, interface, r#enum, unit,
component, system, extend, event, test, screen, command, patch, targets,
was, requires, every, has, r#where, when, get, set, init, mc, out,
public, private, internal, protected, r#static, r#const, readonly, r#async,
r#abstract, r#virtual, r#override, sealed, r#extern,
server, client, shared, saved, synced, tune,
void, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, decimal, bool, char, string, object,
dynamic,
r#let, r#mut, r#if, r#else, foreach, r#for, r#while, r#do, r#break, r#continue, r#return, skip,
new, this, base, r#ref, r#move, r#typeof, nameof, default, r#true, r#false, null, r#await, r#try, is, r#as, r#in, switch, and, or, not,
add, before, after, inside, replace, read, write, priority, uses, local,
around, at, call, constant, first, last,
}