]> gitweb.ps.run Git - toc/blob - src/find.h
add comments, fix struct/function lookup
[toc] / src / find.h
1 #pragma once\r
2 \r
3 #include "repr.h"\r
4 #include "typeInfo.h"\r
5 \r
6 #include <functional>\r
7 #include <optional>\r
8 \r
9 template<typename T>\r
10 using opt = std::optional<T>;\r
11 \r
12 template<typename T>\r
13 opt<T> find(const std::vector<T> & ts, std::function<bool(T)> f)\r
14 {\r
15   for (auto t : ts)\r
16     if (f(t))\r
17       return t;\r
18   return nullopt;\r
19 }\r
20 \r
21 template<typename T>\r
22 opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)\r
23 {\r
24   for (int i = 0; i < ts.size(); i++)\r
25     if (f(ts[i]))\r
26       return &((T *)ts.data())[i];\r
27   return nullopt;\r
28 }\r
29 \r
30 std::optional<\r
31   std::tuple<\r
32     std::shared_ptr<Context>,\r
33     std::vector<std::string>>>\r
34 getContext(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)\r
35 {\r
36   auto result = ctx;\r
37 \r
38   for (auto name : namespacePrefix)\r
39   {\r
40     auto newResult = find<Namespace>(result->namespaces, [&](Namespace n) { return n.name == name; });\r
41     if (newResult.has_value())\r
42     {\r
43       result = newResult->ctx;\r
44     }\r
45     else\r
46     {\r
47       return nullopt;\r
48     }\r
49   }\r
50 \r
51   std::vector<std::string> namespaces;\r
52   for (auto it = result; it != nullptr; it = it->parent)\r
53   {\r
54     if (it->name.has_value())\r
55     {\r
56       namespaces.insert(namespaces.begin(), it->name.value());\r
57     }\r
58     else if (it->parent != nullptr)\r
59     {\r
60       namespaces.clear();\r
61       break;\r
62     }\r
63   }\r
64 \r
65   return std::make_tuple(result, namespaces);\r
66 }\r
67 \r
68 \r
69 \r
70 opt<std::tuple<Function, std::vector<std::string>>> findFunction(\r
71   const std::string & name,\r
72   const std::vector<std::string> & namespacePrefix,\r
73   std::shared_ptr<Context> ctx)\r
74 {\r
75   for (auto it = ctx; it != nullptr; it = it->parent)\r
76   {\r
77     auto n = getContext(it, namespacePrefix);\r
78     if (n.has_value())\r
79     {\r
80       auto x = find<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });\r
81       if (x.has_value())\r
82         return std::make_tuple(x.value(), std::get<1>(*n));\r
83     }\r
84   }\r
85   return nullopt;\r
86 }\r
87 \r
88 opt<std::tuple<Function *, std::vector<std::string>>> findFunctionPtr(\r
89   const std::string & name,\r
90   const std::vector<std::string> & namespacePrefix,\r
91   std::shared_ptr<Context> ctx)\r
92 {\r
93   for (auto it = ctx; it != nullptr; it = it->parent)\r
94   {\r
95     auto n = getContext(it, namespacePrefix);\r
96     if (n.has_value())\r
97     {\r
98       auto x = findPtr<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });\r
99       if (x.has_value())\r
100         return std::make_tuple(x.value(), std::get<1>(*n));\r
101     }\r
102   }\r
103   return nullopt;\r
104 }\r
105 \r
106 \r
107 \r
108 opt<std::tuple<Struct, std::vector<std::string>>> findStruct(\r
109   const std::string & name,\r
110   const std::vector<std::string> & namespacePrefix,\r
111   std::shared_ptr<Context> ctx)\r
112 {\r
113   for (auto it = ctx; it != nullptr; it = it->parent)\r
114   {\r
115     auto n = getContext(it, namespacePrefix);\r
116     if (n.has_value())\r
117     {\r
118       auto x = find<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });\r
119       if (x.has_value())\r
120         return std::make_tuple(x.value(), std::get<1>(*n));\r
121     }\r
122   }\r
123   return nullopt;\r
124 }\r
125 \r
126 opt<std::tuple<Struct *, std::vector<std::string>>> findStructPtr(\r
127   const std::string & name,\r
128   const std::vector<std::string> & namespacePrefix,\r
129   std::shared_ptr<Context> ctx)\r
130 {\r
131   for (auto it = ctx; it != nullptr; it = it->parent)\r
132   {\r
133     auto n = getContext(it, namespacePrefix);\r
134     if (n.has_value())\r
135     {\r
136       auto x = findPtr<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });\r
137       if (x.has_value())\r
138         return std::make_tuple(x.value(), std::get<1>(*n));\r
139     }\r
140   }\r
141   return nullopt;\r
142 }\r
143 \r
144 \r
145 \r
146 opt<std::tuple<Variable, std::vector<std::string>>> findVariable(\r
147   const std::string & name,\r
148   const std::vector<std::string> & namespacePrefix,\r
149   std::shared_ptr<Context> ctx)\r
150 {\r
151   for (auto it = ctx; it != nullptr; it = it->parent)\r
152   {\r
153     auto n = getContext(it, namespacePrefix);\r
154     if (n.has_value())\r
155     {\r
156       auto x = find<Variable>(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; });\r
157       if (x.has_value())\r
158         return std::make_tuple(x.value(), std::get<1>(*n));\r
159     }\r
160   }\r
161   return nullopt;\r
162 }\r
163 \r
164 \r
165 \r
166 opt<StructMember<Function>> findStructMethod(\r
167   const std::string & name,\r
168   const Struct & s)\r
169 {\r
170   return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
171 }\r
172 opt<StructMember<Function> *> findStructMethodPtr(\r
173   const std::string & name,\r
174   const Struct & s)\r
175 {\r
176   return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
177 }\r
178 \r
179 opt<StructMember<Variable>> findStructMember(\r
180   const std::string & name,\r
181   const Struct & s)\r
182 {\r
183   return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
184 }\r
185 \r
186 opt<StructMember<Variable> *> findStructMemberPtr(\r
187   const std::string & name,\r
188   const Struct & s)\r
189 {\r
190   return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
191 }