[flang] repackage SetOfChars as a class type
authorpeter klausler <pklausler@nvidia.com>
Wed, 18 Apr 2018 23:28:29 +0000 (16:28 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 19 Apr 2018 18:21:06 +0000 (11:21 -0700)
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
flang/lib/parser/char-set.h
flang/lib/parser/message.cc
flang/lib/parser/message.h
flang/lib/parser/token-parsers.h

index 04bd19d..6054e4a 100644 (file)
@@ -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;
     }
   }
index 304ff02..f6f398b 100644 (file)
 namespace Fortran {
 namespace parser {
 
-using SetOfChars = std::uint64_t;
-
-static constexpr char SixBitEncoding(char c) {
+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 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<std::uint64_t>(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<SetOfChars>(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<SetOfChars>(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);
index e44d2ec..3e19004 100644 (file)
@@ -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();
       }
index 66188d4..c705c5b 100644 (file)
@@ -87,7 +87,7 @@ public:
 private:
   const char *str_{nullptr};
   std::size_t bytes_{0};
-  SetOfChars set_{emptySetOfChars};
+  SetOfChars set_;
 };
 
 class Message : public ReferenceCounted<Message> {
@@ -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};
 };
index a2eea1d..cef6751 100644 (file)
@@ -40,7 +40,7 @@ public:
   }
 
 private:
-  SetOfChars set_;
+  const SetOfChars set_;
 };
 
 constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {