@@ -42,4 +42,182 @@ module Impl {
4242 )
4343 }
4444 }
45+
46+ /**
47+ * A [character literal][1]. For example:
48+ *
49+ * ```rust
50+ * 'x';
51+ * ```
52+ *
53+ * [1]: https://doc.rust-lang.org/reference/tokens.html#character-literals
54+ */
55+ class CharLiteralExpr extends LiteralExpr {
56+ CharLiteralExpr ( ) { this .getTextValue ( ) .regexpMatch ( "'.*'" ) }
57+
58+ override string getAPrimaryQlClass ( ) { result = "CharLiteralExpr" }
59+ }
60+
61+ /**
62+ * A [string literal][1]. For example:
63+ *
64+ * ```rust
65+ * "Hello, world!";
66+ * ```
67+ *
68+ * [1]: https://doc.rust-lang.org/reference/tokens.html#string-literals
69+ */
70+ class StringLiteralExpr extends LiteralExpr {
71+ StringLiteralExpr ( ) { this .getTextValue ( ) .regexpMatch ( "r?#*\".*\"#*" ) }
72+
73+ override string getAPrimaryQlClass ( ) { result = "StringLiteralExpr" }
74+ }
75+
76+ /**
77+ * A number literal.
78+ */
79+ abstract class NumberLiteralExpr extends LiteralExpr { }
80+
81+ // https://doc.rust-lang.org/reference/tokens.html#integer-literals
82+ private module IntegerLiteralRegexs {
83+ bindingset [ s]
84+ string paren ( string s ) { result = "(?:" + s + ")" }
85+
86+ string integerLiteral ( ) {
87+ result =
88+ paren ( paren ( decLiteral ( ) ) + "|" + paren ( binLiteral ( ) ) + "|" + paren ( octLiteral ( ) ) + "|" +
89+ paren ( hexLiteral ( ) ) ) + "(" + suffix ( ) + ")?"
90+ }
91+
92+ private string suffix ( ) { result = "u8|i8|u16|i16|u32|i32|u64|i64|u128|i128|usize|isize" }
93+
94+ string decLiteral ( ) { result = decDigit ( ) + "(?:" + decDigit ( ) + "|_)*" }
95+
96+ string binLiteral ( ) {
97+ result = "0b(?:" + binDigit ( ) + "|_)*" + binDigit ( ) + "(?:" + binDigit ( ) + "|_)*"
98+ }
99+
100+ string octLiteral ( ) {
101+ result = "0o(?:" + octDigit ( ) + "|_)*" + octDigit ( ) + "(?:" + octDigit ( ) + "|_)*"
102+ }
103+
104+ string hexLiteral ( ) {
105+ result = "0x(?:" + hexDigit ( ) + "|_)*" + hexDigit ( ) + "(?:" + hexDigit ( ) + "|_)*"
106+ }
107+
108+ string decDigit ( ) { result = "[0-9]" }
109+
110+ string binDigit ( ) { result = "[01]" }
111+
112+ string octDigit ( ) { result = "[0-7]" }
113+
114+ string hexDigit ( ) { result = "[0-9a-fA-F]" }
115+ }
116+
117+ /**
118+ * An [integer literal][1]. For example:
119+ *
120+ * ```rust
121+ * 42;
122+ * ```
123+ *
124+ * [1]: https://doc.rust-lang.org/reference/tokens.html#integer-literals
125+ */
126+ class IntegerLiteralExpr extends NumberLiteralExpr {
127+ IntegerLiteralExpr ( ) { this .getTextValue ( ) .regexpMatch ( IntegerLiteralRegexs:: integerLiteral ( ) ) }
128+
129+ /**
130+ * Get the suffix of this integer literal, if any.
131+ *
132+ * For example, `42u8` has the suffix `u8`.
133+ */
134+ string getSuffix ( ) {
135+ exists ( string s , string reg |
136+ s = this .getTextValue ( ) and
137+ reg = IntegerLiteralRegexs:: integerLiteral ( ) and
138+ result = s .regexpCapture ( reg , 1 )
139+ )
140+ }
141+
142+ override string getAPrimaryQlClass ( ) { result = "IntegerLiteralExpr" }
143+ }
144+
145+ // https://doc.rust-lang.org/reference/tokens.html#floating-point-literals
146+ private module FloatLiteralRegexs {
147+ private import IntegerLiteralRegexs
148+
149+ string floatLiteral ( ) {
150+ result =
151+ paren ( decLiteral ( ) + "\\." ) + "|" + paren ( floatLiteralSuffix1 ( ) ) + "|" +
152+ paren ( floatLiteralSuffix2 ( ) )
153+ }
154+
155+ string floatLiteralSuffix1 ( ) {
156+ result = decLiteral ( ) + "\\." + decLiteral ( ) + "(" + suffix ( ) + ")?"
157+ }
158+
159+ string floatLiteralSuffix2 ( ) {
160+ result =
161+ decLiteral ( ) + paren ( "\\." + decLiteral ( ) ) + "?" + paren ( exponent ( ) ) + "(" + suffix ( ) + ")?"
162+ }
163+
164+ string integerSuffixLiteral ( ) {
165+ result =
166+ paren ( paren ( decLiteral ( ) ) + "|" + paren ( binLiteral ( ) ) + "|" + paren ( octLiteral ( ) ) + "|" +
167+ paren ( hexLiteral ( ) ) ) + "(" + suffix ( ) + ")"
168+ }
169+
170+ private string suffix ( ) { result = "f32|f64" }
171+
172+ string exponent ( ) {
173+ result =
174+ "(?:e|E)(?:\\+|-)?(?:" + decDigit ( ) + "|_)*" + decDigit ( ) + "(?:" + decDigit ( ) + "|_)*"
175+ }
176+ }
177+
178+ /**
179+ * A [floating-point literal][1]. For example:
180+ *
181+ * ```rust
182+ * 42.0;
183+ * ```
184+ *
185+ * [1]: https://doc.rust-lang.org/reference/tokens.html#floating-point-literals
186+ */
187+ class FloatLiteralExpr extends NumberLiteralExpr {
188+ FloatLiteralExpr ( ) {
189+ this .getTextValue ( )
190+ .regexpMatch ( IntegerLiteralRegexs:: paren ( FloatLiteralRegexs:: floatLiteral ( ) ) + "|" +
191+ IntegerLiteralRegexs:: paren ( FloatLiteralRegexs:: integerSuffixLiteral ( ) ) ) and
192+ // E.g. `0x01_f32` is an integer, not a float
193+ not this instanceof IntegerLiteralExpr
194+ }
195+
196+ /**
197+ * Get the suffix of this floating-point literal, if any.
198+ *
199+ * For example, `42.0f32` has the suffix `f32`.
200+ */
201+ string getSuffix ( ) {
202+ exists ( string s , string reg |
203+ reg =
204+ IntegerLiteralRegexs:: paren ( FloatLiteralRegexs:: floatLiteralSuffix1 ( ) ) + "|" +
205+ IntegerLiteralRegexs:: paren ( FloatLiteralRegexs:: floatLiteralSuffix2 ( ) ) + "|" +
206+ IntegerLiteralRegexs:: paren ( FloatLiteralRegexs:: integerSuffixLiteral ( ) ) and
207+ s = this .getTextValue ( ) and
208+ result = s .regexpCapture ( reg , [ 1 , 2 , 3 ] )
209+ )
210+ }
211+
212+ override string getAPrimaryQlClass ( ) { result = "FloatLiteralExpr" }
213+ }
214+
215+ /**
216+ * A Boolean literal. Either `true` or `false`.
217+ */
218+ class BooleanLiteralExpr extends LiteralExpr {
219+ BooleanLiteralExpr ( ) { this .getTextValue ( ) = [ "false" , "true" ] }
220+
221+ override string getAPrimaryQlClass ( ) { result = "BooleanLiteralExpr" }
222+ }
45223}
0 commit comments