From ba9a9199d01b0fdd4bf9a54914f8058bf71f30c5 Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Thu, 17 Apr 2025 16:03:01 +0000
Subject: [PATCH] unary and binary operations

---
 src/Symbols/SymbolContainer.hpp |  136 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 113 insertions(+), 23 deletions(-)

diff --git a/src/Symbols/SymbolContainer.hpp b/src/Symbols/SymbolContainer.hpp
index 1985c50..c0bb814 100644
--- a/src/Symbols/SymbolContainer.hpp
+++ b/src/Symbols/SymbolContainer.hpp
@@ -1,51 +1,141 @@
-// SymbolContainer.hpp
 #ifndef SYMBOL_CONTAINER_HPP
 #define SYMBOL_CONTAINER_HPP
 
+#include <memory>
+#include <stdexcept>
+#include <unordered_map>
+
 #include "SymbolTable.hpp"
+
+#define NSMGR Symbols::SymbolContainer::instance()
 
 namespace Symbols {
 
 class SymbolContainer {
-    std::shared_ptr<SymbolTable> globalScope_;
-    std::shared_ptr<SymbolTable> currentScope_;
+    std::unordered_map<std::string, std::shared_ptr<SymbolTable>> scopes_;
+    std::string                                                   currentScope_  = "global";
+    std::string                                                   previousScope_ = "global";
 
-public:
-    SymbolContainer() {
-        globalScope_ = std::make_shared<SymbolTable>();
-        currentScope_ = globalScope_;
+  public:
+    static SymbolContainer * instance() {
+        static SymbolContainer instance_;
+        return &instance_;
     }
 
-    void enterScope() {
-        currentScope_ = std::make_shared<SymbolTable>(currentScope_);
+    explicit SymbolContainer(const std::string & default_scope_name = "global") { create(default_scope_name); }
+
+    // --- Scope management ---
+
+    void create(const std::string & name) {
+        scopes_[name]  = std::make_shared<SymbolTable>();
+        previousScope_ = currentScope_;
+        currentScope_  = name;
     }
 
-    void leaveScope() {
-        if (currentScope_->getParent()) {
-            currentScope_ = currentScope_->getParent();
+    void enter(const std::string & name) {
+        if (scopes_.contains(name)) {
+            previousScope_ = currentScope_;
+            currentScope_  = name;
+        } else {
+            throw std::runtime_error("Scope does not exist: " + name);
         }
     }
 
-    void define(const std::string& ns, const SymbolPtr& symbol) {
-        currentScope_->define(ns, symbol);
+    void enterPreviousScope() { currentScope_ = previousScope_; }
+
+    [[nodiscard]] std::string currentScopeName() const { return currentScope_; }
+
+    std::vector<std::string> getScopeNames() const {
+        std::vector<std::string> result;
+        result.reserve(scopes_.size());
+        for (const auto & [scopeName, _] : scopes_) {
+            result.push_back(scopeName);
+        }
+        return result;
     }
 
-    SymbolPtr resolve(const std::string& ns, const std::string& name) const {
-        return currentScope_->get(ns, name);
+    // --- Symbol operations ---
+
+    std::string add(const SymbolPtr & symbol) {
+        const std::string ns = getNamespaceForSymbol(symbol);
+        scopes_[currentScope_]->define(ns, symbol);
+        return ns;
     }
 
-    bool exists(const std::string& ns, const std::string& name) const {
-        return currentScope_->exists(ns, name);
+    std::vector<std::string> getNameSpaces(const std::string & scopeName) const {
+        std::vector<std::string> result;
+        auto                     it = scopes_.find(scopeName);
+        if (it != scopes_.end()) {
+            return it->second->listNSs();
+        }
+        return result;
     }
 
-    std::vector<SymbolPtr> listNamespace(const std::string& ns) const {
-        return currentScope_->listAll(ns);
+    std::vector<SymbolPtr> getAll(const std::string & ns = "") const {
+        std::vector<SymbolPtr> result;
+        for (const auto & [_, table] : scopes_) {
+            auto symbols = ns.empty() ? table->listAll() : table->listAll(ns);
+            result.insert(result.end(), symbols.begin(), symbols.end());
+        }
+        return result;
     }
 
-    std::shared_ptr<SymbolTable> getGlobalScope() const { return globalScope_; }
-    std::shared_ptr<SymbolTable> getCurrentScope() const { return currentScope_; }
+    bool exists(const std::string & name, std::string fullNamespace = "") const {
+        if (fullNamespace.empty()) {
+            fullNamespace = currentScope_;
+        }
+
+        for (const auto & [_, table] : scopes_) {
+            if (table->exists(fullNamespace, name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    SymbolPtr get(const std::string & fullNamespace, const std::string & name) const {
+        for (const auto & [_, table] : scopes_) {
+            auto sym = table->get(fullNamespace, name);
+            if (sym) {
+                return sym;
+            }
+        }
+        return nullptr;
+    }
+
+    static std::string dump() {
+        std::string result = "";
+
+        std::cout << "\n--- Defined Scopes ---" << '\n';
+        for (const auto & scope_name : instance()->getScopeNames()) {
+            result += scope_name + '\n';
+            for (const auto & sname : instance()->getNameSpaces(scope_name)) {
+                result += "\t -" + sname + '\n';
+                for (const auto & symbol : instance()->getAll(sname)) {
+                    result += symbol->dump() + '\n';
+                }
+            }
+        }
+        return result;
+    }
+
+  private:
+    std::string getNamespaceForSymbol(const SymbolPtr & symbol) const {
+        std::string base = symbol->context().empty() ? currentScope_ : symbol->context();
+
+        switch (symbol->type()) {
+            case Symbols::Kind::Variable:
+                return base + ".variables";
+            case Symbols::Kind::Function:
+                return base + ".functions";
+            case Symbols::Kind::Constant:
+                return base + ".constants";
+            default:
+                return base + ".others";
+        }
+    }
 };
 
-} // namespace Symbols
+}  // namespace Symbols
 
 #endif

--
Gitblit v1.9.3