]> gitweb.ps.run Git - toc/blobdiff - src/find.h
add comments, fix struct/function lookup
[toc] / src / find.h
index ea3ae2227b89169d99e5b74fa039b1ab53a6889a..3342536b1a05bfcc99bdd6396bb164c2a39e2889 100644 (file)
@@ -27,98 +27,136 @@ opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)
   return nullopt;\r
 }\r
 \r
-bool checkNamespace(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)\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
-  \r
-    bool prefixMatches = true;\r
+  auto result = ctx;\r
 \r
-    auto nIt = ctx;\r
-    for (int i = namespacePrefix.size() - 1; i >= 0; i--)\r
+  for (auto name : namespacePrefix)\r
+  {\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
-      const std::string & prefix = namespacePrefix[i];\r
-      if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix)\r
-      {\r
-        prefixMatches = false;\r
-        break;\r
-      }\r
-      nIt = nIt->parent;\r
+      return nullopt;\r
     }\r
+  }\r
+\r
+  std::vector<std::string> namespaces;\r
+  for (auto it = result; it != nullptr; it = it->parent)\r
+  {\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 prefixMatches;\r
+  return std::make_tuple(result, namespaces);\r
 }\r
 \r
 \r
 \r
-opt<Function> findFunction(\r
+opt<std::tuple<Function, std::vector<std::string>>> findFunction(\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 f = find<Function>(it->functions, [&](Function f) { return f.name == name; });\r
-    if (f.has_value() && checkNamespace(it, namespacePrefix))\r
-      return f;\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
   return nullopt;\r
 }\r
 \r
-opt<Function *> findFunctionPtr(\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
-    auto f = findPtr<Function>(it->functions, [&](Function f) { return f.name == name; });\r
-    if (f.has_value() && checkNamespace(it, namespacePrefix))\r
-      return f;\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
 \r
 \r
-opt<Struct> findStruct(\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 s = find<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
-    if (s.has_value() && checkNamespace(it, namespacePrefix))\r
-      return s;\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<Struct *> findStructPtr(\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 s = findPtr<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
-    if (s.has_value() && checkNamespace(it, namespacePrefix))\r
-      return s;\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 nullopt;\r
 }\r
 \r
 \r
 \r
-opt<Variable> findVariable(\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
   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() && checkNamespace(it, namespacePrefix))\r
-      return v;\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