return nullopt;\r
}\r
\r
-opt<Function> findFunction(\r
- const Program & p,\r
- const std::string & name,\r
- const std::vector<std::string> & namespacePrefixes)\r
+template<typename T>\r
+opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)\r
{\r
- if (namespacePrefixes.empty())\r
- {\r
- return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
- }\r
- \r
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
-\r
- if (!n.has_value())\r
- return nullopt;\r
+ for (int i = 0; i < ts.size(); i++)\r
+ if (f(ts[i]))\r
+ return &((T *)ts.data())[i];\r
+ return nullopt;\r
+}\r
\r
- std::vector<Namespace> namespaces = { n.value() };\r
+std::optional<\r
+ std::tuple<\r
+ std::shared_ptr<Context>,\r
+ std::vector<std::string>>>\r
+getContext(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)\r
+{\r
+ auto result = ctx;\r
\r
- for (int i = 1; i < namespacePrefixes.size(); i++)\r
+ for (auto name : namespacePrefix)\r
{\r
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
- \r
- if (!n.has_value())\r
+ auto newResult = find<Namespace>(result->namespaces, [&](Namespace n) { return n.name == name; });\r
+ if (newResult.has_value())\r
+ {\r
+ result = newResult->ctx;\r
+ }\r
+ else\r
+ {\r
return nullopt;\r
-\r
- namespaces.push_back(n.value());\r
+ }\r
}\r
\r
- for (int i = namespaces.size()-1; i >= 0; i--)\r
+ std::vector<std::string> namespaces;\r
+ for (auto it = result; it != nullptr; it = it->parent)\r
{\r
- auto f = find<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });\r
- if (f.has_value())\r
- return f.value();\r
+ if (it->name.has_value())\r
+ {\r
+ namespaces.insert(namespaces.begin(), it->name.value());\r
+ }\r
+ else if (it->parent != nullptr)\r
+ {\r
+ namespaces.clear();\r
+ break;\r
+ }\r
}\r
\r
- return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
+ return std::make_tuple(result, namespaces);\r
}\r
\r
-opt<Struct> findStruct(\r
- const Program & p,\r
+\r
+\r
+opt<std::tuple<Function, std::vector<std::string>>> findFunction(\r
const std::string & name,\r
- const std::vector<std::string> & namespacePrefixes)\r
+ const std::vector<std::string> & namespacePrefix,\r
+ std::shared_ptr<Context> ctx)\r
{\r
- if (namespacePrefixes.empty())\r
+ for (auto it = ctx; it != nullptr; it = it->parent)\r
{\r
- return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });\r
+ auto n = getContext(it, namespacePrefix);\r
+ if (n.has_value())\r
+ {\r
+ auto x = find<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });\r
+ if (x.has_value())\r
+ return std::make_tuple(x.value(), std::get<1>(*n));\r
+ }\r
}\r
- \r
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
- \r
- if (!n.has_value())\r
- return nullopt;\r
- \r
- for (int i = 1; i < namespacePrefixes.size(); i++)\r
+ return nullopt;\r
+}\r
+\r
+opt<std::tuple<Function *, std::vector<std::string>>> findFunctionPtr(\r
+ const std::string & name,\r
+ const std::vector<std::string> & namespacePrefix,\r
+ std::shared_ptr<Context> ctx)\r
+{\r
+ for (auto it = ctx; it != nullptr; it = it->parent)\r
{\r
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
+ auto n = getContext(it, namespacePrefix);\r
+ if (n.has_value())\r
+ {\r
+ auto x = findPtr<Function>(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; });\r
+ if (x.has_value())\r
+ return std::make_tuple(x.value(), std::get<1>(*n));\r
+ }\r
+ }\r
+ return nullopt;\r
+}\r
\r
- if (!n.has_value())\r
- return nullopt;\r
+\r
+\r
+opt<std::tuple<Struct, std::vector<std::string>>> findStruct(\r
+ const std::string & name,\r
+ const std::vector<std::string> & namespacePrefix,\r
+ std::shared_ptr<Context> ctx)\r
+{\r
+ for (auto it = ctx; it != nullptr; it = it->parent)\r
+ {\r
+ auto n = getContext(it, namespacePrefix);\r
+ if (n.has_value())\r
+ {\r
+ auto x = find<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });\r
+ if (x.has_value())\r
+ return std::make_tuple(x.value(), std::get<1>(*n));\r
+ }\r
+ }\r
+ return nullopt;\r
+}\r
+\r
+opt<std::tuple<Struct *, std::vector<std::string>>> findStructPtr(\r
+ const std::string & name,\r
+ const std::vector<std::string> & namespacePrefix,\r
+ std::shared_ptr<Context> ctx)\r
+{\r
+ for (auto it = ctx; it != nullptr; it = it->parent)\r
+ {\r
+ auto n = getContext(it, namespacePrefix);\r
+ if (n.has_value())\r
+ {\r
+ auto x = findPtr<Struct>(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; });\r
+ if (x.has_value())\r
+ return std::make_tuple(x.value(), std::get<1>(*n));\r
+ }\r
}\r
- return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
+ return nullopt;\r
}\r
\r
-opt<Variable> findVariable(\r
- const Program & p,\r
+\r
+\r
+opt<std::tuple<Variable, std::vector<std::string>>> findVariable(\r
const std::string & name,\r
+ const std::vector<std::string> & namespacePrefix,\r
std::shared_ptr<Context> ctx)\r
{\r
- auto it = ctx;\r
- while (it != nullptr)\r
+ for (auto it = ctx; it != nullptr; it = it->parent)\r
{\r
- auto v = find<Variable>(it->variables, [&](Variable v) { return v.name == name; });\r
- if (v.has_value())\r
- return v;\r
- it = it->parent;\r
+ auto n = getContext(it, namespacePrefix);\r
+ if (n.has_value())\r
+ {\r
+ auto x = find<Variable>(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; });\r
+ if (x.has_value())\r
+ return std::make_tuple(x.value(), std::get<1>(*n));\r
+ }\r
}\r
return nullopt;\r
}\r
\r
-opt<Function> findStructMethod(\r
- const Program & p,\r
+\r
+\r
+opt<StructMember<Function>> findStructMethod(\r
+ const std::string & name,\r
+ const Struct & s)\r
+{\r
+ return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
+}\r
+opt<StructMember<Function> *> findStructMethodPtr(\r
+ const std::string & name,\r
+ const Struct & s)\r
+{\r
+ return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
+}\r
+\r
+opt<StructMember<Variable>> findStructMember(\r
const std::string & name,\r
- TypeInfo ti)\r
+ const Struct & s)\r
{\r
- if (!ti.isStruct)\r
- return nullopt;\r
- auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
- if (!s.has_value())\r
- return nullopt;\r
- return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
+ return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
}\r
\r
-opt<Variable> findStructMember(\r
- const Program & p,\r
- TypeInfo ti,\r
- const std::string & name)\r
+opt<StructMember<Variable> *> findStructMemberPtr(\r
+ const std::string & name,\r
+ const Struct & s)\r
{\r
- auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
- if (!s.has_value())\r
- return nullopt;\r
- return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });\r
+ return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
}
\ No newline at end of file