X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/7f83e1b208e87e3808b268303bb633a8fda203f5..c4231c6faf4e1b4650b075c641b0bb8c053739e4:/src/find.h diff --git a/src/find.h b/src/find.h index a969bae..3342536 100644 --- a/src/find.h +++ b/src/find.h @@ -18,104 +18,174 @@ opt find(const std::vector & ts, std::function f) return nullopt; } -opt findFunction( - const Program & p, - const std::string & name, - const std::vector & namespacePrefixes) +template +opt findPtr(const std::vector & ts, std::function f) { - if (namespacePrefixes.empty()) - { - return find(p.functions, [&](Function f) { return f.name == name; }); - } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); + for (int i = 0; i < ts.size(); i++) + if (f(ts[i])) + return &((T *)ts.data())[i]; + return nullopt; +} - if (!n.has_value()) - return nullopt; +std::optional< + std::tuple< + std::shared_ptr, + std::vector>> +getContext(std::shared_ptr ctx, const std::vector & namespacePrefix) +{ + auto result = ctx; - for (int i = 1; i < namespacePrefixes.size(); i++) + for (auto name : namespacePrefix) { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) + auto newResult = find(result->namespaces, [&](Namespace n) { return n.name == name; }); + if (newResult.has_value()) + { + result = newResult->ctx; + } + else + { return nullopt; + } + } + + std::vector namespaces; + for (auto it = result; it != nullptr; it = it->parent) + { + if (it->name.has_value()) + { + namespaces.insert(namespaces.begin(), it->name.value()); + } + else if (it->parent != nullptr) + { + namespaces.clear(); + break; + } } - return find(n.value().functions, [&](Function f) { return f.name == name; }); + return std::make_tuple(result, namespaces); } -opt findStruct( - const Program & p, + + +opt>> findFunction( 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 n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } - - 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++) + return nullopt; +} + +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]; }); + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } + } + return nullopt; +} - if (!n.has_value()) - return nullopt; + + +opt>> findStruct( + const std::string & name, + const std::vector & namespacePrefix, + std::shared_ptr ctx) +{ + for (auto it = ctx; it != nullptr; it = it->parent) + { + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } - return find(n.value().structs, [&](Struct s) { return s.name == name; }); + return nullopt; } -opt findVariable( - const Program & p, +opt>> findStructPtr( 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()) + for (auto it = ctx; it != nullptr; it = it->parent) { - return find(p.ctx->variables, [&](Variable v) { return v.name == name; }); + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } - - 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++) + return nullopt; +} + + + +opt>> findVariable( + 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 n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } - return find(n.value().ctx->variables, [&](Variable v) { return v.name == name; }); + return nullopt; } -opt findStructMethod( - const Program & p, + + +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, - 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 findPtr>(s.methods, [&](Function f) { return f.name == name; }); } -opt findStructMember( - const Program & p, - TypeInfo ti, - const std::string & name) +opt> findStructMember( + const std::string & name, + const Struct & s) +{ + return find>(s.members, [&](Variable v) { return v.name == 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