cplusplus2x.Examples/C++20/scanner/ETL/symbol.hpp
Source: cplusplus2x.Examples/C++20/scanner/ETL/symbol.hpp
#ifndef _SYMBOL_H_
#define _SYMBOL_H_
#include "ast.hpp"
#include <optional>
#include <string>
#include <unordered_map>
namespace symbol {
struct Symbol {
std::string name;
std::string value;
int ivalue;
double dvalue;
ast::VarType vtype;
bool allocated;
Symbol() : name{}, value{}, ivalue{}, dvalue{}, vtype{ast::VarType::NUMBER}, allocated{false} {}
Symbol(const Symbol &s) : name{s.name}, value{s.value}, ivalue{s.ivalue}, dvalue{s.dvalue}, vtype{s.vtype}, allocated{s.allocated} {}
Symbol &operator=(const Symbol &s) {
name = s.name;
value = s.value;
ivalue = s.ivalue;
dvalue = s.dvalue;
return *this;
}
};
struct Function {
std::string functionName;
std::vector<ast::VarType> argTypes; // Store argument types
ast::VarType vtype;
size_t num_args;
Function() = default;
Function(const std::string &name, const std::vector<ast::VarType> &args, ast::VarType retType, size_t num)
: functionName(name), argTypes(args), vtype(retType), num_args{num} {}
};
class SymbolTable {
public:
SymbolTable() {
symbols["global"] = std::unordered_map<std::string, Symbol>();
cur_scope = &symbols["global"]; // Initialize cur_scope to point to the global scope
}
bool is_there(const std::string &sym) {
auto it = cur_scope->find(sym);
return (it != cur_scope->end());
}
void enter(const std::string &sym) {
if (cur_scope->find(sym) == cur_scope->end())
(*cur_scope)[sym] = Symbol();
}
void enterScope(const std::string &fname) {
if (symbols.find(fname) == symbols.end()) {
symbols[fname] = std::unordered_map<std::string, Symbol>();
}
cur_scope = &symbols[fname];
}
void exitScope() {
cur_scope = &symbols["global"];
}
void enterFunction(const std::string &s, const std::vector<ast::VarType> &args, ast::VarType vtype) {
if (func.find(s) == func.end()) {
func[s] = Function(s, args, vtype, args.size());
}
}
std::optional<Function *> lookupFunc(const std::string &f) {
auto it = func.find(f);
if (it != func.end()) {
return &it->second;
}
return std::nullopt;
}
std::optional<Symbol *> lookup(const std::string &sym) {
auto it = cur_scope->find(sym);
if (it != cur_scope->end())
return &it->second;
return std::nullopt;
}
int getCurrentScopeSize() const {
return cur_scope->size();
}
auto getSymbols() {
return symbols;
}
// New method to check if a symbol is in memory
bool isInMemory(const std::string &sym) const {
return cur_scope->find(sym) != cur_scope->end();
}
void print() {
for (auto &i : symbols) {
for (auto &z : i.second) {
std::cout << z.second.name << " : " << z.second.value << " -> " << static_cast<int>(z.second.vtype) << "\n";
}
}
}
auto getTable() {
return symbols;
}
private:
std::unordered_map<std::string, std::unordered_map<std::string, Symbol>> symbols;
std::unordered_map<std::string, Function> func;
std::unordered_map<std::string, Symbol> *cur_scope; // Pointer to the current scope
};
} // namespace symbol
#endif