@@ -42,4 +42,191 @@ module Impl {
42
42
)
43
43
}
44
44
}
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
+ }
45
232
}
0 commit comments