@@ -167,14 +167,9 @@ pub enum Token {
167
167
Break ( BreakToken ) ,
168
168
Begin ( BeginToken ) ,
169
169
End ,
170
- Eof ,
171
170
}
172
171
173
172
impl Token {
174
- crate fn is_eof ( & self ) -> bool {
175
- matches ! ( self , Token :: Eof )
176
- }
177
-
178
173
pub fn is_hardbreak_tok ( & self ) -> bool {
179
174
matches ! ( self , Token :: Break ( BreakToken { offset: 0 , blank_space: SIZE_INFINITY } ) )
180
175
}
@@ -187,7 +182,6 @@ impl fmt::Display for Token {
187
182
Token :: Break ( _) => f. write_str ( "BREAK" ) ,
188
183
Token :: Begin ( _) => f. write_str ( "BEGIN" ) ,
189
184
Token :: End => f. write_str ( "END" ) ,
190
- Token :: Eof => f. write_str ( "EOF" ) ,
191
185
}
192
186
}
193
187
}
@@ -212,10 +206,6 @@ pub struct Printer {
212
206
margin : isize ,
213
207
/// Number of spaces left on line
214
208
space : isize ,
215
- /// Index of left side of input stream
216
- left : usize ,
217
- /// Index of right side of input stream
218
- right : usize ,
219
209
/// Ring-buffer of tokens and calculated sizes
220
210
buf : RingBuffer < BufEntry > ,
221
211
/// Running size of stream "...left"
@@ -233,6 +223,9 @@ pub struct Printer {
233
223
print_stack : Vec < PrintStackElem > ,
234
224
/// Buffered indentation to avoid writing trailing whitespace
235
225
pending_indentation : isize ,
226
+ /// The token most recently popped from the left boundary of the
227
+ /// ring-buffer for printing
228
+ last_printed : Option < Token > ,
236
229
}
237
230
238
231
#[ derive( Clone ) ]
@@ -241,39 +234,34 @@ struct BufEntry {
241
234
size : isize ,
242
235
}
243
236
244
- impl Default for BufEntry {
245
- fn default ( ) -> Self {
246
- BufEntry { token : Token :: Eof , size : 0 }
247
- }
248
- }
249
-
250
237
impl Printer {
251
238
pub fn new ( ) -> Self {
252
239
let linewidth = 78 ;
253
- let mut buf = RingBuffer :: new ( ) ;
254
- buf. advance_right ( ) ;
255
240
Printer {
256
241
out : String :: new ( ) ,
257
242
margin : linewidth as isize ,
258
243
space : linewidth as isize ,
259
- left : 0 ,
260
- right : 0 ,
261
- buf,
244
+ buf : RingBuffer :: new ( ) ,
262
245
left_total : 0 ,
263
246
right_total : 0 ,
264
247
scan_stack : VecDeque :: new ( ) ,
265
248
print_stack : Vec :: new ( ) ,
266
249
pending_indentation : 0 ,
250
+ last_printed : None ,
267
251
}
268
252
}
269
253
270
- pub fn last_token ( & self ) -> Token {
271
- self . buf [ self . right ] . token . clone ( )
254
+ pub fn last_token ( & self ) -> Option < & Token > {
255
+ self . last_token_still_buffered ( ) . or_else ( || self . last_printed . as_ref ( ) )
256
+ }
257
+
258
+ pub fn last_token_still_buffered ( & self ) -> Option < & Token > {
259
+ self . buf . last ( ) . map ( |last| & last. token )
272
260
}
273
261
274
262
/// Be very careful with this!
275
- pub fn replace_last_token ( & mut self , t : Token ) {
276
- self . buf [ self . right ] . token = t;
263
+ pub fn replace_last_token_still_buffered ( & mut self , t : Token ) {
264
+ self . buf . last_mut ( ) . unwrap ( ) . token = t;
277
265
}
278
266
279
267
fn scan_eof ( & mut self ) {
@@ -287,89 +275,63 @@ impl Printer {
287
275
if self . scan_stack . is_empty ( ) {
288
276
self . left_total = 1 ;
289
277
self . right_total = 1 ;
290
- self . right = self . left ;
291
- self . buf . truncate ( 1 ) ;
292
- } else {
293
- self . advance_right ( ) ;
278
+ self . buf . clear ( ) ;
294
279
}
295
- self . scan_push ( BufEntry { token : Token :: Begin ( b) , size : -self . right_total } ) ;
280
+ let right = self . buf . push ( BufEntry { token : Token :: Begin ( b) , size : -self . right_total } ) ;
281
+ self . scan_stack . push_front ( right) ;
296
282
}
297
283
298
284
fn scan_end ( & mut self ) {
299
285
if self . scan_stack . is_empty ( ) {
300
286
self . print_end ( ) ;
301
287
} else {
302
- self . advance_right ( ) ;
303
- self . scan_push ( BufEntry { token : Token :: End , size : - 1 } ) ;
288
+ let right = self . buf . push ( BufEntry { token : Token :: End , size : - 1 } ) ;
289
+ self . scan_stack . push_front ( right ) ;
304
290
}
305
291
}
306
292
307
293
fn scan_break ( & mut self , b : BreakToken ) {
308
294
if self . scan_stack . is_empty ( ) {
309
295
self . left_total = 1 ;
310
296
self . right_total = 1 ;
311
- self . right = self . left ;
312
- self . buf . truncate ( 1 ) ;
297
+ self . buf . clear ( ) ;
313
298
} else {
314
- self . advance_right ( ) ;
299
+ self . check_stack ( 0 ) ;
315
300
}
316
- self . check_stack ( 0 ) ;
317
- self . scan_push ( BufEntry { token : Token :: Break ( b ) , size : - self . right_total } ) ;
301
+ let right = self . buf . push ( BufEntry { token : Token :: Break ( b ) , size : - self . right_total } ) ;
302
+ self . scan_stack . push_front ( right ) ;
318
303
self . right_total += b. blank_space ;
319
304
}
320
305
321
306
fn scan_string ( & mut self , s : Cow < ' static , str > ) {
322
307
if self . scan_stack . is_empty ( ) {
323
- self . print_string ( s) ;
308
+ self . print_string ( & s) ;
324
309
} else {
325
- self . advance_right ( ) ;
326
310
let len = s. len ( ) as isize ;
327
- self . buf [ self . right ] = BufEntry { token : Token :: String ( s) , size : len } ;
311
+ self . buf . push ( BufEntry { token : Token :: String ( s) , size : len } ) ;
328
312
self . right_total += len;
329
313
self . check_stream ( ) ;
330
314
}
331
315
}
332
316
333
317
fn check_stream ( & mut self ) {
334
- if self . right_total - self . left_total > self . space {
335
- if Some ( & self . left ) == self . scan_stack . back ( ) {
336
- let scanned = self . scan_pop_bottom ( ) ;
337
- self . buf [ scanned ] . size = SIZE_INFINITY ;
318
+ while self . right_total - self . left_total > self . space {
319
+ if * self . scan_stack . back ( ) . unwrap ( ) == self . buf . index_of_first ( ) {
320
+ self . scan_stack . pop_back ( ) . unwrap ( ) ;
321
+ self . buf . first_mut ( ) . unwrap ( ) . size = SIZE_INFINITY ;
338
322
}
339
323
self . advance_left ( ) ;
340
- if self . left != self . right {
341
- self . check_stream ( ) ;
324
+ if self . buf . is_empty ( ) {
325
+ break ;
342
326
}
343
327
}
344
328
}
345
329
346
- fn scan_push ( & mut self , entry : BufEntry ) {
347
- self . buf [ self . right ] = entry;
348
- self . scan_stack . push_front ( self . right ) ;
349
- }
350
-
351
- fn scan_pop ( & mut self ) -> usize {
352
- self . scan_stack . pop_front ( ) . unwrap ( )
353
- }
354
-
355
- fn scan_top ( & self ) -> usize {
356
- * self . scan_stack . front ( ) . unwrap ( )
357
- }
358
-
359
- fn scan_pop_bottom ( & mut self ) -> usize {
360
- self . scan_stack . pop_back ( ) . unwrap ( )
361
- }
362
-
363
- fn advance_right ( & mut self ) {
364
- self . right += 1 ;
365
- self . buf . advance_right ( ) ;
366
- }
367
-
368
330
fn advance_left ( & mut self ) {
369
- let mut left_size = self . buf [ self . left ] . size ;
331
+ let mut left_size = self . buf . first ( ) . unwrap ( ) . size ;
370
332
371
333
while left_size >= 0 {
372
- let left = self . buf [ self . left ] . token . clone ( ) ;
334
+ let left = self . buf . first ( ) . unwrap ( ) . token . clone ( ) ;
373
335
374
336
let len = match left {
375
337
Token :: Break ( b) => b. blank_space ,
@@ -385,39 +347,38 @@ impl Printer {
385
347
386
348
self . left_total += len;
387
349
388
- if self . left == self . right {
350
+ self . buf . advance_left ( ) ;
351
+ if self . buf . is_empty ( ) {
389
352
break ;
390
353
}
391
354
392
- self . buf . advance_left ( ) ;
393
- self . left += 1 ;
394
-
395
- left_size = self . buf [ self . left ] . size ;
355
+ left_size = self . buf . first ( ) . unwrap ( ) . size ;
396
356
}
397
357
}
398
358
399
- fn check_stack ( & mut self , k : usize ) {
400
- if ! self . scan_stack . is_empty ( ) {
401
- let x = self . scan_top ( ) ;
402
- match self . buf [ x ] . token {
359
+ fn check_stack ( & mut self , mut k : usize ) {
360
+ while let Some ( & x ) = self . scan_stack . front ( ) {
361
+ let mut entry = & mut self . buf [ x ] ;
362
+ match entry . token {
403
363
Token :: Begin ( _) => {
404
- if k > 0 {
405
- self . scan_pop ( ) ;
406
- self . buf [ x] . size += self . right_total ;
407
- self . check_stack ( k - 1 ) ;
364
+ if k == 0 {
365
+ break ;
408
366
}
367
+ self . scan_stack . pop_front ( ) . unwrap ( ) ;
368
+ entry. size += self . right_total ;
369
+ k -= 1 ;
409
370
}
410
371
Token :: End => {
411
372
// paper says + not =, but that makes no sense.
412
- self . scan_pop ( ) ;
413
- self . buf [ x ] . size = 1 ;
414
- self . check_stack ( k + 1 ) ;
373
+ self . scan_stack . pop_front ( ) . unwrap ( ) ;
374
+ entry . size = 1 ;
375
+ k += 1 ;
415
376
}
416
377
_ => {
417
- self . scan_pop ( ) ;
418
- self . buf [ x ] . size += self . right_total ;
419
- if k > 0 {
420
- self . check_stack ( k ) ;
378
+ self . scan_stack . pop_front ( ) . unwrap ( ) ;
379
+ entry . size += self . right_total ;
380
+ if k == 0 {
381
+ break ;
421
382
}
422
383
}
423
384
}
@@ -477,7 +438,7 @@ impl Printer {
477
438
}
478
439
}
479
440
480
- fn print_string ( & mut self , s : Cow < ' static , str > ) {
441
+ fn print_string ( & mut self , s : & str ) {
481
442
let len = s. len ( ) as isize ;
482
443
// assert!(len <= space);
483
444
self . space -= len;
@@ -491,21 +452,21 @@ impl Printer {
491
452
self . out . reserve ( self . pending_indentation as usize ) ;
492
453
self . out . extend ( std:: iter:: repeat ( ' ' ) . take ( self . pending_indentation as usize ) ) ;
493
454
self . pending_indentation = 0 ;
494
- self . out . push_str ( & s) ;
455
+ self . out . push_str ( s) ;
495
456
}
496
457
497
458
fn print ( & mut self , token : Token , l : isize ) {
498
- match token {
499
- Token :: Begin ( b) => self . print_begin ( b, l) ,
459
+ match & token {
460
+ Token :: Begin ( b) => self . print_begin ( * b, l) ,
500
461
Token :: End => self . print_end ( ) ,
501
- Token :: Break ( b) => self . print_break ( b, l) ,
462
+ Token :: Break ( b) => self . print_break ( * b, l) ,
502
463
Token :: String ( s) => {
503
464
let len = s. len ( ) as isize ;
504
465
assert_eq ! ( len, l) ;
505
466
self . print_string ( s) ;
506
467
}
507
- Token :: Eof => panic ! ( ) , // Eof should never get here.
508
468
}
469
+ self . last_printed = Some ( token) ;
509
470
}
510
471
511
472
// Convenience functions to talk to the printer.
@@ -560,7 +521,10 @@ impl Printer {
560
521
}
561
522
562
523
pub fn is_beginning_of_line ( & self ) -> bool {
563
- self . last_token ( ) . is_eof ( ) || self . last_token ( ) . is_hardbreak_tok ( )
524
+ match self . last_token ( ) {
525
+ Some ( last_token) => last_token. is_hardbreak_tok ( ) ,
526
+ None => true ,
527
+ }
564
528
}
565
529
566
530
pub fn hardbreak_tok_offset ( off : isize ) -> Token {
0 commit comments