]> gitweb.ps.run Git - toc/blob - src/find.h
ea3ae2227b89169d99e5b74fa039b1ab53a6889a
[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 bool checkNamespace(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)\r
31 {\r
32   \r
33     bool prefixMatches = true;\r
34 \r
35     auto nIt = ctx;\r
36     for (int i = namespacePrefix.size() - 1; i >= 0; i--)\r
37     {\r
38       const std::string & prefix = namespacePrefix[i];\r
39       if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix)\r
40       {\r
41         prefixMatches = false;\r
42         break;\r
43       }\r
44       nIt = nIt->parent;\r
45     }\r
46 \r
47     return prefixMatches;\r
48 }\r
49 \r
50 \r
51 \r
52 opt<Function> findFunction(\r
53   const std::string & name,\r
54   const std::vector<std::string> & namespacePrefix,\r
55   std::shared_ptr<Context> ctx)\r
56 {\r
57   for (auto it = ctx; it != nullptr; it = it->parent)\r
58   {\r
59     auto f = find<Function>(it->functions, [&](Function f) { return f.name == name; });\r
60     if (f.has_value() && checkNamespace(it, namespacePrefix))\r
61       return f;\r
62   }\r
63   return nullopt;\r
64 }\r
65 \r
66 opt<Function *> findFunctionPtr(\r
67   const std::string & name,\r
68   const std::vector<std::string> & namespacePrefix,\r
69   std::shared_ptr<Context> ctx)\r
70 {\r
71   for (auto it = ctx; it != nullptr; it = it->parent)\r
72   {\r
73     auto f = findPtr<Function>(it->functions, [&](Function f) { return f.name == name; });\r
74     if (f.has_value() && checkNamespace(it, namespacePrefix))\r
75       return f;\r
76   }\r
77   return nullopt;\r
78 }\r
79 \r
80 \r
81 \r
82 opt<Struct> findStruct(\r
83   const std::string & name,\r
84   const std::vector<std::string> & namespacePrefix,\r
85   std::shared_ptr<Context> ctx)\r
86 {\r
87   for (auto it = ctx; it != nullptr; it = it->parent)\r
88   {\r
89     auto s = find<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
90     if (s.has_value() && checkNamespace(it, namespacePrefix))\r
91       return s;\r
92   }\r
93   return nullopt;\r
94 }\r
95 \r
96 opt<Struct *> findStructPtr(\r
97   const std::string & name,\r
98   const std::vector<std::string> & namespacePrefix,\r
99   std::shared_ptr<Context> ctx)\r
100 {\r
101   for (auto it = ctx; it != nullptr; it = it->parent)\r
102   {\r
103     auto s = findPtr<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
104     if (s.has_value() && checkNamespace(it, namespacePrefix))\r
105       return s;\r
106   }\r
107   return nullopt;\r
108 }\r
109 \r
110 \r
111 \r
112 opt<Variable> findVariable(\r
113   const std::string & name,\r
114   const std::vector<std::string> & namespacePrefix,\r
115   std::shared_ptr<Context> ctx)\r
116 {\r
117   for (auto it = ctx; it != nullptr; it = it->parent)\r
118   {\r
119     auto v = find<Variable>(it->variables, [&](Variable v) { return v.name == name; });\r
120     if (v.has_value() && checkNamespace(it, namespacePrefix))\r
121       return v;\r
122   }\r
123   return nullopt;\r
124 }\r
125 \r
126 \r
127 \r
128 opt<StructMember<Function>> findStructMethod(\r
129   const std::string & name,\r
130   const Struct & s)\r
131 {\r
132   return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
133 }\r
134 opt<StructMember<Function> *> findStructMethodPtr(\r
135   const std::string & name,\r
136   const Struct & s)\r
137 {\r
138   return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
139 }\r
140 \r
141 opt<StructMember<Variable>> findStructMember(\r
142   const std::string & name,\r
143   const Struct & s)\r
144 {\r
145   return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
146 }\r
147 \r
148 opt<StructMember<Variable> *> findStructMemberPtr(\r
149   const std::string & name,\r
150   const Struct & s)\r
151 {\r
152   return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
153 }