@@ -652,47 +652,68 @@ export function toUpper8(c: u32): u32 {
652652export function strtol < T > ( str : string , radix : i32 = 0 ) : T {
653653 var len = str . length ;
654654 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+ }
659662 }
660663
661664 var ptr = changetype < usize > ( str ) /* + HEAD -> offset */ ;
662665 var code = < u32 > load < u16 > ( ptr ) ;
663666
664- // determine sign
665- // @ts -ignore: cast
666- var sign : T = 1 ;
667667 // trim white spaces
668668 while ( isSpace ( code ) ) {
669669 code = < u32 > load < u16 > ( ptr += 2 ) ;
670670 -- len ;
671671 }
672- if ( code == CharCode . MINUS ) {
672+ // determine sign
673+ // @ts -ignore
674+ var sign : T = 1 ;
675+ if ( code == CharCode . MINUS || code == CharCode . PLUS ) {
673676 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+ }
678684 }
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 ;
688688 }
689689 code = < u32 > load < u16 > ( ptr += 2 ) ;
690690 }
691691
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
694715 if ( code == CharCode . _0 && len > 2 ) {
695- switch ( < u32 > load < u16 > ( ptr + 2 ) | 32 ) {
716+ switch ( < u32 > load < u16 > ( ptr , 2 ) | 32 ) {
696717 case CharCode . b : {
697718 ptr += 4 ; len -= 2 ;
698719 radix = 2 ;
@@ -708,14 +729,9 @@ export function strtol<T>(str: string, radix: i32 = 0): T {
708729 radix = 16 ;
709730 break ;
710731 }
711- default : radix = 10 ;
712732 }
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 ;
719735 }
720736
721737 // calculate value
@@ -729,8 +745,19 @@ export function strtol<T>(str: string, radix: i32 = 0): T {
729745 code -= CharCode . A - 10 ;
730746 } else if ( code - CharCode . a <= < u32 > ( CharCode . z - CharCode . a ) ) {
731747 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+ }
734761 // @ts -ignore: type
735762 num = num * radix + code ;
736763 ptr += 2 ;
@@ -746,7 +773,7 @@ export function strtod(str: string): f64 {
746773 var ptr = changetype < usize > ( str ) ;
747774 var code = < u32 > load < u16 > ( ptr ) ;
748775
749- var sign = 1. ;
776+ var sign = 1.0 ;
750777 // skip white spaces
751778 while ( len && isSpace ( code ) ) {
752779 code = < u32 > load < u16 > ( ptr += 2 ) ;
@@ -770,7 +797,7 @@ export function strtod(str: string): f64 {
770797 load < u64 > ( ptr , 0 ) == 0x690066006E0049 && // ifnI
771798 load < u64 > ( ptr , 8 ) == 0x7900740069006E // ytin
772799 ) {
773- return copysign < f64 > ( Infinity , sign ) ;
800+ return Infinity * sign ;
774801 }
775802 return NaN ;
776803 }
0 commit comments