source: icGREP/icgrep-devel/icgrep/re/re_name.h @ 6173

Last change on this file since 6173 was 6173, checked in by nmedfort, 12 months ago

Added RE_Inspector.

Migrated RE passes to RE_Transformer.

Incorporated Memoizer functionality into RE_Transformer/Inspector.

Removed Memoizer.

Bug fix for unicode_set.

File size: 6.3 KB
RevLine 
[3917]1#ifndef RE_NAME_H
2#define RE_NAME_H
3
[4246]4#include <re/re_re.h>
[4335]5#include <re/re_cc.h>
[5267]6#include <llvm/Support/Casting.h>
[3917]7
[4808]8namespace UCD {
9    class UnicodeSet;
10}
[4246]11
[4194]12namespace re {
13
14class Name : public RE {
[3917]15public:
[4194]16    static inline bool classof(const RE * re) {
17        return re->getClassTypeId() == ClassTypeId::Name;
18    }
19    static inline bool classof(const void *) {
20        return false;
21    }
[4516]22    using length_t = std::string::size_type;
[4194]23    enum class Type {
[5805]24        Unicode
[4377]25        , UnicodeProperty
[5080]26        , Capture
27        , Reference
[5091]28        , ZeroWidth
[4335]29        , Unknown
[4194]30    };
[4516]31    std::string getNamespace() const;
[4809]32    bool hasNamespace() const;
[4516]33    std::string getName() const;
[5887]34    std::string getFullName() const;
[4182]35    Type getType() const;
[4808]36    RE * getDefinition() const;
[4819]37    bool operator<(const Name & other) const;
38    bool operator<(const CC & other) const;
[4823]39    bool operator>(const CC & other) const;
[4818]40    void setDefinition(RE * definition);
[4194]41    virtual ~Name() {}
42protected:
[4823]43    friend Name * makeName(const std::string & name, RE * cc);
[5080]44    friend Name * makeCapture(const std::string & name, RE * captured);
45    friend Name * makeReference(const std::string & name, RE * captureName);
[5091]46    friend Name * makeZeroWidth(const std::string & name, RE * zerowidth);
[4823]47    friend Name * makeName(CC * const cc);
[6173]48    friend Name * makeName(const std::string &, Type, RE *);
49    friend Name * makeName(const std::string &, const std::string &, Type, RE *);
[5202]50    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, Type type, RE * defn)
[4249]51    : RE(ClassTypeId::Name)
[4516]52    , mNamespaceLength(namespaceLength)
53    , mNamespace(replicateString(nameSpace, namespaceLength))
54    , mNameLength(nameLength)
55    , mName(replicateString(name, nameLength))
[4249]56    , mType(type)
[5234]57    , mDefinition(defn) {
[4249]58
59    }
[4516]60    inline const char * replicateString(const char * string, const length_t length) {
[5781]61        if (string && (length > 0)) {
[4516]62            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
63            std::memcpy(allocated, string, length);
[5781]64            return allocated;
[4516]65        }
[5781]66        return nullptr;
[4516]67    }
[4249]68
[3917]69private:
[4660]70    const length_t      mNamespaceLength;
71    const char * const  mNamespace;
72    const length_t      mNameLength;
73    const char * const  mName;
[5233]74    Type                mType;
[4818]75    RE *                mDefinition;
[3917]76};
77
[4516]78inline std::string Name::getNamespace() const {
79    return std::string(mNamespace, mNamespaceLength);
[4377]80}
81
[4809]82inline bool Name::hasNamespace() const {
83    return (mNamespaceLength != 0);
84}
85
[4516]86inline std::string Name::getName() const {
87    return std::string(mName, mNameLength);
88}
[5887]89
90inline std::string Name::getFullName() const {
91    if (hasNamespace()) return getNamespace() + "=" + getName();
92    else return getName();
93}
94
[4246]95inline Name::Type Name::getType() const {
96    return mType;
[4194]97}
98
[4336]99inline RE * Name::getDefinition() const {
[4818]100    return mDefinition;
[4194]101}
102
[4818]103inline void Name::setDefinition(RE * definition) {
[5634]104    assert (definition != nullptr);
[4818]105    assert (definition != this);
106    mDefinition = definition;
[4194]107}
108
[4819]109inline bool Name::operator < (const Name & other) const {
[5267]110    if (LLVM_LIKELY(mDefinition && other.mDefinition && llvm::isa<CC>(mDefinition) && llvm::isa<CC>(other.mDefinition))) {
111        return *llvm::cast<CC>(mDefinition) < *llvm::cast<CC>(other.mDefinition);
[4819]112    } else if (mNamespaceLength < other.mNamespaceLength) {
113        return true;
114    } else if (mNamespaceLength > other.mNamespaceLength) {
115        return false;
116    } else if (mNameLength < other.mNameLength) {
117        return true;
118    } else if (mNameLength > other.mNameLength) {
119        return false;
120    }
121    const auto diff = std::memcmp(mNamespace, other.mNamespace, mNamespaceLength);
122    if (diff < 0) {
123        return true;
124    } else if (diff > 0) {
125        return false;
126    }
127    return (std::memcmp(mName, other.mName, mNameLength) < 0);
128}
129
130inline bool Name::operator < (const CC & other) const {
[5267]131    if (mDefinition && llvm::isa<CC>(mDefinition)) {
132        return *llvm::cast<CC>(mDefinition) < other;
[4819]133    }
[5630]134    return RE::ClassTypeId::Name < RE::ClassTypeId::CC;
[4819]135}
136
[4823]137inline bool Name::operator > (const CC & other) const {
[5267]138    if (mDefinition && llvm::isa<CC>(mDefinition)) {
139        return other < *llvm::cast<CC>(mDefinition);
[4823]140    }
[5630]141    return RE::ClassTypeId::CC < RE::ClassTypeId::Name;
[4823]142}
143
[6173]144inline Name * makeName(const std::string & name, const Name::Type type, RE * defn = nullptr) {
145    return new Name(nullptr, 0, name.c_str(), name.length(), type, defn);
[4194]146}
147
[6173]148inline Name * makeName(const std::string & property, const std::string & value, const Name::Type type, RE * defn = nullptr) {
149    return new Name(property.c_str(), property.length(), value.c_str(), value.length(), type, defn);
[4377]150}
151
[4516]152inline Name * makeName(const std::string & name, RE * cc) {
[5267]153    if (llvm::isa<Name>(cc)) {
154        return llvm::cast<Name>(cc);
[4249]155    }
[5267]156    else if (llvm::isa<CC>(cc)) {
[5805]157        return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
[4335]158    }
[4516]159    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
[4194]160}
161
[4823]162inline Name * makeName(CC * const cc) {
[5847]163    const std::string name = cc->canonicalName();
[5805]164    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
[4194]165}
166
[5797]167inline Name * makeCapture(const std::string & name, RE * captured) {
[5080]168    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Capture, captured);
[4823]169}
[5080]170   
171inline Name * makeReference(const std::string & name, RE * captureName) {
172    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Reference, captureName);
173}
[4823]174
[5091]175inline Name * makeZeroWidth(const std::string & name, RE * zerowidth = NULL) {
176    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::ZeroWidth, zerowidth);
[5080]177}
[5091]178}
[5080]179
[6159]180template <typename To, typename FromTy> bool defined(FromTy * e) {
181    if (llvm::isa<To>(e)) return true;
182    if (llvm::isa<re::Name>(e)) {
183        re::RE * def = llvm::cast<re::Name>(e)->getDefinition();
184        return def && defined<To, FromTy>(def);
185    }
186    return false;
187}
188
189template <typename To, typename FromTy> To * defCast(FromTy * e) {
190    if (llvm::isa<To>(e)) return llvm::cast<To>(e);
191    if (llvm::isa<re::Name>(e)) {
192        re::RE * def = llvm::cast<re::Name>(e)->getDefinition();
193        if (def) return defCast<To, FromTy>(def);
194    }
195    return nullptr;
196}
197
198
[3917]199#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.