1use crate::{Parse, ParseResult, Parser, Peek, Peeker};
2
3use sway_ast::keywords::*;
4use sway_error::parser_error::ParseErrorKind;
5use sway_types::Spanned;
6
7fn peek_keyword<T: Keyword>(peeker: Peeker<'_>) -> Option<T> {
8 let ident = peeker.peek_ident().ok()?;
9 (ident.as_str() == T::AS_STR).then(|| T::new(ident.span()))
10}
11
12fn parse_keyword<T: Keyword + Peek>(parser: &mut Parser) -> ParseResult<T> {
13 match parser.take() {
14 Some(value) => Ok(value),
15 None => Err(parser.emit_error(ParseErrorKind::ExpectedKeyword { word: T::AS_STR })),
16 }
17}
18
19macro_rules! keyword_impls {
20 ($($ty:ty),*) => {
21 $(
22 impl Peek for $ty {
23 fn peek(peeker: Peeker<'_>) -> Option<Self> {
24 peek_keyword(peeker)
25 }
26 }
27
28 impl Parse for $ty {
29 fn parse(parser: &mut Parser) -> ParseResult<Self> {
30 parse_keyword(parser)
31 }
32 }
33 )*
34 };
35}
36
37keyword_impls! {
38 ScriptToken,
39 ContractToken,
40 PredicateToken,
41 LibraryToken,
42 ModToken,
43 PubToken,
44 UseToken,
45 AsToken,
46 StructToken,
47 ClassToken,
48 EnumToken,
49 SelfToken,
50 FnToken,
51 TraitToken,
52 ImplToken,
53 ForToken,
54 InToken,
55 AbiToken,
56 ConstToken,
57 StorageToken,
58 StrToken,
59 AsmToken,
60 ReturnToken,
61 IfToken,
62 ElseToken,
63 MatchToken,
64 MutToken,
65 LetToken,
66 WhileToken,
67 WhereToken,
68 RefToken,
69 TrueToken,
70 FalseToken,
71 BreakToken,
72 ContinueToken,
73 ConfigurableToken,
74 TypeToken,
75 PtrToken,
76 SliceToken
77}
78
79fn peek_token<T: Token>(peeker: Peeker<'_>) -> Option<T> {
80 let span = peeker
81 .peek_punct_kinds(T::PUNCT_KINDS, T::NOT_FOLLOWED_BY)
82 .ok()?;
83 Some(T::new(span))
84}
85
86fn parse_token<T: Token + Peek>(parser: &mut Parser) -> ParseResult<T> {
87 match parser.take() {
88 Some(value) => Ok(value),
89 None => {
90 let kinds = T::PUNCT_KINDS.to_owned();
91 Err(parser.emit_error(ParseErrorKind::ExpectedPunct { kinds }))
92 }
93 }
94}
95
96macro_rules! token_impls {
97 ($($ty:ty),*) => {
98 $(
99 impl Peek for $ty {
100 fn peek(peeker: Peeker<'_>) -> Option<Self> {
101 peek_token(peeker)
102 }
103 }
104
105 impl Parse for $ty {
106 fn parse(parser: &mut Parser) -> ParseResult<Self> {
107 parse_token(parser)
108 }
109 }
110 )*
111 };
112}
113
114token_impls! {
115 SemicolonToken,
116 ForwardSlashToken,
117 DoubleColonToken,
118 StarToken,
119 DoubleStarToken,
120 CommaToken,
121 ColonToken,
122 RightArrowToken,
123 LessThanToken,
124 GreaterThanToken,
125 OpenAngleBracketToken,
126 CloseAngleBracketToken,
127 EqToken,
128 AddEqToken,
129 SubEqToken,
130 StarEqToken,
131 DivEqToken,
132 ShlEqToken,
133 ShrEqToken,
134 FatRightArrowToken,
135 DotToken,
136 DoubleDotToken,
137 BangToken,
138 PercentToken,
139 AddToken,
140 SubToken,
141 ShrToken,
142 ShlToken,
143 AmpersandToken,
144 CaretToken,
145 PipeToken,
146 DoubleEqToken,
147 BangEqToken,
148 GreaterThanEqToken,
149 LessThanEqToken,
150 DoubleAmpersandToken,
151 DoublePipeToken,
152 UnderscoreToken,
153 HashToken,
154 HashBangToken
155}
156
157pub const RESERVED_KEYWORDS: phf::Set<&'static str> = phf::phf_set! {
159 "script",
160 "contract",
161 "predicate",
162 "library",
163 "mod",
164 "pub",
165 "use",
166 "as",
167 "struct",
168 "enum",
169 "self",
170 "fn",
171 "trait",
172 "impl",
173 "for",
174 "abi",
175 "const",
176 "storage",
177 "str",
178 "asm",
179 "return",
180 "if",
181 "else",
182 "match",
183 "mut",
184 "let",
185 "while",
186 "where",
187 "ref",
188 "true",
189 "false",
190 "break",
191 "continue",
192 "configurable",
193 "type",
194};