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

vbscript: Added support for exponential form of numeric literals.

parent 9e4803dd
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "wine/port.h" #include "wine/port.h"
#include <assert.h> #include <assert.h>
#include <limits.h>
#include "vbscript.h" #include "vbscript.h"
#include "parse.h" #include "parse.h"
...@@ -261,8 +262,10 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret) ...@@ -261,8 +262,10 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
static int parse_numeric_literal(parser_ctx_t *ctx, void **ret) static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
{ {
BOOL use_int = TRUE;
LONGLONG d = 0, hlp; LONGLONG d = 0, hlp;
int exp = 0; int exp = 0;
double r;
if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.') if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.')
return *ctx->ptr++; return *ctx->ptr++;
...@@ -281,13 +284,8 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret) ...@@ -281,13 +284,8 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
ctx->ptr++; ctx->ptr++;
} }
if(*ctx->ptr != '.') { if(*ctx->ptr == '.') {
if(!exp && (LONG)d == d) { use_int = FALSE;
LONG l = d;
*(LONG*)ret = l;
return (short)l == l ? tShort : tLong;
}
}else {
ctx->ptr++; ctx->ptr++;
while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
...@@ -302,7 +300,53 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret) ...@@ -302,7 +300,53 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
ctx->ptr++; ctx->ptr++;
} }
*(double*)ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp); if(*ctx->ptr == 'e' || *ctx->ptr == 'E') {
int e = 0, sign = 1;
if(*++ctx->ptr == '-') {
ctx->ptr++;
sign = -1;
}
if(!isdigitW(*ctx->ptr)) {
FIXME("Invalid numeric literal\n");
return 0;
}
use_int = FALSE;
do {
e = e*10 + *(ctx->ptr++) - '0';
if(sign == -1 && -e+exp < -(INT_MAX/100)) {
/* The literal will be rounded to 0 anyway. */
while(isdigitW(*ctx->ptr))
ctx->ptr++;
*(double*)ret = 0;
return tDouble;
}
if(sign*e + exp > INT_MAX/100) {
FIXME("Invalid numeric literal\n");
return 0;
}
} while(isdigitW(*ctx->ptr));
exp += sign*e;
}
if(use_int && (LONG)d == d) {
LONG l = d;
*(LONG*)ret = l;
return (short)l == l ? tShort : tLong;
}
r = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
if(isinf(r)) {
FIXME("Invalid numeric literal\n");
return 0;
}
*(double*)ret = r;
return tDouble; return tDouble;
} }
......
...@@ -40,6 +40,12 @@ Call ok(010 = 10, "010 <> 10") ...@@ -40,6 +40,12 @@ Call ok(010 = 10, "010 <> 10")
Call ok(10. = 10, "10. <> 10") Call ok(10. = 10, "10. <> 10")
Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1") Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1")
Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1") Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1")
Call ok(34e5 = 3400000, "34e5 <> 3400000")
Call ok(56.789e5 = 5678900, "56.789e5 = 5678900")
Call ok(56.789e-2 = 0.56789, "56.789e-2 <> 0.56789")
Call ok(1e-94938484 = 0, "1e-... <> 0")
Call ok(34e0 = 34, "34e0 <> 34")
Call ok(34E1 = 340, "34E0 <> 340")
Call ok(--1 = 1, "--1 = " & --1) Call ok(--1 = 1, "--1 = " & --1)
Call ok(-empty = 0, "-empty = " & (-empty)) Call ok(-empty = 0, "-empty = " & (-empty))
Call ok(true = -1, "! true = -1") Call ok(true = -1, "! true = -1")
...@@ -78,6 +84,9 @@ Call ok(getVT(&h10&) = "VT_I2", "getVT(&h10&) is not VT_I2") ...@@ -78,6 +84,9 @@ Call ok(getVT(&h10&) = "VT_I2", "getVT(&h10&) is not VT_I2")
Call ok(getVT(&h10000&) = "VT_I4", "getVT(&h10000&) is not VT_I4") Call ok(getVT(&h10000&) = "VT_I4", "getVT(&h10000&) is not VT_I4")
Call ok(getVT(&H10000&) = "VT_I4", "getVT(&H10000&) is not VT_I4") Call ok(getVT(&H10000&) = "VT_I4", "getVT(&H10000&) is not VT_I4")
Call ok(getVT(&hffFFffFF&) = "VT_I2", "getVT(&hffFFffFF&) is not VT_I2") Call ok(getVT(&hffFFffFF&) = "VT_I2", "getVT(&hffFFffFF&) is not VT_I2")
Call ok(getVT(1e2) = "VT_R8", "getVT(1e2) is not VT_R8")
Call ok(getVT(1e0) = "VT_R8", "getVT(1e0) is not VT_R8")
Call ok(getVT(0.1e2) = "VT_R8", "getVT(0.1e2) is not VT_R8")
Call ok(getVT(1 & 100000) = "VT_BSTR", "getVT(1 & 100000) is not VT_BSTR") Call ok(getVT(1 & 100000) = "VT_BSTR", "getVT(1 & 100000) is not VT_BSTR")
Call ok(getVT(-empty) = "VT_I2", "getVT(-empty) = " & getVT(-empty)) Call ok(getVT(-empty) = "VT_I2", "getVT(-empty) = " & getVT(-empty))
Call ok(getVT(-null) = "VT_NULL", "getVT(-null) = " & getVT(-null)) Call ok(getVT(-null) = "VT_NULL", "getVT(-null) = " & getVT(-null))
......
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