sway_ast/
keywords.rs

1use crate::priv_prelude::*;
2
3/// The type is a keyword.
4pub trait Keyword: Spanned + Sized {
5    /// Creates the keyword from the given `span`.
6    fn new(span: Span) -> Self;
7
8    /// Returns an identifier for this keyword.
9    fn ident(&self) -> Ident;
10
11    /// What the string representation of the keyword is when lexing.
12    const AS_STR: &'static str;
13}
14
15macro_rules! define_keyword (
16    ($ty_name:ident, $keyword:literal) => {
17        #[derive(Clone, Debug, Serialize)]
18        pub struct $ty_name {
19            span: Span,
20        }
21
22        impl Spanned for $ty_name {
23            fn span(&self) -> Span {
24                self.span.clone()
25            }
26        }
27
28        impl Keyword for $ty_name {
29            fn new(span: Span) -> Self {
30                $ty_name { span }
31            }
32
33            fn ident(&self) -> Ident {
34                Ident::new(self.span())
35            }
36
37            const AS_STR: &'static str = $keyword;
38        }
39
40        impl From<$ty_name> for Ident {
41            fn from(o: $ty_name) -> Ident {
42                o.ident()
43            }
44        }
45    };
46);
47
48define_keyword!(ScriptToken, "script");
49define_keyword!(ContractToken, "contract");
50define_keyword!(PredicateToken, "predicate");
51define_keyword!(LibraryToken, "library");
52define_keyword!(ModToken, "mod");
53define_keyword!(PubToken, "pub");
54define_keyword!(UseToken, "use");
55define_keyword!(AsToken, "as");
56define_keyword!(StructToken, "struct");
57define_keyword!(ClassToken, "class"); // Not in the language! Exists for recovery.
58define_keyword!(EnumToken, "enum");
59define_keyword!(SelfToken, "self");
60define_keyword!(FnToken, "fn");
61define_keyword!(TraitToken, "trait");
62define_keyword!(ImplToken, "impl");
63define_keyword!(ForToken, "for");
64define_keyword!(InToken, "in");
65define_keyword!(AbiToken, "abi");
66define_keyword!(ConstToken, "const");
67define_keyword!(StorageToken, "storage");
68define_keyword!(StrToken, "str");
69define_keyword!(AsmToken, "asm");
70define_keyword!(ReturnToken, "return");
71define_keyword!(IfToken, "if");
72define_keyword!(ElseToken, "else");
73define_keyword!(MatchToken, "match");
74define_keyword!(MutToken, "mut");
75define_keyword!(LetToken, "let");
76define_keyword!(WhileToken, "while");
77define_keyword!(WhereToken, "where");
78define_keyword!(RefToken, "ref");
79define_keyword!(TrueToken, "true");
80define_keyword!(FalseToken, "false");
81define_keyword!(BreakToken, "break");
82define_keyword!(ContinueToken, "continue");
83define_keyword!(ConfigurableToken, "configurable");
84define_keyword!(TypeToken, "type");
85define_keyword!(PtrToken, "__ptr");
86define_keyword!(SliceToken, "__slice");
87
88/// The type is a token.
89pub trait Token: Spanned + Sized {
90    /// Creates the token from the given `span`.
91    fn new(span: Span) -> Self;
92
93    /// Returns an identifier for this token.
94    fn ident(&self) -> Ident;
95
96    /// The sequence of punctuations that make up the token.
97    const PUNCT_KINDS: &'static [PunctKind];
98
99    /// Punctuations that will not follow the token.
100    const NOT_FOLLOWED_BY: &'static [PunctKind];
101
102    /// What the string representation of the token is when lexing.
103    const AS_STR: &'static str;
104}
105
106macro_rules! define_token (
107    ($ty_name:ident, $description:literal, $as_str:literal, [$($punct_kinds:ident),*], [$($not_followed_by:ident),*]) => {
108        #[derive(Clone, Debug, Serialize)]
109        pub struct $ty_name {
110            span: Span,
111        }
112
113        impl Default for $ty_name {
114            fn default() -> Self {
115                Self {
116                    span: Span::dummy()
117                }
118            }
119        }
120
121        impl Spanned for $ty_name {
122            fn span(&self) -> Span {
123                self.span.clone()
124            }
125        }
126
127        impl Token for $ty_name {
128            fn new(span: Span) -> Self {
129                $ty_name { span }
130            }
131
132            fn ident(&self) -> Ident {
133                Ident::new(self.span())
134            }
135
136            const PUNCT_KINDS: &'static [PunctKind] = &[$(PunctKind::$punct_kinds,)*];
137            const NOT_FOLLOWED_BY: &'static [PunctKind] = &[$(PunctKind::$not_followed_by,)*];
138            const AS_STR: &'static str = $as_str;
139        }
140
141        impl From<$ty_name> for Ident {
142            fn from(o: $ty_name) -> Ident {
143                o.ident()
144            }
145        }
146    };
147);
148
149define_token!(SemicolonToken, "a semicolon", ";", [Semicolon], []);
150define_token!(
151    ForwardSlashToken,
152    "a forward slash",
153    "/",
154    [ForwardSlash],
155    [Equals]
156);
157define_token!(
158    DoubleColonToken,
159    "a double colon (::)",
160    "::",
161    [Colon, Colon],
162    [Colon]
163);
164define_token!(StarToken, "an asterisk (*)", "*", [Star], [Equals]);
165define_token!(DoubleStarToken, "`**`", "**", [Star, Star], []);
166define_token!(CommaToken, "a comma", ",", [Comma], []);
167define_token!(ColonToken, "a colon", ":", [Colon], [Colon]);
168define_token!(
169    RightArrowToken,
170    "`->`",
171    "->",
172    [Sub, GreaterThan],
173    [GreaterThan, Equals]
174);
175define_token!(LessThanToken, "`<`", "<", [LessThan], [LessThan, Equals]);
176define_token!(
177    GreaterThanToken,
178    "`>`",
179    ">",
180    [GreaterThan],
181    [GreaterThan, Equals]
182);
183define_token!(OpenAngleBracketToken, "`<`", "<", [LessThan], []);
184define_token!(CloseAngleBracketToken, "`>`", ">", [GreaterThan], []);
185define_token!(EqToken, "`=`", "=", [Equals], [GreaterThan, Equals]);
186define_token!(AddEqToken, "`+=`", "+=", [Add, Equals], []);
187define_token!(SubEqToken, "`-=`", "-=", [Sub, Equals], []);
188define_token!(StarEqToken, "`*=`", "*=", [Star, Equals], []);
189define_token!(DivEqToken, "`/=`", "/=", [ForwardSlash, Equals], []);
190define_token!(ShlEqToken, "`<<=`", "<<=", [LessThan, LessThan, Equals], []);
191define_token!(
192    ShrEqToken,
193    "`>>=`",
194    ">>=",
195    [GreaterThan, GreaterThan, Equals],
196    []
197);
198define_token!(
199    FatRightArrowToken,
200    "`=>`",
201    "=>",
202    [Equals, GreaterThan],
203    [GreaterThan, Equals]
204);
205define_token!(DotToken, "`.`", ".", [Dot], []);
206define_token!(DoubleDotToken, "`..`", "..", [Dot, Dot], [Dot]);
207define_token!(BangToken, "`!`", "!", [Bang], [Equals]);
208define_token!(PercentToken, "`%`", "%", [Percent], []);
209define_token!(AddToken, "`+`", "+", [Add], [Equals]);
210define_token!(SubToken, "`-`", "-", [Sub], [Equals]);
211define_token!(
212    ShrToken,
213    "`>>`",
214    ">>",
215    [GreaterThan, GreaterThan],
216    [GreaterThan, Equals]
217);
218define_token!(
219    ShlToken,
220    "`<<`",
221    "<<",
222    [LessThan, LessThan],
223    [LessThan, Equals]
224);
225define_token!(AmpersandToken, "`&`", "&", [Ampersand], [Ampersand]);
226define_token!(CaretToken, "`^`", "^", [Caret], []);
227define_token!(PipeToken, "`|`", "|", [Pipe], [Pipe]);
228define_token!(
229    DoubleEqToken,
230    "`==`",
231    "==",
232    [Equals, Equals],
233    [Equals, GreaterThan]
234);
235define_token!(
236    BangEqToken,
237    "`!=`",
238    "!=",
239    [Bang, Equals],
240    [Equals, GreaterThan]
241);
242define_token!(
243    GreaterThanEqToken,
244    "`>=`",
245    ">=",
246    [GreaterThan, Equals],
247    [Equals, GreaterThan]
248);
249define_token!(
250    LessThanEqToken,
251    "`<=`",
252    "<=",
253    [LessThan, Equals],
254    [Equals, GreaterThan]
255);
256define_token!(
257    DoubleAmpersandToken,
258    "`&&`",
259    "&&",
260    [Ampersand, Ampersand],
261    [Ampersand]
262);
263define_token!(DoublePipeToken, "`||`", "||", [Pipe, Pipe], [Pipe]);
264define_token!(UnderscoreToken, "`_`", "_", [Underscore], [Underscore]);
265define_token!(HashToken, "`#`", "#", [Sharp], []);
266define_token!(HashBangToken, "`#!`", "#!", [Sharp, Bang], []);