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 {
46 level: Level,
47 parse: fn(&mut Parser, Expr, bool) -> PResult<Expr>,
48 negatable: bool,
49 },
50 Modifier(Modifier),
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)]
66pub enum Level {
67 Coalesce,
68 Or,
69 And,
70 Compare,
71 Range,
72 Sum,
73 Product,
74 Convert,
75}
76
77impl Word {
78 pub fn role<T>(&self, pick: impl Fn(&Role) -> Option<T>) -> Option<T> {
80 self.roles.iter().find_map(pick)
81 }
82}
83
84impl PartialEq for Word {
85 fn eq(&self, other: &Word) -> bool {
86 self.text == other.text
87 }
88}
89
90impl fmt::Debug for Word {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "`{}`", self.text)
93 }
94}
95
96pub fn reserved(text: &str) -> Option<&'static Word> {
98 ALL.iter().copied().find(|w| w.reserved && w.text == text)
99}
100
101pub fn named(text: &str) -> Option<&'static Word> {
103 ALL.iter().copied().find(|w| w.text == text)
104}
105
106macro_rules! words {
107 ($($file:ident $(= $path:literal)?),* $(,)?) => {
108 $($(#[path = $path])? pub(crate) mod $file;)*
109
110 pub static ALL: &[&Word] = &[$(&$file::WORD),*];
112 };
113}
114
115words! {
116 r#use, module = "words/mod_word.rs", r#fn, r#let, r#var, val, r#const, r#type, unit, record, union, r#enum,
119 extend, on, test, native, version, recipe, screen, command, state, action, slots,
120 patch,
121 was, requires, ui, of, mc,
123 server, client, shared, saved, synced, tune, r#pub,
125 r#for, r#while, r#loop, r#break, r#continue, r#return, skip,
127 r#if, r#else, r#match, r#try, r#true, r#false, none, this = "words/self_word.rs", it, not, and, or, is, r#as, r#in,
129 add, before, after, inside, replace, read, write, priority, uses, local,
131 around, at, call, new, constant, first, last, r#where,
132}