jscript: Added string to number conversion implementation.
This commit is contained in:
parent
bf84d3bc2d
commit
91b798ddf8
|
@ -217,6 +217,110 @@ HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static int hex_to_int(WCHAR c)
|
||||
{
|
||||
if('0' <= c && c <= '9')
|
||||
return c-'0';
|
||||
|
||||
if('a' <= c && c <= 'f')
|
||||
return c-'a'+10;
|
||||
|
||||
if('A' <= c && c <= 'F')
|
||||
return c-'A'+10;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 9.3.1 */
|
||||
static HRESULT str_to_number(BSTR str, VARIANT *ret)
|
||||
{
|
||||
const WCHAR *ptr = str;
|
||||
BOOL neg = FALSE;
|
||||
DOUBLE d = 0.0;
|
||||
|
||||
static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};
|
||||
|
||||
while(isspaceW(*ptr))
|
||||
ptr++;
|
||||
|
||||
if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) {
|
||||
ptr += sizeof(infinityW)/sizeof(WCHAR);
|
||||
while(*ptr && isspaceW(*ptr))
|
||||
ptr++;
|
||||
|
||||
if(*ptr) {
|
||||
FIXME("NaN\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
FIXME("inf\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(*ptr == '-') {
|
||||
neg = TRUE;
|
||||
ptr++;
|
||||
}else if(*ptr == '+') {
|
||||
ptr++;
|
||||
}else if(*ptr == '0' && ptr[1] == 'x') {
|
||||
DWORD l = 0;
|
||||
|
||||
ptr += 2;
|
||||
while((l = hex_to_int(*ptr)) != -1) {
|
||||
d = d*16 + l;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
num_set_val(ret, d);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
while(isdigitW(*ptr))
|
||||
d = d*10 + (*ptr++ - '0');
|
||||
|
||||
if(*ptr == 'e' || *ptr == 'E') {
|
||||
BOOL eneg = FALSE;
|
||||
LONG l = 0;
|
||||
|
||||
ptr++;
|
||||
if(*ptr == '-') {
|
||||
ptr++;
|
||||
eneg = TRUE;
|
||||
}else if(*ptr == '+') {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
while(isdigitW(*ptr))
|
||||
l = l*10 + (*ptr++ - '0');
|
||||
if(eneg)
|
||||
l = -l;
|
||||
|
||||
d *= pow(10, l);
|
||||
}else if(*ptr == '.') {
|
||||
DOUBLE dec = 0.1;
|
||||
|
||||
ptr++;
|
||||
while(isdigitW(*ptr)) {
|
||||
d += dec * (*ptr++ - '0');
|
||||
dec *= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
while(isspaceW(*ptr))
|
||||
ptr++;
|
||||
|
||||
if(*ptr) {
|
||||
FIXME("NaN\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(neg)
|
||||
d = -d;
|
||||
|
||||
num_set_val(ret, d);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 9.3 */
|
||||
HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
||||
{
|
||||
|
@ -229,6 +333,8 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
|||
case VT_R8:
|
||||
*ret = *v;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
return str_to_number(V_BSTR(v), ret);
|
||||
case VT_BOOL:
|
||||
V_VT(ret) = VT_I4;
|
||||
V_I4(ret) = V_BOOL(v) ? 1 : 0;
|
||||
|
|
|
@ -387,7 +387,7 @@ static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **li
|
|||
e = e*10 + *ctx->ptr++ - '0';
|
||||
e *= sign;
|
||||
|
||||
d = pow(d, e);
|
||||
d *= pow(10, e);
|
||||
}
|
||||
|
||||
*literal = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
|
|
@ -344,6 +344,11 @@ ok(+3 === 3, "+3 !== 3");
|
|||
ok(+true === 1, "+true !== 1");
|
||||
ok(+false === 0, "+false !== 0");
|
||||
ok(+null === 0, "+null !== 0");
|
||||
ok(+"0" === 0, "+'0' !== 0");
|
||||
ok(+"3" === 3, "+'3' !== 3");
|
||||
ok(+"-3" === -3, "+'-3' !== -3");
|
||||
ok(+"0xff" === 255, "+'0xff' !== 255");
|
||||
ok(+"3e3" === 3000, "+'3e3' !== 3000");
|
||||
|
||||
ok("" + 0 === "0", "\"\" + 0 !== \"0\"");
|
||||
ok("" + 123 === "123", "\"\" + 123 !== \"123\"");
|
||||
|
|
Loading…
Reference in New Issue