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