wgsl-reader: Hex float exponents are optional
Fixed: tint:1210 Change-Id: I4256494e3ca3f98082f360e0447d0392964073bd Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/66040 Auto-Submit: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
a095b26d17
commit
a6969c4359
|
@ -343,7 +343,9 @@ Token Lexer::try_hex_float() {
|
|||
}
|
||||
|
||||
// .?
|
||||
bool hex_point = false;
|
||||
if (matches(end, ".")) {
|
||||
hex_point = true;
|
||||
end++;
|
||||
}
|
||||
|
||||
|
@ -359,14 +361,18 @@ Token Lexer::try_hex_float() {
|
|||
return {};
|
||||
}
|
||||
|
||||
// (p|P)
|
||||
if (matches(end, "p") || matches(end, "P")) {
|
||||
// Is the binary exponent present? It's optional.
|
||||
const bool has_exponent = (matches(end, "p") || matches(end, "P"));
|
||||
if (has_exponent) {
|
||||
end++;
|
||||
} else {
|
||||
}
|
||||
if (!has_exponent && !hex_point) {
|
||||
// It's not a hex float. At best it's a hex integer.
|
||||
return {};
|
||||
}
|
||||
|
||||
// At this point, we know for sure our token is a hex float value.
|
||||
// At this point, we know for sure our token is a hex float value,
|
||||
// or an invalid token.
|
||||
|
||||
// Parse integer part
|
||||
// [0-9a-fA-F]*
|
||||
|
@ -423,8 +429,20 @@ Token Lexer::try_hex_float() {
|
|||
}
|
||||
}
|
||||
|
||||
// (+|-)?
|
||||
// Determine if the value of the mantissa is zero.
|
||||
// Note: it's not enough to check mantissa == 0 as we drop the initial bit,
|
||||
// whether it's in the integer part or the fractional part.
|
||||
const bool is_zero = !seen_prior_one_bits;
|
||||
TINT_ASSERT(Reader, !is_zero || mantissa == 0);
|
||||
|
||||
// Parse the optional exponent.
|
||||
// ((p|P)(\+|-)?[0-9]+)?
|
||||
uint32_t input_exponent = 0; // Defaults to 0 if not present
|
||||
int32_t exponent_sign = 1;
|
||||
// If the 'p' part is present, the rest of the exponent must exist.
|
||||
if (has_exponent) {
|
||||
// Parse the rest of the exponent.
|
||||
// (+|-)?
|
||||
if (matches(end, "+")) {
|
||||
end++;
|
||||
} else if (matches(end, "-")) {
|
||||
|
@ -432,20 +450,13 @@ Token Lexer::try_hex_float() {
|
|||
end++;
|
||||
}
|
||||
|
||||
// Determine if the value is zero.
|
||||
// Note: it's not enough to check mantissa == 0 as we drop the initial bit,
|
||||
// whether it's in the integer part or the fractional part.
|
||||
const bool is_zero = !seen_prior_one_bits;
|
||||
TINT_ASSERT(Reader, !is_zero || mantissa == 0);
|
||||
|
||||
// Parse exponent from input
|
||||
// [0-9]+
|
||||
// Allow overflow (in uint32_t) when the floating point value magnitude is
|
||||
// zero.
|
||||
bool has_exponent = false;
|
||||
uint32_t input_exponent = 0;
|
||||
bool has_exponent_digits = false;
|
||||
while (end < len_ && isdigit(content_->data[end])) {
|
||||
has_exponent = true;
|
||||
has_exponent_digits = true;
|
||||
auto prev_exponent = input_exponent;
|
||||
input_exponent = (input_exponent * 10) + dec_value(content_->data[end]);
|
||||
// Check if we've overflowed input_exponent. This only matters when
|
||||
|
@ -456,10 +467,11 @@ Token Lexer::try_hex_float() {
|
|||
}
|
||||
end++;
|
||||
}
|
||||
if (!has_exponent) {
|
||||
if (!has_exponent_digits) {
|
||||
return {Token::Type::kError, source,
|
||||
"expected an exponent value for hex float"};
|
||||
}
|
||||
}
|
||||
|
||||
pos_ = end;
|
||||
location_.column += (end - start);
|
||||
|
|
|
@ -275,6 +275,14 @@ FloatLiteralTestCase hexfloat_literal_test_cases[] = {
|
|||
{"-0x123Ep+1", -9340.f},
|
||||
{"0x1a2b3cP12", 7.024656e+09f},
|
||||
{"-0x1a2b3cP12", -7.024656e+09f},
|
||||
|
||||
// Examples without a binary exponent part.
|
||||
{"0x1.", 1.0f},
|
||||
{"0x.8", 0.5f},
|
||||
{"0x1.8", 1.5f},
|
||||
{"-0x1.", -1.0f},
|
||||
{"-0x.8", -0.5f},
|
||||
{"-0x1.8", -1.5f},
|
||||
};
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplFloatLiteralTest_HexFloat,
|
||||
ParserImplFloatLiteralTest,
|
||||
|
@ -326,9 +334,18 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
testing::ValuesIn(invalid_hexfloat_exponent_too_large_cases));
|
||||
|
||||
InvalidLiteralTestCase invalid_hexfloat_exponent_missing_cases[] = {
|
||||
// Lower case p
|
||||
{"0x0p", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0p+", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0p-", "1:1: expected an exponent value for hex float"},
|
||||
{"0x1.0p", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0.1p", "1:1: expected an exponent value for hex float"},
|
||||
// Upper case p
|
||||
{"0x0P", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0P+", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0P-", "1:1: expected an exponent value for hex float"},
|
||||
{"0x1.0P", "1:1: expected an exponent value for hex float"},
|
||||
{"0x0.1P", "1:1: expected an exponent value for hex float"},
|
||||
};
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ParserImplInvalidLiteralTest_HexFloatExponentMissing,
|
||||
|
|
Loading…
Reference in New Issue