87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
#ifndef SAQUT_SYMBOL_TABLE
|
||
#define SAQUT_SYMBOL_TABLE
|
||
|
||
#include <memory>
|
||
#include <vector>
|
||
#include <unordered_map>
|
||
#include "symbol/scope.hpp"
|
||
|
||
class SymbolTable {
|
||
public:
|
||
SymbolTable() {
|
||
global_ = newScope(nullptr);
|
||
current_ = global_;
|
||
}
|
||
|
||
Scope* global() { return global_; }
|
||
Scope* current() { return current_; }
|
||
|
||
Scope* enterScope() {
|
||
current_ = newScope(current_);
|
||
return current_;
|
||
}
|
||
|
||
void exitScope() {
|
||
if (current_->parent) current_ = current_->parent;
|
||
}
|
||
|
||
// current scope'ta tanımla; duplicate → nullptr döner
|
||
Symbol* define(const std::string& name, SymbolKind k, Type t, SourceLocation loc) {
|
||
auto s = std::make_unique<Symbol>();
|
||
s->name = name;
|
||
s->kind = k;
|
||
s->type = std::move(t);
|
||
s->definitionLoc = loc;
|
||
Symbol* raw = s.get();
|
||
if (!current_->defineLocal(raw)) return nullptr; // duplicate
|
||
pool_.push_back(std::move(s));
|
||
return raw;
|
||
}
|
||
|
||
Symbol* resolve(const std::string& n) { return current_->resolve(n); }
|
||
|
||
void addReference(Symbol* s, SourceLocation loc) {
|
||
if (s) s->references.push_back(loc);
|
||
}
|
||
|
||
std::vector<Symbol*> allSymbols() const {
|
||
std::vector<Symbol*> result;
|
||
result.reserve(pool_.size());
|
||
for (const auto& s : pool_) result.push_back(s.get());
|
||
return result;
|
||
}
|
||
|
||
// Struct alan düzeni: struct adı → sıralı [(alan adı, tip)] listesi
|
||
// Sembol toplayıcı doldurur; tip denetleyici ve IR üreteci okur.
|
||
std::unordered_map<std::string, std::vector<std::pair<std::string, Type>>> structLayouts;
|
||
|
||
int getFieldIndex(const std::string& structName, const std::string& fieldName) const {
|
||
auto it = structLayouts.find(structName);
|
||
if (it == structLayouts.end()) return -1;
|
||
for (int i = 0; i < (int)it->second.size(); i++)
|
||
if (it->second[i].first == fieldName) return i;
|
||
return -1;
|
||
}
|
||
|
||
Type getFieldType(const std::string& structName, const std::string& fieldName) const {
|
||
auto it = structLayouts.find(structName);
|
||
if (it == structLayouts.end()) return Type::error();
|
||
for (auto& p : it->second)
|
||
if (p.first == fieldName) return p.second;
|
||
return Type::error();
|
||
}
|
||
|
||
private:
|
||
Scope* newScope(Scope* p) {
|
||
scopes_.push_back(std::make_unique<Scope>(p));
|
||
return scopes_.back().get();
|
||
}
|
||
|
||
std::vector<std::unique_ptr<Scope>> scopes_;
|
||
std::vector<std::unique_ptr<Symbol>> pool_;
|
||
Scope* global_ = nullptr;
|
||
Scope* current_ = nullptr;
|
||
};
|
||
|
||
#endif // SAQUT_SYMBOL_TABLE
|