X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/7f83e1b208e87e3808b268303bb633a8fda203f5..17860defa84c6d8bc0e8bc088a7e09361f17db07:/src/find.h diff --git a/src/find.h b/src/find.h index a969bae..ea3ae22 100644 --- a/src/find.h +++ b/src/find.h @@ -18,104 +18,136 @@ opt find(const std::vector & ts, std::function f) return nullopt; } +template +opt findPtr(const std::vector & ts, std::function f) +{ + for (int i = 0; i < ts.size(); i++) + if (f(ts[i])) + return &((T *)ts.data())[i]; + return nullopt; +} + +bool checkNamespace(std::shared_ptr ctx, const std::vector & namespacePrefix) +{ + + bool prefixMatches = true; + + auto nIt = ctx; + for (int i = namespacePrefix.size() - 1; i >= 0; i--) + { + const std::string & prefix = namespacePrefix[i]; + if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix) + { + prefixMatches = false; + break; + } + nIt = nIt->parent; + } + + return prefixMatches; +} + + + opt findFunction( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - if (namespacePrefixes.empty()) + for (auto it = ctx; it != nullptr; it = it->parent) { - return find(p.functions, [&](Function f) { return f.name == name; }); + auto f = find(it->functions, [&](Function f) { return f.name == name; }); + if (f.has_value() && checkNamespace(it, namespacePrefix)) + return f; } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; + return nullopt; +} - for (int i = 1; i < namespacePrefixes.size(); i++) +opt findFunctionPtr( + const std::string & name, + const std::vector & namespacePrefix, + std::shared_ptr ctx) +{ + for (auto it = ctx; it != nullptr; it = it->parent) { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; + auto f = findPtr(it->functions, [&](Function f) { return f.name == name; }); + if (f.has_value() && checkNamespace(it, namespacePrefix)) + return f; } - - return find(n.value().functions, [&](Function f) { return f.name == name; }); + return nullopt; } + + opt findStruct( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - if (namespacePrefixes.empty()) + for (auto it = ctx; it != nullptr; it = it->parent) { - return find(p.structs, [&](Struct s) { return s.name == name; }); + auto s = find(it->structs, [&](Struct s) { return s.name == name; }); + if (s.has_value() && checkNamespace(it, namespacePrefix)) + return s; } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - for (int i = 1; i < namespacePrefixes.size(); i++) - { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); + return nullopt; +} - if (!n.has_value()) - return nullopt; +opt findStructPtr( + const std::string & name, + const std::vector & namespacePrefix, + std::shared_ptr ctx) +{ + for (auto it = ctx; it != nullptr; it = it->parent) + { + auto s = findPtr(it->structs, [&](Struct s) { return s.name == name; }); + if (s.has_value() && checkNamespace(it, namespacePrefix)) + return s; } - return find(n.value().structs, [&](Struct s) { return s.name == name; }); + return nullopt; } + + opt findVariable( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - for (auto n : namespacePrefixes) - std::cout << n << std::endl; - if (namespacePrefixes.empty()) - { - return find(p.ctx->variables, [&](Variable v) { return v.name == name; }); - } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - for (int i = 1; i < namespacePrefixes.size(); i++) + for (auto it = ctx; it != nullptr; it = it->parent) { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; + auto v = find(it->variables, [&](Variable v) { return v.name == name; }); + if (v.has_value() && checkNamespace(it, namespacePrefix)) + return v; } - return find(n.value().ctx->variables, [&](Variable v) { return v.name == name; }); + return nullopt; +} + + + +opt> findStructMethod( + const std::string & name, + const Struct & s) +{ + return find>(s.methods, [&](Function f) { return f.name == name; }); +} +opt *> findStructMethodPtr( + const std::string & name, + const Struct & s) +{ + return findPtr>(s.methods, [&](Function f) { return f.name == name; }); } -opt findStructMethod( - const Program & p, +opt> findStructMember( const std::string & name, - TypeInfo ti) + const Struct & s) { - if (!ti.isStruct) - return nullopt; - auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes); - if (!s.has_value()) - return nullopt; - return find>(s.value().methods, [&](Function f) { return f.name == name; }); + return find>(s.members, [&](Variable v) { return v.name == name; }); } -opt findStructMember( - const Program & p, - TypeInfo ti, - const std::string & name) +opt *> findStructMemberPtr( + const std::string & name, + const Struct & s) { - auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes); - if (!s.has_value()) - return nullopt; - return find>(s.value().members, [&](Variable v) { return v.name == name; }); + return findPtr>(s.members, [&](Variable v) { return v.name == name; }); } \ No newline at end of file