@@ -21,6 +21,7 @@ use rsparse = parse;
21
21
use std:: fmt:: parse;
22
22
use std:: hashmap:: { HashMap , HashSet } ;
23
23
use std:: vec;
24
+ use std:: cell:: RefCell ;
24
25
25
26
#[ deriving( Eq ) ]
26
27
enum ArgumentType {
@@ -367,169 +368,179 @@ impl<'a> Context<'a> {
367
368
return ~[ unnamed, allow_dead_code] ;
368
369
}
369
370
370
- /// Translate a `parse::Piece` to a static `rt::Piece`
371
- fn trans_piece ( & mut self , piece : & parse:: Piece ) -> @ast:: Expr {
372
- let sp = self . fmtsp ;
373
- let parsepath = |s : & str | {
374
- ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
375
- self . ecx . ident_of ( "parse" ) , self . ecx . ident_of ( s) ]
376
- } ;
377
- let rtpath = |s : & str | {
378
- ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
379
- self . ecx . ident_of ( "rt" ) , self . ecx . ident_of ( s) ]
380
- } ;
381
- let ctpath = |s : & str | {
382
- ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
383
- self . ecx . ident_of ( "parse" ) , self . ecx . ident_of ( s) ]
384
- } ;
385
- let none = self . ecx . path_global ( sp, ~[
371
+ fn parsepath ( & self , s : & str ) -> ~[ ast:: Ident ] {
372
+ ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
373
+ self . ecx . ident_of ( "parse" ) , self . ecx . ident_of ( s) ]
374
+ }
375
+
376
+ fn rtpath ( & self , s : & str ) -> ~[ ast:: Ident ] {
377
+ ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
378
+ self . ecx . ident_of ( "rt" ) , self . ecx . ident_of ( s) ]
379
+ }
380
+
381
+ fn ctpath ( & self , s : & str ) -> ~[ ast:: Ident ] {
382
+ ~[ self . ecx . ident_of ( "std" ) , self . ecx . ident_of ( "fmt" ) ,
383
+ self . ecx . ident_of ( "parse" ) , self . ecx . ident_of ( s) ]
384
+ }
385
+
386
+ fn none ( & self ) -> @ast:: Expr {
387
+ let none = self . ecx . path_global ( self . fmtsp , ~[
386
388
self . ecx . ident_of ( "std" ) ,
387
389
self . ecx . ident_of ( "option" ) ,
388
390
self . ecx . ident_of ( "None" ) ] ) ;
389
- let none = self . ecx . expr_path ( none) ;
390
- let some = |e : @ast:: Expr | {
391
- let p = self . ecx . path_global ( sp, ~[
391
+ self . ecx . expr_path ( none)
392
+ }
393
+
394
+ fn some ( & self , e : @ast:: Expr ) -> @ast:: Expr {
395
+ let p = self . ecx . path_global ( self . fmtsp , ~[
392
396
self . ecx . ident_of ( "std" ) ,
393
397
self . ecx . ident_of ( "option" ) ,
394
398
self . ecx . ident_of ( "Some" ) ] ) ;
395
- let p = self . ecx . expr_path ( p) ;
396
- self . ecx . expr_call ( sp, p, ~[ e] )
397
- } ;
398
- let trans_count = |c : parse:: Count | {
399
- match c {
400
- parse:: CountIs ( i) => {
401
- self . ecx . expr_call_global ( sp, rtpath ( "CountIs" ) ,
402
- ~[ self . ecx . expr_uint ( sp, i) ] )
403
- }
404
- parse:: CountIsParam ( i) => {
405
- self . ecx . expr_call_global ( sp, rtpath ( "CountIsParam" ) ,
406
- ~[ self . ecx . expr_uint ( sp, i) ] )
407
- }
408
- parse:: CountImplied => {
409
- let path = self . ecx . path_global ( sp, rtpath ( "CountImplied" ) ) ;
410
- self . ecx . expr_path ( path)
411
- }
412
- parse:: CountIsNextParam => {
413
- let path = self . ecx . path_global ( sp, rtpath ( "CountIsNextParam" ) ) ;
414
- self . ecx . expr_path ( path)
415
- }
416
- parse:: CountIsName ( n) => {
417
- let i = match self . name_positions . find_equiv ( & n) {
418
- Some ( & i) => i,
419
- None => 0 , // error already emitted elsewhere
420
- } ;
421
- let i = i + self . args . len ( ) ;
422
- self . ecx . expr_call_global ( sp, rtpath ( "CountIsParam" ) ,
423
- ~[ self . ecx . expr_uint ( sp, i) ] )
424
- }
399
+ let p = self . ecx . expr_path ( p) ;
400
+ self . ecx . expr_call ( self . fmtsp , p, ~[ e] )
401
+ }
402
+
403
+ fn trans_count ( & self , c : parse:: Count ) -> @ast:: Expr {
404
+ let sp = self . fmtsp ;
405
+ match c {
406
+ parse:: CountIs ( i) => {
407
+ self . ecx . expr_call_global ( sp, self . rtpath ( "CountIs" ) ,
408
+ ~[ self . ecx . expr_uint ( sp, i) ] )
425
409
}
426
- } ;
427
- let trans_method = |method : & parse:: Method | {
428
- let method = match * method {
429
- parse:: Select ( ref arms, ref default) => {
430
- let arms = arms. iter ( ) . map ( |arm| {
431
- let p = self . ecx . path_global ( sp, rtpath ( "SelectArm" ) ) ;
410
+ parse:: CountIsParam ( i) => {
411
+ self . ecx . expr_call_global ( sp, self . rtpath ( "CountIsParam" ) ,
412
+ ~[ self . ecx . expr_uint ( sp, i) ] )
413
+ }
414
+ parse:: CountImplied => {
415
+ let path = self . ecx . path_global ( sp, self . rtpath ( "CountImplied" ) ) ;
416
+ self . ecx . expr_path ( path)
417
+ }
418
+ parse:: CountIsNextParam => {
419
+ let path = self . ecx . path_global ( sp, self . rtpath ( "CountIsNextParam" ) ) ;
420
+ self . ecx . expr_path ( path)
421
+ }
422
+ parse:: CountIsName ( n) => {
423
+ let i = match self . name_positions . find_equiv ( & n) {
424
+ Some ( & i) => i,
425
+ None => 0 , // error already emitted elsewhere
426
+ } ;
427
+ let i = i + self . args . len ( ) ;
428
+ self . ecx . expr_call_global ( sp, self . rtpath ( "CountIsParam" ) ,
429
+ ~[ self . ecx . expr_uint ( sp, i) ] )
430
+ }
431
+ }
432
+ }
433
+
434
+ fn trans_method ( & mut self , method : & parse:: Method ) -> @ast:: Expr {
435
+ let sp = self . fmtsp ;
436
+ let method = match * method {
437
+ parse:: Select ( ref arms, ref default) => {
438
+ let arms = arms. iter ( ) . map ( |arm| {
439
+ let p = self . ecx . path_global ( sp, self . rtpath ( "SelectArm" ) ) ;
432
440
let result = arm. result . iter ( ) . map ( |p| {
433
441
self . trans_piece ( p)
434
442
} ) . collect ( ) ;
435
443
let s = token:: intern_and_get_ident ( arm. selector ) ;
436
444
let selector = self . ecx . expr_str ( sp, s) ;
437
445
self . ecx . expr_struct ( sp, p, ~[
438
- self . ecx . field_imm ( sp,
439
- self . ecx . ident_of ( "selector" ) ,
440
- selector) ,
441
- self . ecx . field_imm ( sp, self . ecx . ident_of ( "result" ) ,
442
- self . ecx . expr_vec_slice ( sp, result) ) ,
443
- ] )
446
+ self . ecx . field_imm ( sp,
447
+ self . ecx . ident_of ( "selector" ) ,
448
+ selector) ,
449
+ self . ecx . field_imm ( sp, self . ecx . ident_of ( "result" ) ,
450
+ self . ecx . expr_vec_slice ( sp, result) ) ,
451
+ ] )
444
452
} ) . collect ( ) ;
445
- let default = default. iter ( ) . map ( |p| {
453
+ let default = default. iter ( ) . map ( |p| {
446
454
self . trans_piece ( p)
447
455
} ) . collect ( ) ;
448
- self . ecx . expr_call_global ( sp, rtpath ( "Select" ) , ~[
456
+ self . ecx . expr_call_global ( sp, self . rtpath ( "Select" ) , ~[
449
457
self . ecx . expr_vec_slice ( sp, arms) ,
450
458
self . ecx . expr_vec_slice ( sp, default) ,
451
- ] )
452
- }
453
- parse:: Plural ( offset, ref arms, ref default) => {
454
- let offset = match offset {
455
- Some ( i) => { some ( self . ecx . expr_uint ( sp, i) ) }
456
- None => { none . clone ( ) }
457
- } ;
458
- let arms = arms. iter ( ) . map ( |arm| {
459
- let p = self . ecx . path_global ( sp, rtpath ( "PluralArm" ) ) ;
459
+ ] )
460
+ }
461
+ parse:: Plural ( offset, ref arms, ref default) => {
462
+ let offset = match offset {
463
+ Some ( i) => { self . some ( self . ecx . expr_uint ( sp, i) ) }
464
+ None => { self . none ( ) }
465
+ } ;
466
+ let arms = arms. iter ( ) . map ( |arm| {
467
+ let p = self . ecx . path_global ( sp, self . rtpath ( "PluralArm" ) ) ;
460
468
let result = arm. result . iter ( ) . map ( |p| {
461
- self . trans_piece ( p)
462
- } ) . collect ( ) ;
469
+ self . trans_piece ( p)
470
+ } ) . collect ( ) ;
463
471
let ( lr, selarg) = match arm. selector {
464
472
parse:: Keyword ( t) => {
465
- let p = ctpath ( format ! ( "{:?}" , t) ) ;
473
+ let p = self . ctpath ( format ! ( "{:?}" , t) ) ;
466
474
let p = self . ecx . path_global ( sp, p) ;
467
- ( rtpath ( "Keyword" ) , self . ecx . expr_path ( p) )
475
+ ( self . rtpath ( "Keyword" ) , self . ecx . expr_path ( p) )
468
476
}
469
477
parse:: Literal ( i) => {
470
- ( rtpath ( "Literal" ) , self . ecx . expr_uint ( sp, i) )
478
+ ( self . rtpath ( "Literal" ) , self . ecx . expr_uint ( sp, i) )
471
479
}
472
480
} ;
473
481
let selector = self . ecx . expr_call_global ( sp,
474
- lr, ~[ selarg] ) ;
482
+ lr, ~[ selarg] ) ;
475
483
self . ecx . expr_struct ( sp, p, ~[
476
- self . ecx . field_imm ( sp,
477
- self . ecx . ident_of ( "selector" ) ,
478
- selector) ,
479
- self . ecx . field_imm ( sp, self . ecx . ident_of ( "result" ) ,
480
- self . ecx . expr_vec_slice ( sp, result) ) ,
481
- ] )
484
+ self . ecx . field_imm ( sp,
485
+ self . ecx . ident_of ( "selector" ) ,
486
+ selector) ,
487
+ self . ecx . field_imm ( sp, self . ecx . ident_of ( "result" ) ,
488
+ self . ecx . expr_vec_slice ( sp, result) ) ,
489
+ ] )
482
490
} ) . collect ( ) ;
483
- let default = default. iter ( ) . map ( |p| {
491
+ let default = default. iter ( ) . map ( |p| {
484
492
self . trans_piece ( p)
485
493
} ) . collect ( ) ;
486
- self . ecx . expr_call_global ( sp, rtpath ( "Plural" ) , ~[
494
+ self . ecx . expr_call_global ( sp, self . rtpath ( "Plural" ) , ~[
487
495
offset,
488
496
self . ecx . expr_vec_slice ( sp, arms) ,
489
497
self . ecx . expr_vec_slice ( sp, default) ,
490
- ] )
491
- }
492
- } ;
493
- let life = self . ecx . lifetime ( sp, self . ecx . ident_of ( "static" ) ) ;
494
- let ty = self . ecx . ty_path ( self . ecx . path_all (
498
+ ] )
499
+ }
500
+ } ;
501
+ let life = self . ecx . lifetime ( sp, self . ecx . ident_of ( "static" ) ) ;
502
+ let ty = self . ecx . ty_path ( self . ecx . path_all (
495
503
sp,
496
504
true ,
497
- rtpath ( "Method" ) ,
505
+ self . rtpath ( "Method" ) ,
498
506
opt_vec:: with ( life) ,
499
507
~[ ]
500
- ) , None ) ;
501
- let st = ast:: ItemStatic ( ty, ast:: MutImmutable , method) ;
502
- let static_name = self . ecx . ident_of ( format ! ( "__STATIC_METHOD_{}" ,
503
- self . method_statics. len( ) ) ) ;
504
- let item = self . ecx . item ( sp, static_name, self . static_attrs ( ) , st) ;
505
- self . method_statics . push ( item) ;
506
- self . ecx . expr_ident ( sp, static_name)
507
- } ;
508
+ ) , None ) ;
509
+ let st = ast:: ItemStatic ( ty, ast:: MutImmutable , method) ;
510
+ let static_name = self . ecx . ident_of ( format ! ( "__STATIC_METHOD_{}" ,
511
+ self . method_statics. len( ) ) ) ;
512
+ let item = self . ecx . item ( sp, static_name, self . static_attrs ( ) , st) ;
513
+ self . method_statics . push ( item) ;
514
+ self . ecx . expr_ident ( sp, static_name)
515
+ }
508
516
517
+ /// Translate a `parse::Piece` to a static `rt::Piece`
518
+ fn trans_piece ( & mut self , piece : & parse:: Piece ) -> @ast:: Expr {
519
+ let sp = self . fmtsp ;
509
520
match * piece {
510
521
parse:: String ( s) => {
511
522
let s = token:: intern_and_get_ident ( s) ;
512
523
self . ecx . expr_call_global ( sp,
513
- rtpath ( "String" ) ,
524
+ self . rtpath ( "String" ) ,
514
525
~[
515
526
self . ecx . expr_str ( sp, s)
516
527
] )
517
528
}
518
529
parse:: CurrentArgument => {
519
530
let nil = self . ecx . expr_lit ( sp, ast:: LitNil ) ;
520
- self . ecx . expr_call_global ( sp, rtpath ( "CurrentArgument" ) , ~[ nil] )
531
+ self . ecx . expr_call_global ( sp, self . rtpath ( "CurrentArgument" ) , ~[ nil] )
521
532
}
522
533
parse:: Argument ( ref arg) => {
523
534
// Translate the position
524
535
let pos = match arg. position {
525
536
// These two have a direct mapping
526
537
parse:: ArgumentNext => {
527
538
let path = self . ecx . path_global ( sp,
528
- rtpath ( "ArgumentNext" ) ) ;
539
+ self . rtpath ( "ArgumentNext" ) ) ;
529
540
self . ecx . expr_path ( path)
530
541
}
531
542
parse:: ArgumentIs ( i) => {
532
- self . ecx . expr_call_global ( sp, rtpath ( "ArgumentIs" ) ,
543
+ self . ecx . expr_call_global ( sp, self . rtpath ( "ArgumentIs" ) ,
533
544
~[ self . ecx . expr_uint ( sp, i) ] )
534
545
}
535
546
// Named arguments are converted to positional arguments at
@@ -540,7 +551,7 @@ impl<'a> Context<'a> {
540
551
None => 0 , // error already emitted elsewhere
541
552
} ;
542
553
let i = i + self . args . len ( ) ;
543
- self . ecx . expr_call_global ( sp, rtpath ( "ArgumentIs" ) ,
554
+ self . ecx . expr_call_global ( sp, self . rtpath ( "ArgumentIs" ) ,
544
555
~[ self . ecx . expr_uint ( sp, i) ] )
545
556
}
546
557
} ;
@@ -550,20 +561,20 @@ impl<'a> Context<'a> {
550
561
let fill = self . ecx . expr_lit ( sp, ast:: LitChar ( fill as u32 ) ) ;
551
562
let align = match arg. format . align {
552
563
parse:: AlignLeft => {
553
- self . ecx . path_global ( sp, parsepath ( "AlignLeft" ) )
564
+ self . ecx . path_global ( sp, self . parsepath ( "AlignLeft" ) )
554
565
}
555
566
parse:: AlignRight => {
556
- self . ecx . path_global ( sp, parsepath ( "AlignRight" ) )
567
+ self . ecx . path_global ( sp, self . parsepath ( "AlignRight" ) )
557
568
}
558
569
parse:: AlignUnknown => {
559
- self . ecx . path_global ( sp, parsepath ( "AlignUnknown" ) )
570
+ self . ecx . path_global ( sp, self . parsepath ( "AlignUnknown" ) )
560
571
}
561
572
} ;
562
573
let align = self . ecx . expr_path ( align) ;
563
574
let flags = self . ecx . expr_uint ( sp, arg. format . flags ) ;
564
- let prec = trans_count ( arg. format . precision ) ;
565
- let width = trans_count ( arg. format . width ) ;
566
- let path = self . ecx . path_global ( sp, rtpath ( "FormatSpec" ) ) ;
575
+ let prec = self . trans_count ( arg. format . precision ) ;
576
+ let width = self . trans_count ( arg. format . width ) ;
577
+ let path = self . ecx . path_global ( sp, self . rtpath ( "FormatSpec" ) ) ;
567
578
let fmt = self . ecx . expr_struct ( sp, path, ~[
568
579
self . ecx . field_imm ( sp, self . ecx . ident_of ( "fill" ) , fill) ,
569
580
self . ecx . field_imm ( sp, self . ecx . ident_of ( "align" ) , align) ,
@@ -574,19 +585,19 @@ impl<'a> Context<'a> {
574
585
575
586
// Translate the method (if any)
576
587
let method = match arg. method {
577
- None => { none . clone ( ) }
588
+ None => { self . none ( ) }
578
589
Some ( ref m) => {
579
- let m = trans_method ( * m) ;
580
- some ( self . ecx . expr_addr_of ( sp, m) )
590
+ let m = self . trans_method ( * m) ;
591
+ self . some ( self . ecx . expr_addr_of ( sp, m) )
581
592
}
582
593
} ;
583
- let path = self . ecx . path_global ( sp, rtpath ( "Argument" ) ) ;
594
+ let path = self . ecx . path_global ( sp, self . rtpath ( "Argument" ) ) ;
584
595
let s = self . ecx . expr_struct ( sp, path, ~[
585
596
self . ecx . field_imm ( sp, self . ecx . ident_of ( "position" ) , pos) ,
586
597
self . ecx . field_imm ( sp, self . ecx . ident_of ( "format" ) , fmt) ,
587
598
self . ecx . field_imm ( sp, self . ecx . ident_of ( "method" ) , method) ,
588
599
] ) ;
589
- self . ecx . expr_call_global ( sp, rtpath ( "Argument" ) , ~[ s] )
600
+ self . ecx . expr_call_global ( sp, self . rtpath ( "Argument" ) , ~[ s] )
590
601
}
591
602
}
592
603
}
0 commit comments