|
@@ -324,11 +324,6 @@ auto NumericLiteral::Parser::CheckDigitSequence(llvm::StringRef text,
|
|
|
return {.ok = false};
|
|
return {.ok = false};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Check that digit separators occur in exactly the expected positions.
|
|
|
|
|
- if (num_digit_separators) {
|
|
|
|
|
- CheckDigitSeparatorPlacement(text, radix, num_digit_separators);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (!CanLexInt(emitter_, text)) {
|
|
if (!CanLexInt(emitter_, text)) {
|
|
|
return {.ok = false};
|
|
return {.ok = false};
|
|
|
}
|
|
}
|
|
@@ -336,51 +331,6 @@ auto NumericLiteral::Parser::CheckDigitSequence(llvm::StringRef text,
|
|
|
return {.ok = true, .has_digit_separators = (num_digit_separators != 0)};
|
|
return {.ok = true, .has_digit_separators = (num_digit_separators != 0)};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// Given a number with digit separators, check that the digit separators are
|
|
|
|
|
-// correctly positioned.
|
|
|
|
|
-auto NumericLiteral::Parser::CheckDigitSeparatorPlacement(
|
|
|
|
|
- llvm::StringRef text, Radix radix, int num_digit_separators) -> void {
|
|
|
|
|
- CARBON_DCHECK(std::count(text.begin(), text.end(), '_') ==
|
|
|
|
|
- num_digit_separators)
|
|
|
|
|
- << "given wrong number of digit separators: " << num_digit_separators;
|
|
|
|
|
-
|
|
|
|
|
- if (radix == Radix::Binary) {
|
|
|
|
|
- // There are no restrictions on digit separator placement for binary
|
|
|
|
|
- // literals.
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- auto diagnose_irregular_digit_separators = [&]() {
|
|
|
|
|
- CARBON_DIAGNOSTIC(
|
|
|
|
|
- IrregularDigitSeparators, Error,
|
|
|
|
|
- "Digit separators in {0} number should appear every {1} characters "
|
|
|
|
|
- "from the right.",
|
|
|
|
|
- NumericLiteral::Radix, int);
|
|
|
|
|
- emitter_.Emit(text.begin(), IrregularDigitSeparators, radix,
|
|
|
|
|
- radix == Radix::Decimal ? 3 : 4);
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- // For decimal and hexadecimal digit sequences, digit separators must form
|
|
|
|
|
- // groups of 3 or 4 digits (4 or 5 characters), respectively.
|
|
|
|
|
- int stride = (radix == Radix::Decimal ? 4 : 5);
|
|
|
|
|
- int remaining_digit_separators = num_digit_separators;
|
|
|
|
|
- const auto* pos = text.end();
|
|
|
|
|
- while (pos - text.begin() >= stride) {
|
|
|
|
|
- pos -= stride;
|
|
|
|
|
- if (*pos != '_') {
|
|
|
|
|
- diagnose_irregular_digit_separators();
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- --remaining_digit_separators;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Check there weren't any other digit separators.
|
|
|
|
|
- if (remaining_digit_separators) {
|
|
|
|
|
- diagnose_irregular_digit_separators();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
// Check that we don't have a '0' prefix on a non-zero decimal integer.
|
|
// Check that we don't have a '0' prefix on a non-zero decimal integer.
|
|
|
auto NumericLiteral::Parser::CheckLeadingZero() -> bool {
|
|
auto NumericLiteral::Parser::CheckLeadingZero() -> bool {
|
|
|
if (radix_ == Radix::Decimal && int_part_.starts_with("0") &&
|
|
if (radix_ == Radix::Decimal && int_part_.starts_with("0") &&
|