#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; } 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 std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { auto f = find(it->functions, [&](Function f) { return f.name == name; }); if (f.has_value() && checkNamespace(it, namespacePrefix)) return f; } 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) { auto f = findPtr(it->functions, [&](Function f) { return f.name == name; }); if (f.has_value() && checkNamespace(it, namespacePrefix)) return f; } 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 s = find(it->structs, [&](Struct s) { return s.name == name; }); if (s.has_value() && checkNamespace(it, namespacePrefix)) return s; } 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 nullopt; } opt findVariable( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { auto v = find(it->variables, [&](Variable v) { return v.name == name; }); if (v.has_value() && checkNamespace(it, namespacePrefix)) return v; } 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> 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) { return findPtr>(s.members, [&](Variable v) { return v.name == name; }); }