]> gitweb.ps.run Git - toc/blob - src/find.h
pre change
[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 opt<Function> findFunction(\r
22   const Program & p,\r
23   const std::string & name,\r
24   const std::vector<std::string> & namespacePrefixes)\r
25 {\r
26   if (namespacePrefixes.empty())\r
27   {\r
28     return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
29   }\r
30   \r
31   auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
32 \r
33   if (!n.has_value())\r
34     return nullopt;\r
35 \r
36   for (int i = 1; i < namespacePrefixes.size(); i++)\r
37   {\r
38     n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
39     \r
40     if (!n.has_value())\r
41       return nullopt;\r
42   }\r
43 \r
44   return find<Function>(n.value().functions, [&](Function f) { return f.name == name; });\r
45 }\r
46 \r
47 opt<Struct> findStruct(\r
48   const Program & p,\r
49   const std::string & name,\r
50   const std::vector<std::string> & namespacePrefixes)\r
51 {\r
52   if (namespacePrefixes.empty())\r
53   {\r
54     return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });\r
55   }\r
56   \r
57   auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
58   \r
59   if (!n.has_value())\r
60     return nullopt;\r
61     \r
62   for (int i = 1; i < namespacePrefixes.size(); i++)\r
63   {\r
64     n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
65 \r
66     if (!n.has_value())\r
67       return nullopt;\r
68   }\r
69   return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
70 }\r
71 \r
72 opt<Variable> findVariable(\r
73   const Program & p,\r
74   const std::string & name,\r
75   const std::vector<std::string> & namespacePrefixes)\r
76 {\r
77   for (auto n : namespacePrefixes)\r
78     std::cout << n << std::endl;\r
79   if (namespacePrefixes.empty())\r
80   {\r
81     return find<Variable>(p.ctx->variables, [&](Variable v) { return v.name == name; });\r
82   }\r
83   \r
84   auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
85   \r
86   if (!n.has_value())\r
87     return nullopt;\r
88       \r
89   for (int i = 1; i < namespacePrefixes.size(); i++)\r
90   {\r
91     n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
92     \r
93     if (!n.has_value())\r
94       return nullopt;\r
95   }\r
96   return find<Variable>(n.value().ctx->variables, [&](Variable v) { return v.name == name; });\r
97 }\r
98 \r
99 opt<Function> findStructMethod(\r
100   const Program & p,\r
101   const std::string & name,\r
102   TypeInfo ti)\r
103 {\r
104   if (!ti.isStruct)\r
105     return nullopt;\r
106   auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
107   if (!s.has_value())\r
108     return nullopt;\r
109   return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
110 }\r
111 \r
112 opt<Variable> findStructMember(\r
113   const Program & p,\r
114   TypeInfo ti,\r
115   const std::string & name)\r
116 {\r
117   auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
118   if (!s.has_value())\r
119     return nullopt;\r
120   return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });\r
121 }