1use std::fmt;
6
7use crate::ast::{DeclKind, Expr, Modifier, PatchItem, Point, Stmt};
8use crate::parser::{PResult, Parser};
9
10pub struct Word {
12 pub text: &'static str,
14 pub doc: &'static str,
16 pub reserved: bool,
19 pub roles: &'static [Role],
21}
22
23pub type Starts = Option<fn(&Parser) -> bool>;
25
26#[derive(Clone, Copy)]
28pub enum Role {
29 Decl {
31 starts: Starts,
32 parse: fn(&mut Parser) -> PResult<DeclKind>,
33 },
34 Stmt {
36 parse: fn(&mut Parser) -> PResult<Stmt>,
37 },
38 Prefix {
40 starts: Starts,
41 parse: fn(&mut Parser) -> PResult<Expr>,
42 },
43 Infix {
45 level: Level,
46 parse: fn(&mut Parser, Expr) -> PResult<Expr>,
47 },
48 Modifier(Modifier),
50 BuiltinType,
52 PatchItem {
54 parse: fn(&mut Parser) -> PResult<PatchItem>,
55 },
56 Point {
58 parse: fn(&mut Parser) -> PResult<Point>,
59 },
60 Part,
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
67pub enum Level {
68 Coalesce,
69 Or,
70 And,
71 BitOr,
72 BitXor,
73 BitAnd,
74 Equality,
75 Compare,
76 Range,
77 Shift,
78 Sum,
79 Product,
80 Switch,
81}
82
83impl Word {
84 pub fn role<T>(&self, pick: impl Fn(&Role) -> Option<T>) -> Option<T> {
86 self.roles.iter().find_map(pick)
87 }
88
89 pub fn is_type(&self) -> bool {
91 self.roles.iter().any(|r| matches!(r, Role::BuiltinType))
92 }
93}
94
95impl PartialEq for Word {
96 fn eq(&self, other: &Word) -> bool {
97 self.text == other.text
98 }
99}
100
101impl fmt::Debug for Word {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(f, "`{}`", self.text)
104 }
105}
106
107pub fn reserved(text: &str) -> Option<&'static Word> {
109 ALL.iter().copied().find(|w| w.reserved && w.text == text)
110}
111
112pub fn named(text: &str) -> Option<&'static Word> {
114 ALL.iter().copied().find(|w| w.text == text)
115}
116
117macro_rules! words {
118 ($($file:ident $(= $path:literal)?),* $(,)?) => {
119 $($(#[path = $path])? pub mod $file;)*
120
121 pub static ALL: &[&Word] = &[$(&$file::WORD),*];
123 };
124}
125
126words! {
127 using, global, namespace, module = "words/mod_word.rs", r#macro, class, r#struct, record, interface, r#enum, unit,
129 component, system, extend, event, delegate, test, screen, command, patch, targets,
130 was, requires, every, has, params, r#where, when, get, set, init, value, field, operator, implicit, explicit, mc, out,
132 public, private, internal, protected, r#static, r#const, readonly, r#async,
134 r#abstract, r#virtual, r#override, sealed, r#extern, partial, required,
135 server, client, shared, saved, synced, tune,
136 void, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, decimal, bool, char, string, object,
138 dynamic,
139 r#let, r#mut, r#if, r#else, foreach, r#for, r#while, r#do, r#break, r#continue, goto, r#return, skip, r#yield, lock, r#unsafe, case, checked, unchecked,
141 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, with, and, or, not,
143 add, before, after, inside, replace, read, write, priority, uses, local,
145 around, at, call, constant, first, last,
146 from, select, group, by, orderby, ascending, descending, into, join, on, equals,
148}