numeric_literal.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef TOOLCHAIN_LEXER_NUMERIC_LITERAL_H_
  5. #define TOOLCHAIN_LEXER_NUMERIC_LITERAL_H_
  6. #include <utility>
  7. #include <variant>
  8. #include "llvm/ADT/APInt.h"
  9. #include "llvm/ADT/Optional.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include "toolchain/diagnostics/diagnostic_emitter.h"
  12. namespace Carbon {
  13. // A numeric literal token that has been extracted from a source buffer.
  14. class LexedNumericLiteral {
  15. public:
  16. // Get the text corresponding to this literal.
  17. [[nodiscard]] auto Text() const -> llvm::StringRef { return text; }
  18. // Extract a numeric literal from the given text, if it has a suitable form.
  19. //
  20. // The supplied `source_text` must outlive the return value.
  21. static auto Lex(llvm::StringRef source_text)
  22. -> llvm::Optional<LexedNumericLiteral>;
  23. // Value of an integer literal.
  24. struct IntegerValue {
  25. // An unsigned literal value.
  26. llvm::APInt value;
  27. };
  28. // Value of a real literal.
  29. struct RealValue {
  30. // The radix of the exponent, either 2 or 10.
  31. int radix;
  32. // The mantissa, represented as a variable-width unsigned integer.
  33. llvm::APInt mantissa;
  34. // The exponent, represented as a variable-width signed integer..
  35. llvm::APInt exponent;
  36. };
  37. struct UnrecoverableError {};
  38. using Value = std::variant<IntegerValue, RealValue, UnrecoverableError>;
  39. // Compute the value of the token, if possible. Emit diagnostics to the given
  40. // emitter if the token is not valid.
  41. auto ComputeValue(DiagnosticEmitter<const char*>& emitter) const -> Value;
  42. private:
  43. LexedNumericLiteral() = default;
  44. class Parser;
  45. // The text of the token.
  46. llvm::StringRef text;
  47. // The offset of the '.'. Set to text.size() if none is present.
  48. int radix_point;
  49. // The offset of the alphabetical character introducing the exponent. In a
  50. // valid literal, this will be an 'e' or a 'p', and may be followed by a '+'
  51. // or a '-', but for error recovery, this may simply be the last lowercase
  52. // letter in the invalid token. Always greater than or equal to radix_point.
  53. // Set to text.size() if none is present.
  54. int exponent;
  55. };
  56. } // namespace Carbon
  57. #endif // TOOLCHAIN_LEXER_NUMERIC_LITERAL_H_