134 lines
4.6 KiB
C++
134 lines
4.6 KiB
C++
#pragma once
|
|
#include "ContextAPI.h"
|
|
#include "ast/ExternalModule.h"
|
|
#include "ast/TypeSignature.h"
|
|
#include "ast/Module.h"
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_set>
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
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<PrimitiveSymbol> getAvailableFunctions(const std::string& nodeId = "") {
|
|
return collect(nodeId, "function");
|
|
}
|
|
|
|
std::vector<PrimitiveSymbol> getAvailableTypes(const std::string& nodeId = "") {
|
|
return collect(nodeId, "type");
|
|
}
|
|
|
|
std::vector<PrimitiveSymbol> getAvailableConstants(const std::string& nodeId = "") {
|
|
return collect(nodeId, "constant");
|
|
}
|
|
|
|
private:
|
|
std::vector<PrimitiveSymbol> collect(const std::string& nodeId,
|
|
const std::string& filterKind) {
|
|
std::vector<PrimitiveSymbol> out;
|
|
std::unordered_set<std::string> 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<ExternalModule*>(modNode);
|
|
for (auto* sigNode : ext->getChildren("signatures")) {
|
|
auto* sig = static_cast<TypeSignature*>(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<PrimitiveSymbol> builtinsForLanguage(const std::string& lang) {
|
|
std::vector<PrimitiveSymbol> 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("t", "constant");
|
|
add("nil", "constant");
|
|
}
|
|
return out;
|
|
}
|
|
|
|
Module* root_ = nullptr;
|
|
std::string language_ = "python";
|
|
};
|