numeric_literal.h 2.4 KB

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