numeric_literal.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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 CARBON_TOOLCHAIN_LEX_NUMERIC_LITERAL_H_
  5. #define CARBON_TOOLCHAIN_LEX_NUMERIC_LITERAL_H_
  6. #include <optional>
  7. #include <variant>
  8. #include "llvm/ADT/APInt.h"
  9. #include "llvm/ADT/StringRef.h"
  10. #include "toolchain/diagnostics/emitter.h"
  11. namespace Carbon::Lex {
  12. // A numeric literal token that has been extracted from a source buffer.
  13. class NumericLiteral {
  14. public:
  15. enum class Radix : int8_t {
  16. Binary = 2,
  17. Octal = 8,
  18. Decimal = 10,
  19. Hexadecimal = 16
  20. };
  21. // Value of an integer literal.
  22. struct IntValue {
  23. // An unsigned literal value.
  24. llvm::APInt value;
  25. };
  26. // Value of a real literal.
  27. struct RealValue {
  28. // The radix of the exponent, either Binary or Decimal.
  29. Radix radix;
  30. // The mantissa, represented as a variable-width unsigned integer.
  31. llvm::APInt mantissa;
  32. // The exponent, represented as a variable-width signed integer.
  33. llvm::APInt exponent;
  34. };
  35. struct UnrecoverableError {};
  36. using Value = std::variant<IntValue, RealValue, UnrecoverableError>;
  37. // Extract a numeric literal from the given text, if it has a suitable form.
  38. //
  39. // The supplied `source_text` must outlive the return value.
  40. static auto Lex(llvm::StringRef source_text, bool can_form_real_literal)
  41. -> std::optional<NumericLiteral>;
  42. // Compute the value of the token, if possible. Emit diagnostics to the given
  43. // emitter if the token is not valid.
  44. auto ComputeValue(Diagnostics::Emitter<const char*>& emitter) const -> Value;
  45. // Get the text corresponding to this literal.
  46. auto text() const -> llvm::StringRef { return text_; }
  47. private:
  48. class Parser;
  49. NumericLiteral() = default;
  50. // The text of the token.
  51. llvm::StringRef text_;
  52. // The offset of the '.'. Set to text.size() if none is present.
  53. int radix_point_;
  54. // The offset of the alphabetical character introducing the exponent. In a
  55. // valid literal, this will be an 'e' or a 'p', and may be followed by a '+'
  56. // or a '-', but for error recovery, this may simply be the last lowercase
  57. // letter in the invalid token. Always greater than or equal to radix_point.
  58. // Set to text.size() if none is present.
  59. int exponent_;
  60. };
  61. } // namespace Carbon::Lex
  62. #endif // CARBON_TOOLCHAIN_LEX_NUMERIC_LITERAL_H_