@@ -652,47 +652,68 @@ export function toUpper8(c: u32): u32 {
652
652
export function strtol < T > ( str : string , radix : i32 = 0 ) : T {
653
653
var len = str . length ;
654
654
if ( ! len ) {
655
- // @ts -ignore: cast
656
- if ( isFloat < T > ( ) ) return < T > NaN ;
657
- // @ts -ignore: cast
658
- return < T > 0 ;
655
+ if ( isFloat < T > ( ) ) {
656
+ // @ts -ignore: cast
657
+ return < T > NaN ;
658
+ } else {
659
+ // @ts -ignore: cast
660
+ return < T > 0 ;
661
+ }
659
662
}
660
663
661
664
var ptr = changetype < usize > ( str ) /* + HEAD -> offset */ ;
662
665
var code = < u32 > load < u16 > ( ptr ) ;
663
666
664
- // determine sign
665
- // @ts -ignore: cast
666
- var sign : T = 1 ;
667
667
// trim white spaces
668
668
while ( isSpace ( code ) ) {
669
669
code = < u32 > load < u16 > ( ptr += 2 ) ;
670
670
-- len ;
671
671
}
672
- if ( code == CharCode . MINUS ) {
672
+ // determine sign
673
+ // @ts -ignore
674
+ var sign : T = 1 ;
675
+ if ( code == CharCode . MINUS || code == CharCode . PLUS ) {
673
676
if ( ! -- len ) {
674
- // @ts -ignore: cast
675
- if ( isFloat < T > ( ) ) return < T > NaN ;
676
- // @ts -ignore: cast
677
- return < T > 0 ;
677
+ if ( isFloat < T > ( ) ) {
678
+ // @ts -ignore: cast
679
+ return < T > NaN ;
680
+ } else {
681
+ // @ts -ignore: cast
682
+ return < T > 0 ;
683
+ }
678
684
}
679
- code = < u32 > load < u16 > ( ptr += 2 ) ;
680
- // @ts -ignore: type
681
- sign = - 1 ;
682
- } else if ( code == CharCode . PLUS ) {
683
- if ( ! -- len ) {
684
- // @ts -ignore: cast
685
- if ( isFloat < T > ( ) ) return < T > NaN ;
686
- // @ts -ignore: cast
687
- return < T > 0 ;
685
+ if ( code == CharCode . MINUS ) {
686
+ // @ts -ignore: type
687
+ sign = - 1 ;
688
688
}
689
689
code = < u32 > load < u16 > ( ptr += 2 ) ;
690
690
}
691
691
692
- // determine radix
693
- if ( ! radix ) {
692
+ // See https://tc39.es/ecma262/#sec-parseint-string-radix
693
+ if ( radix ) {
694
+ if ( radix < 2 || radix > 36 ) {
695
+ if ( isFloat < T > ( ) ) {
696
+ // @ts -ignore: cast
697
+ return < T > NaN ;
698
+ } else {
699
+ // @ts -ignore: cast
700
+ return < T > 0 ;
701
+ }
702
+ }
703
+ // handle case as parseInt("0xFF", 16) by spec
704
+ if ( radix == 16 ) {
705
+ if (
706
+ len > 2 &&
707
+ code == CharCode . _0 &&
708
+ ( < u32 > load < u16 > ( ptr , 2 ) | 32 ) == CharCode . x
709
+ ) {
710
+ ptr += 4 ; len -= 2 ;
711
+ }
712
+ }
713
+ } else {
714
+ // determine radix by literal prefix
694
715
if ( code == CharCode . _0 && len > 2 ) {
695
- switch ( < u32 > load < u16 > ( ptr + 2 ) | 32 ) {
716
+ switch ( < u32 > load < u16 > ( ptr , 2 ) | 32 ) {
696
717
case CharCode . b : {
697
718
ptr += 4 ; len -= 2 ;
698
719
radix = 2 ;
@@ -708,14 +729,9 @@ export function strtol<T>(str: string, radix: i32 = 0): T {
708
729
radix = 16 ;
709
730
break ;
710
731
}
711
- default : radix = 10 ;
712
732
}
713
- } else radix = 10 ;
714
- } else if ( radix < 2 || radix > 36 ) {
715
- // @ts -ignore: cast
716
- if ( isFloat < T > ( ) ) return < T > NaN ;
717
- // @ts -ignore: cast
718
- return < T > 0 ;
733
+ }
734
+ if ( ! radix ) radix = 10 ;
719
735
}
720
736
721
737
// calculate value
@@ -729,8 +745,19 @@ export function strtol<T>(str: string, radix: i32 = 0): T {
729
745
code -= CharCode . A - 10 ;
730
746
} else if ( code - CharCode . a <= < u32 > ( CharCode . z - CharCode . a ) ) {
731
747
code -= CharCode . a - 10 ;
732
- } else break ;
733
- if ( code >= < u32 > radix ) break ;
748
+ }
749
+ if ( code >= < u32 > radix ) {
750
+ if ( ! num ) {
751
+ if ( isFloat < T > ( ) ) {
752
+ // @ts -ignore: cast
753
+ return < T > NaN ;
754
+ } else {
755
+ // @ts -ignore: cast
756
+ return < T > 0 ;
757
+ }
758
+ }
759
+ break ;
760
+ }
734
761
// @ts -ignore: type
735
762
num = num * radix + code ;
736
763
ptr += 2 ;
@@ -746,7 +773,7 @@ export function strtod(str: string): f64 {
746
773
var ptr = changetype < usize > ( str ) ;
747
774
var code = < u32 > load < u16 > ( ptr ) ;
748
775
749
- var sign = 1. ;
776
+ var sign = 1.0 ;
750
777
// skip white spaces
751
778
while ( len && isSpace ( code ) ) {
752
779
code = < u32 > load < u16 > ( ptr += 2 ) ;
@@ -770,7 +797,7 @@ export function strtod(str: string): f64 {
770
797
load < u64 > ( ptr , 0 ) == 0x690066006E0049 && // ifnI
771
798
load < u64 > ( ptr , 8 ) == 0x7900740069006E // ytin
772
799
) {
773
- return copysign < f64 > ( Infinity , sign ) ;
800
+ return Infinity * sign ;
774
801
}
775
802
return NaN ;
776
803
}
0 commit comments