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");
87define_keyword!(PanicToken, "panic");
88
89/// The type is a token.
90pub trait Token: Spanned + Sized {
91    /// Creates the token from the given `span`.
92    fn new(span: Span) -> Self;
93
94    /// Returns an identifier for this token.
95    fn ident(&self) -> Ident;
96
97    /// The sequence of punctuations that make up the token.
98    const PUNCT_KINDS: &'static [PunctKind];
99
100    /// Punctuations that will not follow the token.
101    const NOT_FOLLOWED_BY: &'static [PunctKind];
102
103    /// What the string representation of the token is when lexing.
104    const AS_STR: &'static str;
105}
106
107macro_rules! define_token (
108    ($ty_name:ident, $description:literal, $as_str:literal, [$($punct_kinds:ident),*], [$($not_followed_by:ident),*]) => {
109        #[derive(Clone, Debug, Serialize)]
110        pub struct $ty_name {
111            span: Span,
112        }
113
114        impl Default for $ty_name {
115            fn default() -> Self {
116                Self {
117                    span: Span::dummy()
118                }
119            }
120        }
121
122        impl Spanned for $ty_name {
123            fn span(&self) -> Span {
124                self.span.clone()
125            }
126        }
127
128        impl Token for $ty_name {
129            fn new(span: Span) -> Self {
130                $ty_name { span }
131            }
132
133            fn ident(&self) -> Ident {
134                Ident::new(self.span())
135            }
136
137            const PUNCT_KINDS: &'static [PunctKind] = &[$(PunctKind::$punct_kinds,)*];
138            const NOT_FOLLOWED_BY: &'static [PunctKind] = &[$(PunctKind::$not_followed_by,)*];
139            const AS_STR: &'static str = $as_str;
140        }
141
142        impl From<$ty_name> for Ident {
143            fn from(o: $ty_name) -> Ident {
144                o.ident()
145            }
146        }
147    };
148);
149
150define_token!(SemicolonToken, "a semicolon", ";", [Semicolon], []);
151define_token!(
152    ForwardSlashToken,
153    "a forward slash",
154    "/",
155    [ForwardSlash],
156    [Equals]
157);
158define_token!(
159    DoubleColonToken,
160    "a double colon (::)",
161    "::",
162    [Colon, Colon],
163    [Colon]
164);
165define_token!(StarToken, "an asterisk (*)", "*", [Star], [Equals]);
166define_token!(DoubleStarToken, "`**`", "**", [Star, Star], []);
167define_token!(CommaToken, "a comma", ",", [Comma], []);
168define_token!(ColonToken, "a colon", ":", [Colon], [Colon]);
169define_token!(
170    RightArrowToken,
171    "`->`",
172    "->",
173    [Sub, GreaterThan],
174    [GreaterThan, Equals]
175);
176define_token!(LessThanToken, "`<`", "<", [LessThan], [LessThan, Equals]);
177define_token!(
178    GreaterThanToken,
179    "`>`",
180    ">",
181    [GreaterThan],
182    [GreaterThan, Equals]
183);
184define_token!(OpenAngleBracketToken, "`<`", "<", [LessThan], []);
185define_token!(CloseAngleBracketToken, "`>`", ">", [GreaterThan], []);
186define_token!(EqToken, "`=`", "=", [Equals], [GreaterThan, Equals]);
187define_token!(AddEqToken, "`+=`", "+=", [Add, Equals], []);
188define_token!(SubEqToken, "`-=`", "-=", [Sub, Equals], []);
189define_token!(StarEqToken, "`*=`", "*=", [Star, Equals], []);
190define_token!(DivEqToken, "`/=`", "/=", [ForwardSlash, Equals], []);
191define_token!(ShlEqToken, "`<<=`", "<<=", [LessThan, LessThan, Equals], []);
192define_token!(
193    ShrEqToken,
194    "`>>=`",
195    ">>=",
196    [GreaterThan, GreaterThan, Equals],
197    []
198);
199define_token!(
200    FatRightArrowToken,
201    "`=>`",
202    "=>",
203    [Equals, GreaterThan],
204    [GreaterThan, Equals]
205);
206define_token!(DotToken, "`.`", ".", [Dot], []);
207define_token!(DoubleDotToken, "`..`", "..", [Dot, Dot], [Dot]);
208define_token!(BangToken, "`!`", "!", [Bang], [Equals]);
209define_token!(PercentToken, "`%`", "%", [Percent], []);
210define_token!(AddToken, "`+`", "+", [Add], [Equals]);
211define_token!(SubToken, "`-`", "-", [Sub], [Equals]);
212define_token!(
213    ShrToken,
214    "`>>`",
215    ">>",
216    [GreaterThan, GreaterThan],
217    [GreaterThan, Equals]
218);
219define_token!(
220    ShlToken,
221    "`<<`",
222    "<<",
223    [LessThan, LessThan],
224    [LessThan, Equals]
225);
226define_token!(AmpersandToken, "`&`", "&", [Ampersand], [Ampersand]);
227define_token!(CaretToken, "`^`", "^", [Caret], []);
228define_token!(PipeToken, "`|`", "|", [Pipe], [Pipe]);
229define_token!(
230    DoubleEqToken,
231    "`==`",
232    "==",
233    [Equals, Equals],
234    [Equals, GreaterThan]
235);
236define_token!(
237    BangEqToken,
238    "`!=`",
239    "!=",
240    [Bang, Equals],
241    [Equals, GreaterThan]
242);
243define_token!(
244    GreaterThanEqToken,
245    "`>=`",
246    ">=",
247    [GreaterThan, Equals],
248    [Equals, GreaterThan]
249);
250define_token!(
251    LessThanEqToken,
252    "`<=`",
253    "<=",
254    [LessThan, Equals],
255    [Equals, GreaterThan]
256);
257define_token!(
258    DoubleAmpersandToken,
259    "`&&`",
260    "&&",
261    [Ampersand, Ampersand],
262    [Ampersand]
263);
264define_token!(DoublePipeToken, "`||`", "||", [Pipe, Pipe], [Pipe]);
265define_token!(UnderscoreToken, "`_`", "_", [Underscore], [Underscore]);
266define_token!(HashToken, "`#`", "#", [Sharp], []);
267define_token!(HashBangToken, "`#!`", "#!", [Sharp, Bang], []);