4 #include "typeInfo.h"
\r
6 #include <functional>
\r
10 using opt = std::optional<T>;
\r
11 template<typename ... Ts>
\r
12 using tup = std::tuple<Ts ...>;
\r
14 // find an item in a vector by predicate
\r
15 template<typename T>
\r
16 opt<T> find(const std::vector<T> & ts, std::function<bool(T)> f)
\r
24 // same as above but return pointer into raw array held by vector
\r
25 template<typename T>
\r
26 opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)
\r
28 for (int i = 0; i < ts.size(); i++)
\r
30 return &((T *)ts.data())[i];
\r
35 std::shared_ptr<Context>,
\r
36 std::vector<std::string>>>
\r
37 getContext(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)
\r
39 // try finding a continuos series of namespaces in a given context
\r
42 for (auto name : namespacePrefix)
\r
44 auto newResult = find<Namespace>(result->namespaces, [&](Namespace n) { return n.name == name; });
\r
45 if (newResult.has_value())
\r
47 result = newResult->ctx;
\r
55 // if the found context is the end of a series of namespaces, also return
\r
56 // a vector of namespace names
\r
57 std::vector<std::string> namespaces;
\r
58 for (auto it = result; it != nullptr; it = it->parent)
\r
60 if (it->name.has_value())
\r
62 namespaces.insert(namespaces.begin(), it->name.value());
\r
64 else if (it->parent != nullptr)
\r
71 return std::make_tuple(result, namespaces);
\r
74 // all of the following functions work the same way,
\r
75 // walking up the context hierarchy until the global context.
\r
76 // return the first found instance that matches provided criteria
\r
77 // theres also a variant to get a pointer instead for functions and
\r
78 // structs used for generic instantiation
\r
80 opt<tup<Function, std::vector<std::string>>> findFunction(
\r
81 const std::string & name,
\r
82 const std::vector<std::string> & namespacePrefix,
\r
83 std::shared_ptr<Context> ctx)
\r
85 for (auto it = ctx; it != nullptr; it = it->parent)
\r
87 auto n = getContext(it, namespacePrefix);
\r
90 auto x = find<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });
\r
92 return std::make_tuple(x.value(), std::get<1>(*n));
\r
98 opt<tup<Function *, std::vector<std::string>>> findFunctionPtr(
\r
99 const std::string & name,
\r
100 const std::vector<std::string> & namespacePrefix,
\r
101 std::shared_ptr<Context> ctx)
\r
103 for (auto it = ctx; it != nullptr; it = it->parent)
\r
105 auto n = getContext(it, namespacePrefix);
\r
108 auto x = findPtr<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });
\r
110 return std::make_tuple(x.value(), std::get<1>(*n));
\r
118 opt<tup<Struct, std::vector<std::string>>> findStruct(
\r
119 const std::string & name,
\r
120 const std::vector<std::string> & namespacePrefix,
\r
121 std::shared_ptr<Context> ctx)
\r
123 for (auto it = ctx; it != nullptr; it = it->parent)
\r
125 auto n = getContext(it, namespacePrefix);
\r
128 auto x = find<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });
\r
130 return std::make_tuple(x.value(), std::get<1>(*n));
\r
136 opt<tup<Struct *, std::vector<std::string>>> findStructPtr(
\r
137 const std::string & name,
\r
138 const std::vector<std::string> & namespacePrefix,
\r
139 std::shared_ptr<Context> ctx)
\r
141 for (auto it = ctx; it != nullptr; it = it->parent)
\r
143 auto n = getContext(it, namespacePrefix);
\r
146 auto x = findPtr<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });
\r
148 return std::make_tuple(x.value(), std::get<1>(*n));
\r
156 opt<tup<Variable, std::vector<std::string>>> findVariable(
\r
157 const std::string & name,
\r
158 const std::vector<std::string> & namespacePrefix,
\r
159 std::shared_ptr<Context> ctx)
\r
161 for (auto it = ctx; it != nullptr; it = it->parent)
\r
163 auto n = getContext(it, namespacePrefix);
\r
166 auto x = find<Variable>(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; });
\r
168 return std::make_tuple(x.value(), std::get<1>(*n));
\r
176 // find struct members and pointer variants
\r
178 opt<StructMember<Function>> findStructMethod(
\r
179 const std::string & name,
\r
182 return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });
\r
184 opt<StructMember<Function> *> findStructMethodPtr(
\r
185 const std::string & name,
\r
188 return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });
\r
191 opt<StructMember<Variable>> findStructMember(
\r
192 const std::string & name,
\r
195 return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });
\r
198 opt<StructMember<Variable> *> findStructMemberPtr(
\r
199 const std::string & name,
\r
202 return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });
\r