diff --git a/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/Tree.h b/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/Tree.h new file mode 100644 index 0000000..d240fe9 --- /dev/null +++ b/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/Tree.h @@ -0,0 +1,123 @@ +#pragma once + +#include + +namespace mllif::mlir { + + class Node final { + std::string _tag; + std::string _name; + std::vector> _attributes; + std::vector _children; + + static std::string Escape(std::string s) { + std::stringstream ss; + for (const auto c : s) { + if (!std::isprint(c)) { + ss << "&#" << static_cast(c) << ';'; + } + + switch (c) { + case '"': + ss << """; + break; + case '\'': + ss << "'"; + break; + case '<': + ss << "<"; + break; + case '>': + ss << ">"; + break; + case '&': + ss << "&"; + break; + default: + ss << c; + break; + } + } + return ss.str(); + } + + public: + explicit Node(std::string tag, std::string name) : _tag(std::move(tag)), _name(std::move(name)) {} + + std::string &tag() { return _tag; } + std::string tag() const { return _tag; } + + std::string name() const { return _name; } + + std::vector> &attributes() { return _attributes; } + const std::vector> &attributes() const { return _attributes; } + + std::vector &children() { return _children; } + const std::vector &children() const { return _children; } + + void print(llvm::raw_ostream &os) const { + os << '<' << tag(); + + if (name().size()) { + os << " id=\"" << Escape(name()) << '"'; + } + + if (attributes().size()) { + for (const auto &[key, value] : _attributes) { + os << ' ' << key << "=\"" << Escape(value) << '"'; + } + } + + if (children().size()) { + os << "/>"; + return; + } + + os << '>'; + for (const auto &child : children()) { + child.print(os); + } + os << "'; + } + + Node *insert_inplace(std::deque &path, const std::string &tag) { + if (path.empty()) { + return nullptr; + } + + for (auto &child : children()) { + if (const auto p = child.insert(path, tag)) + return p; + } + + auto &node = children().emplace_back(path.size() > 1 ? "namespace" : tag, path.front()); + path.pop_front(); + node.insert_inplace(path, tag); + + return &node; + } + + Node *insert(std::deque &path, const std::string &tag) { + if (path.empty() || path.front() != name()) { + return nullptr; + } + + path.pop_front(); + if (path.empty()) { + return this; + } + + return insert_inplace(path, tag); + } + }; + + class Tree { + Node _root; + + public: + Tree() : _root("assembly", "") {} + + Node &root() { return _root; } + }; + +} // namespace mllif::mlir diff --git a/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/symboltree.h b/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/symboltree.h deleted file mode 100644 index b19c880..0000000 --- a/mllif/Frontend/MLIR/include/mllif/Frontend/MLIR/symboltree.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -namespace mllif::mlir { - - class Symbol { - void print(llvm::raw_ostream &ss, std::size_t indent) const; - - public: - virtual ~Symbol() = default; - - Symbol(const std::string &tag, const std::string &name) : tag(tag), name(name) {} - - std::string tag; - std::string name; - - std::vector> attributes; - std::vector children; - - virtual void print(llvm::raw_ostream &ss) const { - print(ss, 0); - } - }; - - class RootSymbol final : public Symbol { - public: - RootSymbol(); - - void print(llvm::raw_ostream &ss) const override; - }; - - class SymbolTree { - RootSymbol root; - - public: - Symbol& insert(std::deque path); - - void print(llvm::raw_ostream &ss) const; - }; - -} // namespace mllif::mlir diff --git a/mllif/Frontend/MLIR/lib/Tree.cxx b/mllif/Frontend/MLIR/lib/Tree.cxx new file mode 100644 index 0000000..da3ad2a --- /dev/null +++ b/mllif/Frontend/MLIR/lib/Tree.cxx @@ -0,0 +1 @@ +#include "mllif/Frontend/MLIR/Tree.h" diff --git a/mllif/Frontend/MLIR/lib/main.cxx b/mllif/Frontend/MLIR/lib/main.cxx index 765bba8..99ba9d5 100644 --- a/mllif/Frontend/MLIR/lib/main.cxx +++ b/mllif/Frontend/MLIR/lib/main.cxx @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include namespace { @@ -66,7 +66,7 @@ auto main(int argc, char **argv) -> int { const std::string output = argv[1]; - mllif::mlir::SymbolTree tree; + mllif::mlir::Tree tree; for (auto i = 2; i < argc; ++i) { auto module = LoadModule(context, std::string(argv[i])); @@ -146,8 +146,7 @@ auto main(int argc, char **argv) -> int { return; } - auto fnSym = tree.insert(path); - fnSym.tag = tag; + const auto fnSym = tree.root().insert_inplace(path, tag); for (auto iParm = 0; iParm < args.size(); ++iParm) { std::string buffer; @@ -155,9 +154,11 @@ auto main(int argc, char **argv) -> int { args[iParm].getType().print(os); os.flush(); - auto parmSym = mllif::mlir::Symbol("param", argNames[iParm]); - parmSym.attributes.emplace_back("type", buffer); - fnSym.children.push_back(parmSym); + fnSym + ->children() + .emplace_back("param", argNames[iParm]) + .attributes() + .emplace_back("type", buffer); } }); } @@ -169,7 +170,7 @@ auto main(int argc, char **argv) -> int { return 1; } - tree.print(os); + tree.root().print(os); return 0; } diff --git a/mllif/Frontend/MLIR/lib/symboltree.cxx b/mllif/Frontend/MLIR/lib/symboltree.cxx deleted file mode 100644 index 5e2c710..0000000 --- a/mllif/Frontend/MLIR/lib/symboltree.cxx +++ /dev/null @@ -1,61 +0,0 @@ -#include "mllif/Frontend/MLIR/symboltree.h" - -void mllif::mlir::Symbol::print(llvm::raw_ostream &ss, std::size_t indent) const { - const std::string tab(indent, '\t'); - - ss << tab << '<' << tag; - for (const auto &[key, value] : attributes) { - ss << ' ' << key << '=' << '"' << value << '"'; - } - if (children.empty()) { - ss << "/>\n"; - return; - } - - ss << ">\n"; - for (auto child : children) { - child.print(ss, indent + 1); - } - ss << tab << "\n"; -} - -mllif::mlir::RootSymbol::RootSymbol() : Symbol("assembly", "") { -} - -void mllif::mlir::RootSymbol::print(llvm::raw_ostream &ss) const { - ss << "\n"; - Symbol::print(ss); -} - -mllif::mlir::Symbol &mllif::mlir::SymbolTree::insert(std::deque path) { - - llvm::outs() << "PATH: "; - for (const auto &token : path) { - llvm::outs() << token << '/'; - } - llvm::outs() << '\n'; - - Symbol &scope = root; - - while (!path.empty()) { - auto current = path.front(); - path.pop_front(); - - const Symbol *p = nullptr; - for (const auto &child : scope.children) { - if (child.name == current) { - p = &child; - } - } - if (!p) { - p = &scope.children.emplace_back("namespace", current); - } - - scope = *p; - } - - return scope; -} -void mllif::mlir::SymbolTree::print(llvm::raw_ostream &ss) const { - root.print(ss); -}