diff --git a/jsbuiltin.c b/jsbuiltin.c index 8738ddd..1b99b51 100644 --- a/jsbuiltin.c +++ b/jsbuiltin.c @@ -43,15 +43,43 @@ static void jsB_parseInt(js_State *J, unsigned int argc) { const char *s = js_tostring(J, 1); double radix = js_isdefined(J, 2) ? js_tonumber(J, 2) : 10; + char *e; + double n; + while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s; - js_pushnumber(J, strtol(s, NULL, radix == 0 ? 10 : radix)); + if (radix == 0) + radix = 10; + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + s += 2; + radix = 16; + } + n = strtol(s, &e, radix); + if (s == e) + js_pushnumber(J, NAN); + else + js_pushnumber(J, n); } static void jsB_parseFloat(js_State *J, unsigned int argc) { const char *s = js_tostring(J, 1); + char *e; + double n; + while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s; - js_pushnumber(J, strtod(s, NULL)); + if (!strncmp(s, "Infinity", 8)) + js_pushnumber(J, INFINITY); + else if (!strncmp(s, "+Infinity", 9)) + js_pushnumber(J, INFINITY); + else if (!strncmp(s, "-Infinity", 9)) + js_pushnumber(J, -INFINITY); + else { + n = js_strtod(s, &e); + if (e == s) + js_pushnumber(J, NAN); + else + js_pushnumber(J, n); + } } static void jsB_isNaN(js_State *J, unsigned int argc) diff --git a/jsvalue.c b/jsvalue.c index 8ee2600..06de3b8 100644 --- a/jsvalue.c +++ b/jsvalue.c @@ -110,6 +110,29 @@ int jsV_toboolean(js_State *J, const js_Value *v) } } +double js_strtod(const char *s, char **ep) +{ + char *end; + double n; + const char *e = s; + while (*e == '+' || *e == '-') ++e; + while (*e >= '0' && *e <= '9') ++e; + if (*e == '.') ++e; + while (*e >= '0' && *e <= '9') ++e; + if (*e == 'e' || *e == 'E') { + ++e; + while (*e == '+' || *e == '-') ++e; + while (*e >= '0' && *e <= '9') ++e; + } + n = strtod(s, &end); + if (end == e) { + *ep = (char*)e; + return n; + } + *ep = (char*)s; + return 0; +} + /* ToNumber() on a string */ double jsV_stringtonumber(js_State *J, const char *s) { @@ -118,8 +141,14 @@ double jsV_stringtonumber(js_State *J, const char *s) while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s; if (s[0] == '0' && s[1] == 'x' && s[2] != 0) n = strtol(s + 2, &e, 16); + else if (!strncmp(s, "Infinity", 8)) + n = INFINITY, e = (char*)s + 8; + else if (!strncmp(s, "+Infinity", 9)) + n = INFINITY, e = (char*)s + 9; + else if (!strncmp(s, "-Infinity", 9)) + n = -INFINITY, e = (char*)s + 9; else - n = strtod(s, &e); + n = js_strtod(s, &e); while (jsY_iswhite(*e) || jsY_isnewline(*e)) ++e; if (*e) return NAN; return n; diff --git a/jsvalue.h b/jsvalue.h index 8cff991..2461d9e 100644 --- a/jsvalue.h +++ b/jsvalue.h @@ -123,6 +123,7 @@ const char *jsV_tostring(js_State *J, const js_Value *v); js_Object *jsV_toobject(js_State *J, const js_Value *v); js_Value jsV_toprimitive(js_State *J, const js_Value *v, int preferred); +double js_strtod(const char *s, char **ep); double jsV_numbertointeger(double n); int jsV_numbertoint32(double n); unsigned int jsV_numbertouint32(double n);