#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; std::vector namespaces = { n.value() }; 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; namespaces.push_back(n.value()); } for (int i = namespaces.size()-1; i >= 0; i--) { auto f = find(namespaces[i].functions, [&](Function f) { return f.name == name; }); if (f.has_value()) return f.value(); } return find(p.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, std::shared_ptr ctx) { auto it = ctx; while (it != nullptr) { auto v = find(it->variables, [&](Variable v) { return v.name == name; }); if (v.has_value()) return v; it = it->parent; } return nullopt; } 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; }); }