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.is_raw_ident() && 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 PanicToken
78}
79
80fn peek_token<T: Token>(peeker: Peeker<'_>) -> Option<T> {
81 let span = peeker
82 .peek_punct_kinds(T::PUNCT_KINDS, T::NOT_FOLLOWED_BY)
83 .ok()?;
84 Some(T::new(span))
85}
86
87fn parse_token<T: Token + Peek>(parser: &mut Parser) -> ParseResult<T> {
88 match parser.take() {
89 Some(value) => Ok(value),
90 None => {
91 let kinds = T::PUNCT_KINDS.to_owned();
92 Err(parser.emit_error(ParseErrorKind::ExpectedPunct { kinds }))
93 }
94 }
95}
96
97macro_rules! token_impls {
98 ($($ty:ty),*) => {
99 $(
100 impl Peek for $ty {
101 fn peek(peeker: Peeker<'_>) -> Option<Self> {
102 peek_token(peeker)
103 }
104 }
105
106 impl Parse for $ty {
107 fn parse(parser: &mut Parser) -> ParseResult<Self> {
108 parse_token(parser)
109 }
110 }
111 )*
112 };
113}
114
115token_impls! {
116 SemicolonToken,
117 ForwardSlashToken,
118 DoubleColonToken,
119 StarToken,
120 DoubleStarToken,
121 CommaToken,
122 ColonToken,
123 RightArrowToken,
124 LessThanToken,
125 GreaterThanToken,
126 OpenAngleBracketToken,
127 CloseAngleBracketToken,
128 EqToken,
129 AddEqToken,
130 SubEqToken,
131 StarEqToken,
132 DivEqToken,
133 ShlEqToken,
134 ShrEqToken,
135 FatRightArrowToken,
136 DotToken,
137 DoubleDotToken,
138 BangToken,
139 PercentToken,
140 AddToken,
141 SubToken,
142 ShrToken,
143 ShlToken,
144 AmpersandToken,
145 CaretToken,
146 PipeToken,
147 DoubleEqToken,
148 BangEqToken,
149 GreaterThanEqToken,
150 LessThanEqToken,
151 DoubleAmpersandToken,
152 DoublePipeToken,
153 UnderscoreToken,
154 HashToken,
155 HashBangToken
156}
157
158pub const RESERVED_KEYWORDS: phf::Set<&'static str> = phf::phf_set! {
160 "script",
161 "contract",
162 "predicate",
163 "library",
164 "mod",
165 "pub",
166 "use",
167 "as",
168 "struct",
169 "enum",
170 "self",
171 "fn",
172 "trait",
173 "impl",
174 "for",
175 "abi",
176 "const",
177 "storage",
178 "str",
179 "asm",
180 "return",
181 "if",
182 "else",
183 "match",
184 "mut",
185 "let",
186 "while",
187 "where",
188 "ref",
189 "true",
190 "false",
191 "break",
192 "continue",
193 "configurable",
194 "type",
195 "panic",
196};