@@ -60,6 +60,7 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
60
60
span : & mut Span ,
61
61
suppress : & FxHashSet < SmolStr > ,
62
62
) -> Result < ( ) , Diagnostic > {
63
+ let mut dirty = false ;
63
64
* self . i = span. start ;
64
65
while * self . i < span. end {
65
66
if let Some ( define_name) = self . parse_define_begin ( span) ? {
@@ -69,15 +70,24 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
69
70
self . parse_simple_define ( span, define_name) ?;
70
71
continue ;
71
72
}
73
+ if self . parse_undef ( span) ? {
74
+ continue ;
75
+ }
72
76
if self . substitute_simple_define ( span, suppress) ? {
73
77
continue ;
74
78
}
75
79
if self . substitute_function_define ( span, suppress) ? {
76
80
continue ;
77
81
}
82
+ if self . substitute_concat ( span) ? {
83
+ dirty = true ;
84
+ continue ;
85
+ }
78
86
* self . i += 1 ;
79
87
}
80
-
88
+ if dirty {
89
+ self . process ( span, suppress) ?;
90
+ }
81
91
Ok ( ( ) )
82
92
}
83
93
@@ -133,7 +143,7 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
133
143
if !matches ! ( name, Token :: Name ( _) | Token :: LParen ) {
134
144
return Ok ( false ) ;
135
145
}
136
- self . tokens . remove ( * self . i ) ;
146
+ self . remove_token ( span ) ;
137
147
let mut args = vec ! [ ] ;
138
148
while name != Token :: RParen {
139
149
if name != Token :: Comma {
@@ -165,18 +175,21 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
165
175
let mut body = vec ! [ ] ;
166
176
self . expect_no_eof ( ) ?;
167
177
let mut token = get_token ( & self . tokens [ * self . i ] ) ;
168
- while token != & Token :: Newline {
169
- body. push ( token. clone ( ) ) ;
170
- self . remove_token ( span) ;
171
- self . expect_no_eof ( ) ?;
172
- token = get_token ( & self . tokens [ * self . i ] ) ;
178
+ loop {
173
179
if token == & Token :: Backslash {
174
180
self . remove_token ( span) ;
175
181
self . expect_no_eof ( ) ?;
176
182
self . remove_token ( span) ;
177
183
self . expect_no_eof ( ) ?;
178
184
token = get_token ( & self . tokens [ * self . i ] ) ;
179
185
}
186
+ if token == & Token :: Newline {
187
+ break ;
188
+ }
189
+ body. push ( token. clone ( ) ) ;
190
+ self . remove_token ( span) ;
191
+ self . expect_no_eof ( ) ?;
192
+ token = get_token ( & self . tokens [ * self . i ] ) ;
180
193
}
181
194
self . remove_token ( span) ;
182
195
Ok ( body)
@@ -208,7 +221,8 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
208
221
let subspan_end = * self . i + simple_define_body. len ( ) ;
209
222
let mut subspan = * self . i ..subspan_end;
210
223
self . process ( & mut subspan, & suppress) ?;
211
- span. end += subspan. end - subspan_end;
224
+ span. end =
225
+ ( ( span. end as isize ) + ( ( subspan. end as isize ) - ( subspan_end as isize ) ) ) as usize ;
212
226
Ok ( true )
213
227
}
214
228
@@ -298,7 +312,73 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
298
312
suppress. insert ( macro_name) ;
299
313
let mut subspan = * self . i ..i;
300
314
self . process ( & mut subspan, & suppress) ?;
301
- span. end += subspan. end - i;
315
+ span. end = ( ( span. end as isize ) + ( ( subspan. end as isize ) - ( i as isize ) ) ) as usize ;
316
+ Ok ( true )
317
+ }
318
+
319
+ fn parse_undef ( & mut self , span : & mut Span ) -> Result < bool , Diagnostic > {
320
+ if get_token ( & self . tokens [ * self . i ] ) != & Token :: Undef {
321
+ return Ok ( false ) ;
322
+ }
323
+ self . remove_token ( span) ;
324
+ self . expect_no_eof ( ) ?;
325
+ let name = get_token ( & self . tokens [ * self . i ] ) . clone ( ) ;
326
+ self . simple_defines . remove ( name. to_string ( ) . as_str ( ) ) ;
327
+ self . function_defines . remove ( name. to_string ( ) . as_str ( ) ) ;
328
+ self . remove_token ( span) ;
329
+ Ok ( true )
330
+ }
331
+
332
+ fn substitute_concat ( & mut self , span : & mut Span ) -> Result < bool , Diagnostic > {
333
+ let Token :: Name ( macro_name) = get_token ( & self . tokens [ * self . i ] ) else {
334
+ return Ok ( false ) ;
335
+ } ;
336
+ let macro_name_span = get_span ( & self . tokens [ * self . i ] ) ;
337
+ if macro_name != "CONCAT" {
338
+ return Ok ( false ) ;
339
+ }
340
+ if self
341
+ . tokens
342
+ . get ( * self . i + 1 )
343
+ . is_none_or ( |token| get_token ( token) != & Token :: LParen )
344
+ {
345
+ return Ok ( false ) ;
346
+ }
347
+ if self
348
+ . tokens
349
+ . get ( * self . i + 3 )
350
+ . is_none_or ( |token| get_token ( token) != & Token :: Comma )
351
+ {
352
+ return Ok ( false ) ;
353
+ }
354
+ if self
355
+ . tokens
356
+ . get ( * self . i + 5 )
357
+ . is_none_or ( |token| get_token ( token) != & Token :: RParen )
358
+ {
359
+ return Ok ( false ) ;
360
+ }
361
+ let Some ( Token :: Name ( left) ) = self . tokens . get ( * self . i + 2 ) . map ( get_token) . cloned ( ) else {
362
+ return Ok ( false ) ;
363
+ } ;
364
+ let Some ( Token :: Name ( right) ) = self . tokens . get ( * self . i + 4 ) . map ( get_token) . cloned ( ) else {
365
+ return Ok ( false ) ;
366
+ } ;
367
+ self . remove_token ( span) ;
368
+ self . remove_token ( span) ;
369
+ self . remove_token ( span) ;
370
+ self . remove_token ( span) ;
371
+ self . remove_token ( span) ;
372
+ self . remove_token ( span) ;
373
+ self . tokens . insert (
374
+ * self . i ,
375
+ (
376
+ macro_name_span. start ,
377
+ Token :: Name ( format ! ( "{}{}" , left, right) . into ( ) ) ,
378
+ macro_name_span. end ,
379
+ ) ,
380
+ ) ;
381
+ span. end += 1 ;
302
382
Ok ( true )
303
383
}
304
384
}
0 commit comments