#pragma once #include "repr.h" #include "typeInfo.h" #include #include template using opt = std::optional; template opt find(const std::vector & ts, std::function f) { for (auto t : ts) if (f(t)) return t; return nullopt; } opt findFunction( const Program & p, const std::string & name, const std::vector & namespacePrefixes) { 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]; }); 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]; }); if (!n.has_value()) return nullopt; } return find(n.value().functions, [&](Function f) { return f.name == name; }); } opt findStruct( const Program & p, const std::string & name, const std::vector & namespacePrefixes) { if (namespacePrefixes.empty()) { return find(p.structs, [&](Struct s) { return s.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++) { n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); if (!n.has_value()) return nullopt; } return find(n.value().structs, [&](Struct s) { return s.name == name; }); } opt findVariable( const Program & p, const std::string & name, const std::vector & namespacePrefixes) { 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++) { n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); if (!n.has_value()) return nullopt; } return find(n.value().ctx->variables, [&](Variable v) { return v.name == name; }); } opt findStructMethod( const Program & p, const std::string & name, TypeInfo ti) { 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; }); } opt findStructMember( const Program & p, TypeInfo ti, const std::string & name) { 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; }); }