@@ -52,7 +52,7 @@ impure fn new_reader(io.reader rdr, str filename, codemap.filemap filemap)
52
52
if ( pos < len) { ret _str. char_at ( file, pos) ; }
53
53
else { ret -1 as char ; }
54
54
}
55
-
55
+
56
56
impure fn init ( ) {
57
57
if ( pos < len) {
58
58
auto next = _str. char_range_at ( file, pos) ;
@@ -368,7 +368,7 @@ impure fn scan_exponent(reader rdr) -> option.t[str] {
368
368
}
369
369
370
370
impure fn scan_dec_digits ( reader rdr) -> str {
371
-
371
+
372
372
auto c = rdr. curr ( ) ;
373
373
let str res = "" ;
374
374
@@ -417,11 +417,11 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
417
417
dec_str = scan_dec_digits ( rdr) ;
418
418
is_dec_integer = true ;
419
419
}
420
-
420
+
421
421
if ( is_dec_integer) {
422
422
accum_int = digits_to_string ( dec_str) ;
423
423
}
424
-
424
+
425
425
c = rdr. curr ( ) ;
426
426
n = rdr. next ( ) ;
427
427
@@ -526,6 +526,44 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
526
526
}
527
527
}
528
528
529
+ impure fn scan_numeric_escape ( reader rdr) -> char {
530
+
531
+ auto n_hex_digits = 0 ;
532
+
533
+ check ( rdr. curr ( ) == '\\' ) ;
534
+
535
+ alt ( rdr. next ( ) ) {
536
+ case ( 'x' ) { n_hex_digits = 2 ; }
537
+ case ( 'u' ) { n_hex_digits = 4 ; }
538
+ case ( 'U' ) { n_hex_digits = 8 ; }
539
+ case ( ?c) {
540
+ log "unknown numeric character escape" ;
541
+ log c;
542
+ fail;
543
+ }
544
+ }
545
+
546
+ rdr. bump ( ) ; // advance curr past \
547
+
548
+ auto n = rdr. next ( ) ;
549
+ auto accum_int = 0 ;
550
+
551
+ while ( n_hex_digits != 0 ) {
552
+ if ( !is_hex_digit ( n) ) {
553
+ log "illegal numeric character escape" ;
554
+ log n;
555
+ fail;
556
+ }
557
+ accum_int *= 16 ;
558
+ accum_int += hex_digit_val ( n) ;
559
+ rdr. bump ( ) ;
560
+ n = rdr. next ( ) ;
561
+ n_hex_digits -= 1 ;
562
+ }
563
+ ret accum_int as char ;
564
+ }
565
+
566
+
529
567
impure fn next_token ( reader rdr) -> token . token {
530
568
auto accum_str = "" ;
531
569
@@ -666,26 +704,31 @@ impure fn next_token(reader rdr) -> token.token {
666
704
auto c2 = rdr. curr ( ) ;
667
705
if ( c2 == '\\' ) {
668
706
alt ( rdr. next ( ) ) {
669
- case ( 'n' ) { rdr. bump ( ) ; c2 = '\n' ; }
670
- case ( 'r' ) { rdr. bump ( ) ; c2 = '\r' ; }
671
- case ( 't' ) { rdr. bump ( ) ; c2 = '\t' ; }
672
- case ( '\\' ) { rdr. bump ( ) ; c2 = '\\' ; }
673
- case ( '\'' ) { rdr. bump ( ) ; c2 = '\'' ; }
674
- // FIXME: unicode numeric escapes.
707
+ case ( 'n' ) { c2 = '\n' ; }
708
+ case ( 'r' ) { c2 = '\r' ; }
709
+ case ( 't' ) { c2 = '\t' ; }
710
+ case ( '\\' ) { c2 = '\\' ; }
711
+ case ( '\'' ) { c2 = '\'' ; }
712
+
713
+ case ( 'x' ) { c2 = scan_numeric_escape ( rdr) ; }
714
+ case ( 'u' ) { c2 = scan_numeric_escape ( rdr) ; }
715
+ case ( 'U' ) { c2 = scan_numeric_escape ( rdr) ; }
716
+
675
717
case ( ?c2) {
676
718
log "unknown character escape" ;
677
719
log c2;
678
720
fail;
679
721
}
680
722
}
723
+ rdr. bump ( ) ;
681
724
}
682
725
683
726
if ( rdr. next ( ) != '\'' ) {
684
727
log "unterminated character constant" ;
685
728
fail;
686
729
}
687
- rdr. bump ( ) ;
688
- rdr. bump ( ) ;
730
+ rdr. bump ( ) ; // advance curr to closing '
731
+ rdr. bump ( ) ; // advance curr past token
689
732
ret token. LIT_CHAR ( c2) ;
690
733
}
691
734
@@ -715,7 +758,22 @@ impure fn next_token(reader rdr) -> token.token {
715
758
rdr. bump ( ) ;
716
759
_str. push_byte ( accum_str, '"' as u8 ) ;
717
760
}
718
- // FIXME: unicode numeric escapes.
761
+
762
+ case ( 'x' ) {
763
+ _str. push_char ( accum_str,
764
+ scan_numeric_escape ( rdr) ) ;
765
+ }
766
+
767
+ case ( 'u' ) {
768
+ _str. push_char ( accum_str,
769
+ scan_numeric_escape ( rdr) ) ;
770
+ }
771
+
772
+ case ( 'U' ) {
773
+ _str. push_char ( accum_str,
774
+ scan_numeric_escape ( rdr) ) ;
775
+ }
776
+
719
777
case ( ?c2) {
720
778
log "unknown string escape" ;
721
779
log c2;
@@ -782,6 +840,12 @@ impure fn next_token(reader rdr) -> token.token {
782
840
case ( '%' ) {
783
841
ret binop ( rdr, token. PERCENT ) ;
784
842
}
843
+
844
+ case ( ?c) {
845
+ log "unkown start of token" ;
846
+ log c;
847
+ fail;
848
+ }
785
849
}
786
850
787
851
fail;
0 commit comments