#pragma once #include "ContextAPI.h" #include "ast/ExternalModule.h" #include "ast/TypeSignature.h" #include "ast/Module.h" #include #include #include #include #include struct PrimitiveSymbol { std::string name; std::string kind; // function, type, constant, variable std::string source; // builtin, import, user std::string library; }; class PrimitivesRegistry { public: void setRoot(Module* root) { root_ = root; } void setLanguage(const std::string& lang) { language_ = lang; } std::vector getAvailableFunctions(const std::string& nodeId = "") { return collect(nodeId, "function"); } std::vector getAvailableTypes(const std::string& nodeId = "") { return collect(nodeId, "type"); } std::vector getAvailableConstants(const std::string& nodeId = "") { return collect(nodeId, "constant"); } private: std::vector collect(const std::string& nodeId, const std::string& filterKind) { std::vector out; std::unordered_set seen; // Builtins for (const auto& sym : builtinsForLanguage(language_)) { if (!filterKind.empty() && sym.kind != filterKind) continue; if (seen.insert(sym.name).second) out.push_back(sym); } // Imported libraries if (root_) { for (auto* modNode : root_->getChildren("externalModules")) { auto* ext = static_cast(modNode); for (auto* sigNode : ext->getChildren("signatures")) { auto* sig = static_cast(sigNode); PrimitiveSymbol ps; ps.name = sig->name; ps.source = "import"; ps.library = ext->name; ps.kind = classifySymbol(ps.name); if (!filterKind.empty() && ps.kind != filterKind) continue; if (seen.insert(ps.name).second) out.push_back(ps); } } } // User-defined (ContextAPI) if (root_ && !nodeId.empty()) { ContextAPI ctx; ctx.setRoot(root_); auto symbols = ctx.getInScopeSymbols(nodeId); for (const auto& sym : symbols) { PrimitiveSymbol ps; ps.name = sym.name; ps.source = "user"; ps.library.clear(); ps.kind = sym.kind == "variable" ? "constant" : sym.kind; if (!filterKind.empty() && ps.kind != filterKind) continue; if (seen.insert(ps.name).second) out.push_back(ps); } } return out; } static std::string classifySymbol(const std::string& name) { if (!name.empty() && std::isupper((unsigned char)name[0])) return "type"; if (std::all_of(name.begin(), name.end(), [](unsigned char c) { return std::isupper(c) || c == '_' || std::isdigit(c); })) { return "constant"; } return "function"; } static std::vector builtinsForLanguage(const std::string& lang) { std::vector out; auto add = [&](const std::string& name, const std::string& kind) { out.push_back({name, kind, "builtin", ""}); }; if (lang == "python") { add("print", "function"); add("len", "function"); add("list", "type"); add("dict", "type"); add("True", "constant"); add("False", "constant"); } else if (lang == "javascript" || lang == "typescript") { add("console.log", "function"); add("Array", "type"); add("Promise", "type"); add("undefined", "constant"); } else if (lang == "cpp") { add("std::vector", "type"); add("std::string", "type"); add("printf", "function"); add("nullptr", "constant"); } else if (lang == "rust") { add("println!", "function"); add("Vec", "type"); add("Option", "type"); } else if (lang == "go") { add("fmt.Println", "function"); add("string", "type"); add("nil", "constant"); } else if (lang == "elisp") { add("message", "function"); add("require", "function"); add("use-package", "function"); add("t", "constant"); add("nil", "constant"); } return out; } Module* root_ = nullptr; std::string language_ = "python"; };