]> gitweb.ps.run Git - toc/blobdiff - src/find.h
generic functions and structs
[toc] / src / find.h
index 1876a1e0a59c0c29459de0b41aea468a746bded6..fec540f1eee81853886fb7bf6009cd6403bf8495 100644 (file)
@@ -18,6 +18,15 @@ opt<T> find(const std::vector<T> & ts, std::function<bool(T)> f)
   return nullopt;\r
 }\r
 \r
+template<typename T>\r
+opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)\r
+{\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
 opt<Function> findFunction(\r
   const Program & p,\r
   const std::string & name,\r
@@ -55,6 +64,43 @@ opt<Function> findFunction(
   return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
 }\r
 \r
+opt<Function *> findFunctionPtr(\r
+  const Program & p,\r
+  const std::string & name,\r
+  const std::vector<std::string> & namespacePrefixes)\r
+{\r
+  if (namespacePrefixes.empty())\r
+  {\r
+    return findPtr<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
+\r
+  std::vector<Namespace> namespaces = { n.value() };\r
+\r
+  for (int i = 1; i < namespacePrefixes.size(); i++)\r
+  {\r
+    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
+    \r
+    if (!n.has_value())\r
+      return nullopt;\r
+\r
+    namespaces.push_back(n.value());\r
+  }\r
+\r
+  for (int i = namespaces.size()-1; i >= 0; i--)\r
+  {\r
+    auto f = findPtr<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });\r
+    if (f.has_value())\r
+      return f.value();\r
+  }\r
+\r
+  return findPtr<Function>(p.functions, [&](Function f) { return f.name == name; });\r
+}\r
+\r
 opt<Struct> findStruct(\r
   const Program & p,\r
   const std::string & name,\r
@@ -69,6 +115,8 @@ opt<Struct> findStruct(
   \r
   if (!n.has_value())\r
     return nullopt;\r
+\r
+  std::vector<Namespace> namespaces = { n.value() };\r
     \r
   for (int i = 1; i < namespacePrefixes.size(); i++)\r
   {\r
@@ -76,10 +124,57 @@ opt<Struct> findStruct(
 \r
     if (!n.has_value())\r
       return nullopt;\r
+\r
+    namespaces.push_back(n.value());\r
+  }\r
+\r
+  for (int i = namespaces.size()-1; i >= 0; i--)\r
+  {\r
+    auto f = find<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });\r
+    if (f.has_value())\r
+      return f.value();\r
   }\r
+\r
   return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
 }\r
 \r
+opt<Struct *> findStructPtr(\r
+  const Program & p,\r
+  const std::string & name,\r
+  const std::vector<std::string> & namespacePrefixes)\r
+{\r
+  if (namespacePrefixes.empty())\r
+  {\r
+    return findPtr<Struct>(p.structs, [&](Struct s) { return s.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
+\r
+  std::vector<Namespace> namespaces = { n.value() };\r
+    \r
+  for (int i = 1; i < namespacePrefixes.size(); i++)\r
+  {\r
+    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
+\r
+    if (!n.has_value())\r
+      return nullopt;\r
+\r
+    namespaces.push_back(n.value());\r
+  }\r
+\r
+  for (int i = namespaces.size()-1; i >= 0; i--)\r
+  {\r
+    auto f = findPtr<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });\r
+    if (f.has_value())\r
+      return f.value();\r
+  }\r
+\r
+  return findPtr<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
+}\r
+\r
 opt<Variable> findVariable(\r
   const Program & p,\r
   const std::string & name,\r
@@ -96,7 +191,7 @@ opt<Variable> findVariable(
   return nullopt;\r
 }\r
 \r
-opt<Function> findStructMethod(\r
+opt<StructMember<Function>> findStructMethod(\r
   const Program & p,\r
   const std::string & name,\r
   TypeInfo ti)\r
@@ -108,8 +203,20 @@ opt<Function> findStructMethod(
     return nullopt;\r
   return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
 }\r
+opt<StructMember<Function> *> findStructMethodPtr(\r
+  const Program & p,\r
+  const std::string & name,\r
+  TypeInfo ti)\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 findPtr<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
+}\r
 \r
-opt<Variable> findStructMember(\r
+opt<StructMember<Variable>> findStructMember(\r
   const Program & p,\r
   TypeInfo ti,\r
   const std::string & name)\r