Tensor Comprehensions
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tree.h
Go to the documentation of this file.
1 
16 #pragma once
17 
18 #include <functional>
19 #include <memory>
20 #include <vector>
21 
22 #include "tc/lang/lexer.h"
23 
24 namespace lang {
25 
42 
43 struct Tree;
44 using TreeRef = std::shared_ptr<Tree>;
45 using TreeList = std::vector<TreeRef>;
46 
47 static const TreeList empty_trees = {};
48 
49 struct Tree : std::enable_shared_from_this<Tree> {
50  Tree(int kind_) : kind_(kind_) {}
51  int kind() const {
52  return kind_;
53  }
54  virtual bool isAtom() const {
55  return true;
56  }
57  virtual const SourceRange& range() const {
58  throw std::runtime_error("is an Atom");
59  }
60  virtual double doubleValue() const {
61  throw std::runtime_error("not a TK_NUMBER");
62  }
63  virtual const std::string& stringValue() const {
64  throw std::runtime_error("not a TK_STRING");
65  }
66  virtual bool boolValue() const {
67  throw std::runtime_error("not a TK_BOOL_VALUE");
68  }
69  virtual const TreeList& trees() const {
70  return empty_trees;
71  }
72  const TreeRef& tree(size_t i) const {
73  return trees().at(i);
74  }
75  virtual TreeRef map(std::function<TreeRef(TreeRef)> fn) {
76  return shared_from_this();
77  }
78  void expect(int k) {
79  expect(k, trees().size());
80  }
81  void expect(int k, int numsubtrees) {
82  if (kind() != k || trees().size() != numsubtrees) {
83  std::stringstream ss;
84  ss << "expected kind '" << kindToString(k) << "' with " << numsubtrees
85  << " subtrees but found '" << kindToString(kind()) << "' with "
86  << trees().size() << " subtrees.\n";
87  range().highlight(ss);
88  throw std::runtime_error(ss.str());
89  }
90  }
91  int kind_;
92 };
93 
94 struct String : public Tree {
95  String(const std::string& value_) : Tree(TK_STRING), value_(value_) {}
96  virtual const std::string& stringValue() const override {
97  return value_;
98  }
99  template <typename... Args>
100  static TreeRef create(Args&&... args) {
101  return std::make_shared<String>(std::forward<Args>(args)...);
102  }
103 
104  private:
105  std::string value_;
106 };
107 struct Number : public Tree {
108  Number(double value_) : Tree(TK_NUMBER), value_(value_) {}
109  virtual double doubleValue() const override {
110  return value_;
111  }
112  template <typename... Args>
113  static TreeRef create(Args&&... args) {
114  return std::make_shared<Number>(std::forward<Args>(args)...);
115  }
116 
117  private:
118  double value_;
119 };
120 struct Bool : public Tree {
121  Bool(bool value_) : Tree(TK_BOOL_VALUE), value_(value_) {}
122  virtual bool boolValue() const override {
123  return value_;
124  }
125  template <typename... Args>
126  static TreeRef create(Args&&... args) {
127  return std::make_shared<Bool>(std::forward<Args>(args)...);
128  }
129 
130  private:
131  bool value_;
132 };
133 
134 static SourceRange mergeRanges(SourceRange c, const TreeList& others) {
135  for (auto t : others) {
136  if (t->isAtom())
137  continue;
138  size_t s = std::min(c.start(), t->range().start());
139  size_t e = std::max(c.end(), t->range().end());
140  c = SourceRange(c.file_ptr(), s, e);
141  }
142  return c;
143 }
144 
145 struct Compound : public Tree {
146  Compound(int kind, const SourceRange& range_) : Tree(kind), range_(range_) {}
148  : Tree(kind),
149  range_(mergeRanges(range_, trees_)),
150  trees_(std::move(trees_)) {}
151  virtual const TreeList& trees() const override {
152  return trees_;
153  }
154  static TreeRef
156  return std::make_shared<Compound>(kind, range_, std::move(trees_));
157  }
158  virtual bool isAtom() const override {
159  return false;
160  }
161  virtual TreeRef map(std::function<TreeRef(TreeRef)> fn) override {
163  for (auto& t : trees()) {
164  trees_.push_back(fn(t));
165  }
166  return Compound::create(kind(), range(), std::move(trees_));
167  }
168  const SourceRange& range() const override {
169  return range_;
170  }
171 
172  private:
175 };
176 
178 struct pretty_tree {
179  pretty_tree(const TreeRef& tree, size_t col = 40) : tree(tree), col(col) {}
180  const TreeRef& tree;
181  size_t col;
182  std::unordered_map<TreeRef, std::string> flat_strings;
183  const std::string& get_flat(const TreeRef& t) {
184  auto it = flat_strings.find(t);
185  if (it != flat_strings.end())
186  return it->second;
187 
188  std::stringstream out;
189  switch (t->kind()) {
190  case TK_NUMBER:
191  out << t->doubleValue();
192  break;
193  case TK_STRING:
194  out << t->stringValue();
195  break;
196  default:
197  out << "(" << kindToString(t->kind());
198  for (auto e : t->trees()) {
199  out << " " << get_flat(e);
200  }
201  out << ")";
202  break;
203  }
204  auto it_ = flat_strings.emplace(t, out.str());
205  return it_.first->second;
206  }
207  void print(std::ostream& out, const TreeRef& t, int indent) {
208  const std::string& s = get_flat(t);
209  if (indent + s.size() < col || t->isAtom()) {
210  out << s;
211  return;
212  }
213  std::string k = kindToString(t->kind());
214  out << "(" << k;
215  for (auto e : t->trees()) {
216  out << "\n" << std::string(indent + 2, ' ');
217  print(out, e, indent + 2);
218  }
219  out << ")";
220  }
221 };
222 
223 static inline std::ostream& operator<<(std::ostream& out, pretty_tree t_) {
224  t_.print(out, t_.tree, 0);
225  return out << std::endl;
226 }
227 
228 static inline std::ostream& operator<<(std::ostream& out, TreeRef t) {
229  return out << pretty_tree(t);
230 }
231 } // namespace lang
void highlight(std::ostream &out) const
Definition: lexer.h:315
virtual const SourceRange & range() const
Definition: tree.h:57
void expect(int k)
Definition: tree.h:78
size_t col
Definition: tree.h:181
String(const std::string &value_)
Definition: tree.h:95
const ErrorReport & operator<<(const ErrorReport &e, const T &t)
Definition: error_report.h:50
static TreeRef create(Args &&...args)
Definition: tree.h:113
Compound(int kind, const SourceRange &range_, TreeList &&trees_)
Definition: tree.h:147
Bool(bool value_)
Definition: tree.h:121
Tree(int kind_)
Definition: tree.h:50
SourceRange range_
Definition: tree.h:173
Compound(int kind, const SourceRange &range_)
Definition: tree.h:146
size_t start() const
Definition: lexer.h:338
Definition: tree.h:120
bool value_
Definition: tree.h:131
virtual TreeRef map(std::function< TreeRef(TreeRef)> fn) override
Definition: tree.h:161
Definition: tree.h:94
const SourceRange & range() const override
Definition: tree.h:168
virtual bool boolValue() const
Definition: tree.h:66
virtual bool isAtom() const override
Definition: tree.h:158
tree pretty printer
Definition: tree.h:178
virtual const TreeList & trees() const override
Definition: tree.h:151
virtual TreeRef map(std::function< TreeRef(TreeRef)> fn)
Definition: tree.h:75
static TreeRef create(Args &&...args)
Definition: tree.h:126
double value_
Definition: tree.h:118
static TreeRef create(Args &&...args)
Definition: tree.h:100
Definition: lexer.h:303
TreeList trees_
Definition: tree.h:174
const TreeRef & tree
Definition: tree.h:180
Definition: tree.h:145
virtual const TreeList & trees() const
Definition: tree.h:69
virtual bool boolValue() const override
Definition: tree.h:122
std::string value_
Definition: tree.h:105
virtual const std::string & stringValue() const
Definition: tree.h:63
const std::string & get_flat(const TreeRef &t)
Definition: tree.h:183
std::vector< TreeRef > TreeList
Definition: tree.h:45
const TreeRef & tree(size_t i) const
Definition: tree.h:72
std::unordered_map< TreeRef, std::string > flat_strings
Definition: tree.h:182
int kind() const
Definition: tree.h:51
int kind_
Definition: tree.h:91
Definition: tree.h:107
virtual const std::string & stringValue() const override
Definition: tree.h:96
void expect(int k, int numsubtrees)
Definition: tree.h:81
std::string kindToString(int kind)
virtual double doubleValue() const override
Definition: tree.h:109
void print(std::ostream &out, const TreeRef &t, int indent)
Definition: tree.h:207
virtual double doubleValue() const
Definition: tree.h:60
virtual bool isAtom() const
Definition: tree.h:54
pretty_tree(const TreeRef &tree, size_t col=40)
Definition: tree.h:179
static TreeRef create(int kind, const SourceRange &range_, TreeList &&trees_)
Definition: tree.h:155
Number(double value_)
Definition: tree.h:108
size_t end() const
Definition: lexer.h:341
std::shared_ptr< Tree > TreeRef
Definition: tree.h:44
Definition: tree.h:49