Jacek Caban : jscript: Added string to number conversion implementation.
Alexandre Julliard
julliard at winehq.org
Mon Sep 22 07:03:59 CDT 2008
Module: wine
Branch: master
Commit: 91b798ddf802bb9d7e812d84df308a324f555652
URL: http://source.winehq.org/git/wine.git/?a=commit;h=91b798ddf802bb9d7e812d84df308a324f555652
Author: Jacek Caban <jacek at codeweavers.com>
Date: Sun Sep 21 19:47:31 2008 +0200
jscript: Added string to number conversion implementation.
---
dlls/jscript/jsutils.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
dlls/jscript/lex.c | 2 +-
dlls/jscript/tests/lang.js | 5 ++
3 files changed, 112 insertions(+), 1 deletions(-)
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index f368c3e..6c0707d 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -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;
diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index ed73202..ba80154 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -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));
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 83732a2..484d192 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -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\"");
More information about the wine-cvs
mailing list