jscript: Make parse_decimal a more generic helper.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bb29a9bf5b
commit
b1197a15ec
|
@ -406,14 +406,14 @@ literal_t *new_boolean_literal(parser_ctx_t *ctx, BOOL bval)
|
|||
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;
|
||||
|
||||
d = int_part;
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
while(ptr < end && isdigitW(*ptr)) {
|
||||
hlp = d*10 + *(ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0) {
|
||||
exp++;
|
||||
break;
|
||||
|
@ -421,51 +421,48 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret)
|
|||
else
|
||||
d = hlp;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
while(ptr < end && isdigitW(*ptr)) {
|
||||
exp++;
|
||||
ctx->ptr++;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(*ctx->ptr == '.') {
|
||||
ctx->ptr++;
|
||||
if(*ptr == '.') {
|
||||
ptr++;
|
||||
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
while(ptr < end && isdigitW(*ptr)) {
|
||||
hlp = d*10 + *(ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0)
|
||||
break;
|
||||
|
||||
d = hlp;
|
||||
exp--;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
while(ptr < end && isdigitW(*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;
|
||||
|
||||
ctx->ptr++;
|
||||
if(ctx->ptr < ctx->end) {
|
||||
if(*ctx->ptr == '+') {
|
||||
ctx->ptr++;
|
||||
}else if(*ctx->ptr == '-') {
|
||||
if(++ptr < end) {
|
||||
if(*ptr == '+') {
|
||||
ptr++;
|
||||
}else if(*ptr == '-') {
|
||||
sign = -1;
|
||||
ctx->ptr++;
|
||||
}else if(!isdigitW(*ctx->ptr)) {
|
||||
ptr++;
|
||||
}else if(!isdigitW(*ptr)) {
|
||||
WARN("Expected exponent part\n");
|
||||
lex_error(ctx, E_FAIL);
|
||||
return FALSE;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->ptr == ctx->end) {
|
||||
if(ptr == end) {
|
||||
WARN("unexpected end of file\n");
|
||||
lex_error(ctx, E_FAIL);
|
||||
return FALSE;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
|
||||
while(ptr < end && isdigitW(*ptr)) {
|
||||
if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
|
||||
e = INT_MAX;
|
||||
}
|
||||
e *= sign;
|
||||
|
@ -475,22 +472,25 @@ static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret)
|
|||
else exp += e;
|
||||
}
|
||||
|
||||
if(is_identifier_char(*ctx->ptr)) {
|
||||
if(is_identifier_char(*ptr)) {
|
||||
WARN("wrong char after zero\n");
|
||||
lex_error(ctx, JS_E_MISSING_SEMICOLON);
|
||||
return FALSE;
|
||||
return JS_E_MISSING_SEMICOLON;
|
||||
}
|
||||
|
||||
*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)
|
||||
{
|
||||
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 == ctx->end) {
|
||||
ERR("unexpected end of file\n");
|
||||
|
@ -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)
|
||||
|
@ -599,8 +605,12 @@ static int next_token(parser_ctx_t *ctx, void *lval)
|
|||
case '.':
|
||||
if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
|
||||
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;
|
||||
}
|
||||
*(literal_t**)lval = new_double_literal(ctx, n);
|
||||
return tNumericLiteral;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue