hobbes
a language, embedded compiler, and runtime for efficient dynamic expression evaluation, data storage and analysis
typemap.H
Go to the documentation of this file.
1 
2 #ifndef HOBBES_LANG_TYPEMAP_HPP_INCLUDED
3 #define HOBBES_LANG_TYPEMAP_HPP_INCLUDED
4 
5 #include <hobbes/lang/type.H>
6 #include <hobbes/util/trie.H>
7 #include <hobbes/util/variant.H>
8 #include <hobbes/lang/typeinf.H>
9 #include <map>
10 
11 namespace hobbes {
12 
13 struct MonoTypeLT {
14  bool operator()(const MonoTypePtr&, const MonoTypePtr&) const;
15 };
16 
17 struct MTyMap {
18  template <typename V>
19  struct map {
20  typedef std::map<MonoTypePtr, V, MonoTypeLT> type;
21  };
22 };
23 
24 // used to do exact matches on types with a wildcard
26 typedef std::vector<MaybePathPoint> MaybePathPoints;
27 
28 // a map from type sequences to some value
29 template <typename V>
30  class type_map {
31  public:
32  void insert(const MonoTypes& mts, const V& v) {
33  this->d.insert(mts.begin(), mts.end(), v);
34  }
35 
36  V* lookup(const MonoTypes& mts) const {
37  return this->d.lookup(mts.begin(), mts.end());
38  }
39 
40  std::vector<V> values() const {
41  return this->d.values();
42  }
43 
44  // determines whether at least one type is unifiable with the given type
45  bool hasMatch(const TEnvPtr& tenv, const MonoTypes& mts) const {
46  MonoTypeUnifier u(tenv);
47  return hasMatch(u, this->d.rootPoint(), mts, 0);
48  }
49 
50  // matches on unifiable (but not necessarily equal) types
51  void matches(const TEnvPtr& tenv, const MonoTypes& mts, std::vector<V>* out) const {
52  MonoTypeUnifier u(tenv);
53  findMatches(u, this->d.rootPoint(), mts, 0, out);
54  }
55 
56  // matches on bidirectionally unifiable types
57  void bidimatches(const TEnvPtr& tenv, const MonoTypes& mts, std::vector<V>* out) const {
58  MonoTypeUnifier u(tenv);
59  findBidiMatches(u, this->d.rootPoint(), mts, 0, out);
60  }
61 
62  // exact matches on types with a wildcard
63  void find(const MaybePathPoints& path, std::vector<V>* out) const {
64  findMatches(this->d.rootPoint(), path, 0, out);
65  }
66  private:
68  tmdata d;
69 
70  bool hasMatch(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i) const {
71  if (p == 0) {
72  return false;
73  }
74 
75  if (i == mts.size()) {
76  return true;
77  } else {
78  const MonoTypePtr& mty = u.substitute(mts[i]);
79 
80  if (!hasFreeVariables(mty)) {
81  return hasMatch(u, this->d.moveTo(mty, p), mts, i + 1);
82  } else {
83  typename tmdata::KeyPointSeq kps;
84  this->d.keyPointsAt(&kps, p);
85 
86  for (typename tmdata::KeyPointSeq::const_iterator kp = kps.begin(); kp != kps.end(); ++kp) {
87  try {
88  MonoTypeUnifier pu = u;
89  mgu(mty, kp->first, &pu);
90  if (hasMatch(pu, kp->second, mts, i + 1)) return true;
91  } catch (std::exception& ex) {
92  }
93  }
94  }
95  }
96  return false;
97  }
98 
99  void findMatches(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i, std::vector<V>* out) const {
100  if (p == 0) return;
101 
102  if (i == mts.size()) {
103  if (const V* v = this->d.valueAt(p)) {
104  out->push_back(*v);
105  }
106  } else {
107  const MonoTypePtr& mty = u.substitute(mts[i]);
108 
109  if (!hasFreeVariables(mty)) {
110  findMatches(u, this->d.moveTo(mty, p), mts, i + 1, out);
111  } else {
112  typename tmdata::KeyPointSeq kps;
113  this->d.keyPointsAt(&kps, p);
114 
115  for (typename tmdata::KeyPointSeq::const_iterator kp = kps.begin(); kp != kps.end(); ++kp) {
116  try {
117  MonoTypeUnifier pu = u;
118  mgu(mty, kp->first, &pu);
119  findMatches(pu, kp->second, mts, i + 1, out);
120  } catch (std::exception& ex) {
121  }
122  }
123  }
124  }
125  }
126 
127  void findBidiMatches(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i, std::vector<V>* out) const {
128  if (p == 0) return;
129 
130  if (i == mts.size()) {
131  if (const V* v = this->d.valueAt(p)) {
132  out->push_back(*v);
133  }
134  } else {
135  const MonoTypePtr& mty = u.substitute(mts[i]);
136 
137  typename tmdata::KeyPointSeq kps;
138  this->d.keyPointsAt(&kps, p);
139 
140  for (typename tmdata::KeyPointSeq::const_iterator kp = kps.begin(); kp != kps.end(); ++kp) {
141  try {
142  MonoTypeUnifier pu = u;
143  mgu(mty, u.substitute(kp->first), &pu);
144  findBidiMatches(pu, kp->second, mts, i + 1, out);
145  } catch (std::exception& ex) {
146  }
147  }
148  }
149  }
150 
151  void findMatches(typename tmdata::point_t p, const MaybePathPoints& path, size_t i, std::vector<V>* out) const {
152  if (p == 0) return;
153 
154  if (i == path.size()) {
155  if (const V* v = this->d.valueAt(p)) {
156  out->push_back(*v);
157  }
158  } else {
159  // do we need an exact match or any point here?
160  if (const MonoTypePtr* mt = get<MonoTypePtr>(path[i])) {
161  findMatches(this->d.moveTo(*mt, p), path, i + 1, out);
162  } else {
163  typename tmdata::KeyPointSeq kps;
164  this->d.keyPointsAt(&kps, p);
165 
166  for (auto kp : kps) {
167  findMatches(kp.second, path, i + 1, out);
168  }
169  }
170  }
171  }
172  };
173 
174 }
175 
176 #endif
177 
tmdata d
Definition: typemap.H:68
bool hasMatch(const TEnvPtr &tenv, const MonoTypes &mts) const
Definition: typemap.H:45
V * valueAt(point_t base) const
Definition: trie.H:143
MonoTypePtr substitute(const MonoTypePtr &)
Definition: typeinf.C:341
void findBidiMatches(MonoTypeUnifier &u, typename tmdata::point_t p, const MonoTypes &mts, size_t i, std::vector< V > *out) const
Definition: typemap.H:127
std::map< MonoTypePtr, V, MonoTypeLT > type
Definition: typemap.H:20
Definition: boot.H:7
void insert(const MonoTypes &mts, const V &v)
Definition: typemap.H:32
void keyPointsAt(KeyPointSeq *kps, point_t base) const
Definition: trie.H:135
MonoType::ptr MonoTypePtr
Definition: type.H:71
void findMatches(MonoTypeUnifier &u, typename tmdata::point_t p, const MonoTypes &mts, size_t i, std::vector< V > *out) const
Definition: typemap.H:99
V * lookup(const MonoTypes &mts) const
Definition: typemap.H:36
void bidimatches(const TEnvPtr &tenv, const MonoTypes &mts, std::vector< V > *out) const
Definition: typemap.H:57
std::vector< V > values() const
Definition: typemap.H:40
Definition: typeinf.H:29
void find(const MaybePathPoints &path, std::vector< V > *out) const
Definition: typemap.H:63
std::vector< MaybePathPoint > MaybePathPoints
Definition: typemap.H:26
void matches(const TEnvPtr &tenv, const MonoTypes &mts, std::vector< V > *out) const
Definition: typemap.H:51
variant< unit, MonoTypePtr > MaybePathPoint
Definition: typemap.H:25
std::shared_ptr< TEnv > TEnvPtr
Definition: type.H:80
bool hasMatch(MonoTypeUnifier &u, typename tmdata::point_t p, const MonoTypes &mts, size_t i) const
Definition: typemap.H:70
void findMatches(typename tmdata::point_t p, const MaybePathPoints &path, size_t i, std::vector< V > *out) const
Definition: typemap.H:151
Definition: typemap.H:30
Definition: typemap.H:19
point_t moveTo(const K &k, point_t base) const
Definition: trie.H:112
#define out
Definition: netio.H:19
Definition: variant.H:103
bool hasFreeVariables(const QualTypePtr &)
Definition: type.C:1858
bool operator()(const MonoTypePtr &, const MonoTypePtr &) const
Definition: typemap.C:187
Definition: typemap.H:17
Definition: typemap.H:13
std::vector< MonoTypePtr > MonoTypes
Definition: type.H:72
std::vector< KeyPoint > KeyPointSeq
Definition: trie.H:134
prefix_tree< MonoTypePtr, V, MTyMap > tmdata
Definition: typemap.H:67
void mgu(const ExprPtr &, const ExprPtr &, MonoTypeUnifier *)
Definition: typeinf.C:959