Commit b1197a15 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Make parse_decimal a more generic helper.

parent bb29a9bf
...@@ -406,14 +406,14 @@ literal_t *new_boolean_literal(parser_ctx_t *ctx, BOOL bval) ...@@ -406,14 +406,14 @@ literal_t *new_boolean_literal(parser_ctx_t *ctx, BOOL bval)
return ret; return ret;
} }
static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret) static HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
{ {
LONGLONG d, hlp; const WCHAR *ptr = *iter;
LONGLONG d = 0, hlp;
int exp = 0; int exp = 0;
d = int_part; while(ptr < end && isdigitW(*ptr)) {
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { hlp = d*10 + *(ptr++) - '0';
hlp = d*10 + *(ctx->ptr++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) { if(d>MAXLONGLONG/10 || hlp<0) {
exp++; exp++;
break; break;
...@@ -421,51 +421,48 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret) ...@@ -421,51 +421,48 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret)
else else
d = hlp; d = hlp;
} }
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { while(ptr < end && isdigitW(*ptr)) {
exp++; exp++;
ctx->ptr++; ptr++;
} }
if(*ctx->ptr == '.') { if(*ptr == '.') {
ctx->ptr++; ptr++;
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { while(ptr < end && isdigitW(*ptr)) {
hlp = d*10 + *(ctx->ptr++) - '0'; hlp = d*10 + *(ptr++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) if(d>MAXLONGLONG/10 || hlp<0)
break; break;
d = hlp; d = hlp;
exp--; exp--;
} }
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) while(ptr < end && isdigitW(*ptr))
ctx->ptr++; ptr++;
} }
if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) { if(ptr < end && (*ptr == 'e' || *ptr == 'E')) {
int sign = 1, e = 0; int sign = 1, e = 0;
ctx->ptr++; if(++ptr < end) {
if(ctx->ptr < ctx->end) { if(*ptr == '+') {
if(*ctx->ptr == '+') { ptr++;
ctx->ptr++; }else if(*ptr == '-') {
}else if(*ctx->ptr == '-') {
sign = -1; sign = -1;
ctx->ptr++; ptr++;
}else if(!isdigitW(*ctx->ptr)) { }else if(!isdigitW(*ptr)) {
WARN("Expected exponent part\n"); WARN("Expected exponent part\n");
lex_error(ctx, E_FAIL); return E_FAIL;
return FALSE;
} }
} }
if(ctx->ptr == ctx->end) { if(ptr == end) {
WARN("unexpected end of file\n"); WARN("unexpected end of file\n");
lex_error(ctx, E_FAIL); return E_FAIL;
return FALSE;
} }
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { while(ptr < end && isdigitW(*ptr)) {
if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0) if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
e = INT_MAX; e = INT_MAX;
} }
e *= sign; e *= sign;
...@@ -475,22 +472,25 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret) ...@@ -475,22 +472,25 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret)
else exp += e; else exp += e;
} }
if(is_identifier_char(*ctx->ptr)) { if(is_identifier_char(*ptr)) {
WARN("wrong char after zero\n"); WARN("wrong char after zero\n");
lex_error(ctx, JS_E_MISSING_SEMICOLON); return JS_E_MISSING_SEMICOLON;
return FALSE;
} }
*ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp); *ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
return TRUE; *iter = ptr;
return S_OK;
} }
static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret) static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
{ {
LONG l, d; HRESULT hres;
if(*ctx->ptr == '0') {
LONG d, l = 0;
ctx->ptr++;
l = *ctx->ptr++ - '0';
if(!l) {
if(*ctx->ptr == 'x' || *ctx->ptr == 'X') { if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
if(++ctx->ptr == ctx->end) { if(++ctx->ptr == ctx->end) {
ERR("unexpected end of file\n"); ERR("unexpected end of file\n");
...@@ -546,7 +546,13 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret) ...@@ -546,7 +546,13 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
} }
} }
return parse_double_literal(ctx, l, ret); hres = parse_decimal(&ctx->ptr, ctx->end, ret);
if(FAILED(hres)) {
lex_error(ctx, hres);
return FALSE;
}
return TRUE;
} }
static int next_token(parser_ctx_t *ctx, void *lval) static int next_token(parser_ctx_t *ctx, void *lval)
...@@ -599,8 +605,12 @@ static int next_token(parser_ctx_t *ctx, void *lval) ...@@ -599,8 +605,12 @@ static int next_token(parser_ctx_t *ctx, void *lval)
case '.': case '.':
if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
double n; double n;
if(!parse_double_literal(ctx, 0, &n)) HRESULT hres;
hres = parse_decimal(&ctx->ptr, ctx->end, &n);
if(FAILED(hres)) {
lex_error(ctx, hres);
return -1; return -1;
}
*(literal_t**)lval = new_double_literal(ctx, n); *(literal_t**)lval = new_double_literal(ctx, n);
return tNumericLiteral; return tNumericLiteral;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment