[flang] repackage SetOfChars as a class type

Original-commit: flang-compiler/f18@bae9199f62
Reviewed-on: https://github.com/flang-compiler/f18/pull/61
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-04-18 16:28:29 -07:00
parent 075fe789da
commit 376d8f96d4
5 changed files with 31 additions and 48 deletions

View File

@ -3,11 +3,12 @@
namespace Fortran { namespace Fortran {
namespace parser { namespace parser {
std::string SetOfCharsToString(SetOfChars set) { std::string SetOfChars::ToString() const {
std::string result; std::string result;
std::uint64_t set{bits_};
for (char ch{' '}; set != 0; ++ch) { for (char ch{' '}; set != 0; ++ch) {
if (IsCharInSet(set, ch)) { if (IsCharInSet(set, ch)) {
set -= SingletonChar(ch); set -= EncodeChar(ch);
result += ch; result += ch;
} }
} }

View File

@ -12,9 +12,18 @@
namespace Fortran { namespace Fortran {
namespace parser { 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*/) { if (c <= 32 /*space*/) {
// map control characters, incl. LF (newline), to '?' // map control characters, incl. LF (newline), to '?'
c = '?'; c = '?';
@ -25,52 +34,25 @@ static constexpr char SixBitEncoding(char c) {
// map lower-case letters to upper-case // map lower-case letters to upper-case
c -= 32; c -= 32;
} }
// range is now [32..95]; reduce to [0..63] // range is now [32..95]; reduce to [0..63] and use as a shift count
return c - 32; return static_cast<std::uint64_t>(1) << (c - 32);
} }
static constexpr char SixBitDecoding(char c) { static constexpr SetOfChars SingletonChar(char c) { return {EncodeChar(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 CharsToSet(const char str[], std::size_t n = 256) { 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) { for (std::size_t j{0}; j < n; ++j) {
if (str[j] == '\0') { if (str[j] == '\0') {
break; break;
} }
chars |= SingletonChar(str[j]); chars.bits_ |= EncodeChar(str[j]);
} }
return chars; 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) { static inline constexpr bool IsCharInSet(SetOfChars set, char c) {
return (set & SingletonChar(c)) != 0; return (set.bits_ & EncodeChar(c)) != 0;
}
static inline constexpr bool IsSingleton(SetOfChars set) {
return (set & (set - 1)) == emptySetOfChars;
} }
std::string SetOfCharsToString(SetOfChars); std::string SetOfCharsToString(SetOfChars);

View File

@ -39,8 +39,8 @@ MessageFormattedText::MessageFormattedText(MessageFixedText text, ...)
void Message::Incorporate(Message &that) { void Message::Incorporate(Message &that) {
if (provenance_ == that.provenance_ && if (provenance_ == that.provenance_ &&
cookedSourceLocation_ == that.cookedSourceLocation_ && cookedSourceLocation_ == that.cookedSourceLocation_ &&
expected_ != emptySetOfChars) { expected_.bits_ != 0) {
expected_ |= that.expected_; expected_.bits_ |= that.expected_.bits_;
} }
} }
@ -58,12 +58,12 @@ std::string Message::ToString() const {
} else { } else {
SetOfChars expect{expected_}; SetOfChars expect{expected_};
if (IsCharInSet(expect, '\n')) { if (IsCharInSet(expect, '\n')) {
expect -= SingletonChar('\n'); expect.bits_ &= ~SingletonChar('\n').bits_;
if (expect == emptySetOfChars) { if (expect.bits_ == 0) {
return "expected end of line"_err_en_US.ToString(); return "expected end of line"_err_en_US.ToString();
} else { } else {
s = SetOfCharsToString(expect); s = expect.ToString();
if (IsSingleton(expect)) { if (s.size() == 1) {
return MessageFormattedText( return MessageFormattedText(
"expected end of line or '%s'"_err_en_US, s.data()) "expected end of line or '%s'"_err_en_US, s.data())
.MoveString(); .MoveString();
@ -74,8 +74,8 @@ std::string Message::ToString() const {
} }
} }
} }
s = SetOfCharsToString(expect); s = expect.ToString();
if (!IsSingleton(expect)) { if (s.size() != 1) {
return MessageFormattedText("expected one of '%s'"_err_en_US, s.data()) return MessageFormattedText("expected one of '%s'"_err_en_US, s.data())
.MoveString(); .MoveString();
} }

View File

@ -87,7 +87,7 @@ public:
private: private:
const char *str_{nullptr}; const char *str_{nullptr};
std::size_t bytes_{0}; std::size_t bytes_{0};
SetOfChars set_{emptySetOfChars}; SetOfChars set_;
}; };
class Message : public ReferenceCounted<Message> { class Message : public ReferenceCounted<Message> {
@ -149,7 +149,7 @@ private:
std::size_t fixedBytes_{0}; std::size_t fixedBytes_{0};
bool isExpected_{false}; bool isExpected_{false};
std::string string_; std::string string_;
SetOfChars expected_{emptySetOfChars}; SetOfChars expected_;
Context context_; Context context_;
bool isFatal_{false}; bool isFatal_{false};
}; };

View File

@ -40,7 +40,7 @@ public:
} }
private: private:
SetOfChars set_; const SetOfChars set_;
}; };
constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) { constexpr AnyOfChars operator""_ch(const char str[], std::size_t n) {