Fun fact: Can even implement parseInt/I32/I64 using generics, see #19

This commit is contained in:
dcodeIO
2018-01-30 06:05:35 +01:00
parent ab5a938ea0
commit 3924aa96ae
12 changed files with 95 additions and 248 deletions

2
std/assembly.d.ts vendored
View File

@ -193,6 +193,8 @@ declare function isFinite<T = f32 | f64>(value: T): bool;
declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`?
/** Parses an integer string to a 64-bit float. */
declare function parseInt(str: string, radix?: i32): f64;
/** Parses an integer string to a 32-bit integer. */
declare function parseI32(str: string, radix?: i32): i32;
/** Parses an integer string to a 64-bit integer. */
declare function parseI64(str: string, radix?: i32): i64;
/** Parses a string to a 64-bit float. */

View File

@ -351,45 +351,34 @@ const enum CharCode {
}
export function parseInt(str: String, radix: i32 = 0): f64 {
var len: i32 = str.length;
if (!len)
return NaN;
var ptr = changetype<usize>(str) /* + HEAD -> offset */;
var code = <i32>load<u16>(ptr, HEAD);
return parse<f64>(str, radix);
}
// pre-check sign
if (code == CharCode.MINUS) {
if (!--len)
return NaN;
} else if (code == CharCode.PLUS) {
if (!--len)
return NaN;
}
// pre-check radix
if (radix && (radix < 2 || radix > 36))
return NaN;
return <f64>parseI64(str, radix);
export function parseI32(str: String, radix: i32 = 0): i32 {
return parse<i32>(str, radix);
}
export function parseI64(str: String, radix: i32 = 0): i64 {
return parse<i64>(str, radix);
}
function parse<T>(str: String, radix: i32 = 0): T {
var len: i32 = str.length;
if (!len)
return 0; // (NaN)
return <T>NaN;
var ptr = changetype<usize>(str) /* + HEAD -> offset */;
var code = <i32>load<u16>(ptr, HEAD);
// determine sign
var sign: i64;
var sign: T;
if (code == CharCode.MINUS) {
if (!--len)
return 0; // (NaN)
return <T>NaN;
code = <i32>load<u16>(ptr += 2, HEAD);
sign = -1;
} else if (code == CharCode.PLUS) {
if (!--len)
return 0; // (NaN)
return <T>NaN;
code = <i32>load<u16>(ptr += 2, HEAD);
sign = 1;
} else
@ -423,10 +412,10 @@ export function parseI64(str: String, radix: i32 = 0): i64 {
}
} else radix = 10;
} else if (radix < 2 || radix > 36)
return 0; // (NaN)
return <T>NaN;
// calculate value
var num: i64 = 0;
var num: T = 0;
while (len--) {
code = <i32>load<u16>(ptr, HEAD);
if (code >= CharCode._0 && code <= CharCode._9)

2
std/portable.d.ts vendored
View File

@ -135,6 +135,8 @@ declare function changetype<T>(value: any): T;
declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`?
/** Parses an integer string to a 64-bit float. */
declare function parseInt(str: string, radix?: i32): f64;
/** Parses an integer string to a 32-bit integer. */
declare function parseI32(str: string, radix?: i32): i32;
/** Parses a floating point string to a 64-bit float. */
declare function parseFloat(str: string): f64;

View File

@ -98,3 +98,7 @@ globalScope["changetype"] = function changetype(value) { return value; }
String["fromCharCodes"] = function fromCharCodes(arr) { return String.fromCharCode.apply(String, arr); }
String["fromCodePoints"] = function fromCodePoints(arr) { return String.fromCodePoint.apply(String, arr); }
globalScope["parseI32"] = function parseI32(str, radix) {
return parseInt(str) | 0;
};