From 376d8f96d47fa7b495b8988d1de404095a5bcfce Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 18 Apr 2018 16:28:29 -0700 Subject: [PATCH] [flang] repackage SetOfChars as a class type Original-commit: flang-compiler/f18@bae9199f62bd37617db1823b93e6f4da4acfd563 Reviewed-on: https://github.com/flang-compiler/f18/pull/61 Tree-same-pre-rewrite: false --- flang/lib/parser/char-set.cc | 5 +-- flang/lib/parser/char-set.h | 52 +++++++++++--------------------- flang/lib/parser/message.cc | 16 +++++----- flang/lib/parser/message.h | 4 +-- flang/lib/parser/token-parsers.h | 2 +- 5 files changed, 31 insertions(+), 48 deletions(-) diff --git a/flang/lib/parser/char-set.cc b/flang/lib/parser/char-set.cc index 04bd19d50a2c..6054e4a82fa6 100644 --- a/flang/lib/parser/char-set.cc +++ b/flang/lib/parser/char-set.cc @@ -3,11 +3,12 @@ namespace Fortran { namespace parser { -std::string SetOfCharsToString(SetOfChars set) { +std::string SetOfChars::ToString() const { std::string result; + std::uint64_t set{bits_}; for (char ch{' '}; set != 0; ++ch) { if (IsCharInSet(set, ch)) { - set -= SingletonChar(ch); + set -= EncodeChar(ch); result += ch; } } diff --git a/flang/lib/parser/char-set.h b/flang/lib/parser/char-set.h index 304ff02dbd88..f6f398bda2a1 100644 --- a/flang/lib/parser/char-set.h +++ b/flang/lib/parser/char-set.h @@ -12,9 +12,18 @@ namespace Fortran { namespace parser { -using SetOfChars = std::uint64_t; +struct SetOfChars { + constexpr SetOfChars() {} + constexpr SetOfChars(std::uint64_t b) : bits_{b} {} + constexpr SetOfChars(const SetOfChars &) = default; + constexpr SetOfChars(SetOfChars &&) = default; + constexpr SetOfChars &operator=(const SetOfChars &) = default; + constexpr SetOfChars &operator=(SetOfChars &&) = default; + std::string ToString() const; + std::uint64_t bits_{0}; +}; -static constexpr char SixBitEncoding(char c) { +static constexpr std::uint64_t EncodeChar(char c) { if (c <= 32 /*space*/) { // map control characters, incl. LF (newline), to '?' c = '?'; @@ -25,52 +34,25 @@ static constexpr char SixBitEncoding(char c) { // map lower-case letters to upper-case c -= 32; } - // range is now [32..95]; reduce to [0..63] - return c - 32; + // range is now [32..95]; reduce to [0..63] and use as a shift count + return static_cast(1) << (c - 32); } -static constexpr char SixBitDecoding(char c) { - c += 32; - if (c == '?') { - return '\n'; - } - return c; -} - -static constexpr SetOfChars SingletonChar(char c) { - return static_cast(1) << SixBitEncoding(c); -} +static constexpr SetOfChars SingletonChar(char c) { return {EncodeChar(c)}; } static constexpr SetOfChars CharsToSet(const char str[], std::size_t n = 256) { - SetOfChars chars{0}; + SetOfChars chars; for (std::size_t j{0}; j < n; ++j) { if (str[j] == '\0') { break; } - chars |= SingletonChar(str[j]); + chars.bits_ |= EncodeChar(str[j]); } return chars; } -static const SetOfChars emptySetOfChars{0}; -static const SetOfChars fullSetOfChars{~static_cast(0)}; -static const SetOfChars setOfLetters{ - CharsToSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}; -static const SetOfChars setOfDecimalDigits{CharsToSet("0123456789")}; -static const SetOfChars setOfIdentifierStarts{setOfLetters | CharsToSet("_@$")}; -static const SetOfChars setOfIdentifierChars{ - setOfIdentifierStarts | setOfDecimalDigits}; - -// sanity check -static_assert(setOfLetters == 0x7fffffe00000000); -static_assert(setOfDecimalDigits == 0x3ff0000); - static inline constexpr bool IsCharInSet(SetOfChars set, char c) { - return (set & SingletonChar(c)) != 0; -} - -static inline constexpr bool IsSingleton(SetOfChars set) { - return (set & (set - 1)) == emptySetOfChars; + return (set.bits_ & EncodeChar(c)) != 0; } std::string SetOfCharsToString(SetOfChars); diff --git a/flang/lib/parser/message.cc b/flang/lib/parser/message.cc index e44d2ecf760a..3e1900452f68 100644 --- a/flang/lib/parser/message.cc +++ b/flang/lib/parser/message.cc @@ -39,8 +39,8 @@ MessageFormattedText::MessageFormattedText(MessageFixedText text, ...) void Message::Incorporate(Message &that) { if (provenance_ == that.provenance_ && cookedSourceLocation_ == that.cookedSourceLocation_ && - expected_ != emptySetOfChars) { - expected_ |= that.expected_; + expected_.bits_ != 0) { + expected_.bits_ |= that.expected_.bits_; } } @@ -58,12 +58,12 @@ std::string Message::ToString() const { } else { SetOfChars expect{expected_}; if (IsCharInSet(expect, '\n')) { - expect -= SingletonChar('\n'); - if (expect == emptySetOfChars) { + expect.bits_ &= ~SingletonChar('\n').bits_; + if (expect.bits_ == 0) { return "expected end of line"_err_en_US.ToString(); } else { - s = SetOfCharsToString(expect); - if (IsSingleton(expect)) { + s = expect.ToString(); + if (s.size() == 1) { return MessageFormattedText( "expected end of line or '%s'"_err_en_US, s.data()) .MoveString(); @@ -74,8 +74,8 @@ std::string Message::ToString() const { } } } - s = SetOfCharsToString(expect); - if (!IsSingleton(expect)) { + s = expect.ToString(); + if (s.size() != 1) { return MessageFormattedText("expected one of '%s'"_err_en_US, s.data()) .MoveString(); } diff --git a/flang/lib/parser/message.h b/flang/lib/parser/message.h index 66188d4f1a1c..c705c5bc1d94 100644 --- a/flang/lib/parser/message.h +++ b/flang/lib/parser/message.h @@ -87,7 +87,7 @@ public: private: const char *str_{nullptr}; std::size_t bytes_{0}; - SetOfChars set_{emptySetOfChars}; + SetOfChars set_; }; class Message : public ReferenceCounted { @@ -149,7 +149,7 @@ private: std::size_t fixedBytes_{0}; bool isExpected_{false}; std::string string_; - SetOfChars expected_{emptySetOfChars}; + SetOfChars expected_; Context context_; bool isFatal_{false}; }; diff --git a/flang/lib/parser/token-parsers.h b/flang/lib/parser/token-parsers.h index a2eea1de66e1..cef675128a4b 100644 --- a/flang/lib/parser/token-parsers.h +++ b/flang/lib/parser/token-parsers.h @@ -40,7 +40,7 @@ public: } private: - SetOfChars set_; + const SetOfChars set_; }; constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {