[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 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;
}
}

View File

@ -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<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);

View 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();
}

View 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};
};

View File

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