diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index ddafee9b188..394a24d6eaa 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -267,6 +267,35 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret) return tDouble; } +static int hex_to_int(WCHAR c) +{ + if('0' <= c && c <= '9') + return c-'0'; + if('a' <= c && c <= 'f') + return c+10-'a'; + if('A' <= c && c <= 'F') + return c+10-'A'; + return -1; +} + +static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret) +{ + const WCHAR *begin = ctx->ptr; + LONG l = 0, d; + + while((d = hex_to_int(*++ctx->ptr)) != -1) + l = l*16 + d; + + if(begin + 9 /* max digits+1 */ < ctx->ptr || *ctx->ptr != '&') { + FIXME("invalid literal\n"); + return 0; + } + + ctx->ptr++; + *ret = l; + return (short)l == l ? tShort : tLong; +} + static void skip_spaces(parser_ctx_t *ctx) { while(*ctx->ptr == ' ' || *ctx->ptr == '\t' || *ctx->ptr == '\r') @@ -329,6 +358,10 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx) return '('; case '"': return parse_string_literal(ctx, lval); + case '&': + if(*++ctx->ptr == 'h' || *ctx->ptr == 'H') + return parse_hex_literal(ctx, lval); + return '&'; case '<': switch(*++ctx->ptr) { case '>': diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 91da4fe9593..dba5c9aa856 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -31,6 +31,10 @@ Call ok(not (true = false), "true = false is true") Call ok("x" = "x", """x"" = ""x"" is false") Call ok(empty = empty, "empty = empty is false") Call ok(empty = "", "empty = """" is false") +Call ok(0 = 0.0, "0 <> 0.0") +Call ok(16 = &h10&, "16 <> &h10&") +Call ok(010 = 10, "010 <> 10") +Call ok(10. = 10, "10. <> 10") Call ok(getVT(false) = "VT_BOOL", "getVT(false) is not VT_BOOL") Call ok(getVT(true) = "VT_BOOL", "getVT(true) is not VT_BOOL") @@ -44,5 +48,9 @@ Call ok(getVT(0.5) = "VT_R8", "getVT(0.5) is not VT_R8") Call ok(getVT(0.0) = "VT_R8", "getVT(0.0) is not VT_R8") Call ok(getVT(2147483647) = "VT_I4", "getVT(2147483647) is not VT_I4") Call ok(getVT(2147483648) = "VT_R8", "getVT(2147483648) is not VT_R8") +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(&hffFFffFF&) = "VT_I2", "getVT(&hffFFffFF&) is not VT_I2") reportSuccess()