A simple scripting language in C++
Ferenc Szontágh
2025-04-18 bda9d46916db19c0c005fd7e70ae67a01b3f94bf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef NAMESPACE_MANAGER_H
#define NAMESPACE_MANAGER_H
#include <functional>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
 
class Namespace {
  public:
    Namespace(const std::string & name = "", Namespace * parent = nullptr) : name_(name), parent_(parent) {}
 
    /**
    * @brief Add a child namespace to the current namespace.
    * @param name Name of the child namespace.
    */
    Namespace * addChild(const std::string & name) {
        auto it = children_.find(name);
        if (it == children_.end()) {
            children_[name] = std::make_unique<Namespace>(name, this);
        }
        return children_[name].get();
    }
 
    /**
    * @brief Get the child namespace by name.
    * @param name Name of the child namespace.
    * @return The child namespace
    */
    Namespace * getChild(const std::string & name) const {
        auto it = children_.find(name);
        return it != children_.end() ? it->second.get() : nullptr;
    }
 
    /**
    * @brief Get the child namespace by name.
    * @param name Name of the child namespace.
    * @return The child namespace
    */
    Namespace * getOrCreate(const std::string & fullName) {
        auto        parts   = split(fullName, '.');
        Namespace * current = this;
        for (const auto & part : parts) {
            current = current->addChild(part);
        }
        return current;
    }
 
    /**
    * @brief Get the parent namespace.
    * @return The parent namespace.
    */
    Namespace * getParent() const { return parent_; }
 
    std::string toString() const {
        if (!parent_ || name_.empty()) {
            return name_;
        }
        return parent_->toString() + "." + name_;
    }
 
    void traverse(const std::function<void(const Namespace &)>& visitor) const {
        visitor(*this);
        for (const auto & [_, child] : children_) {
            child->traverse(visitor);
        }
    }
 
    const std::string & getName() const { return name_; }
 
  private:
    std::string                                       name_;
    Namespace *                                       parent_;
    std::map<std::string, std::unique_ptr<Namespace>> children_;
 
    static std::vector<std::string> split(const std::string & str, char delimiter) {
        std::stringstream        ss(str);
        std::string              part;
        std::vector<std::string> result;
        while (std::getline(ss, part, delimiter)) {
            result.push_back(part);
        }
        return result;
    }
};
 
class NamespaceManager {
  public:
    static NamespaceManager & instance() {
        static NamespaceManager instance_;
        return instance_;
    }
 
    /**
     * @brief Constructor for NamespaceManager.
     * @param name Name of the namespace.
     * @param parent Parent namespace.
     */
    NamespaceManager() : root_(""), currentNamespace_(&root_) {}
 
    /**
    * @brief Get or create a namespace by full name.
    * @param fullName Full name of the namespace.
    * @return The namespace object.
    */
    Namespace * getOrCreate(const std::string & fullName) { return root_.getOrCreate(fullName); }
 
    /**
    * @brief Set the current namespace.
    * @param fullName Full name of the namespace.
    */
    void setCurrent(const std::string & fullName) {
        Namespace * ns = root_.getOrCreate(fullName);
        if (ns) {
            currentNamespace_ = ns;
        } else {
            currentNamespace_ = &root_;  // fallback
        }
    }
 
    /**
    * @brief Get the current namespace.
    * @return The current namespace object.
    */
    Namespace * getCurrent() const { return currentNamespace_; }
 
    /**
    * @brief Reset the current namespace.
    */
    void resetCurrent() { currentNamespace_ = &root_; }
 
    /**
    * @brief Traverse the namespace tree.
    * @param visitor A function to visit each namespace.
    */
    void traverse(const std::function<void(const Namespace &)>& visitor) const { root_.traverse(visitor); }
 
  private:
    Namespace   root_;
    Namespace * currentNamespace_;
};
 
#endif  // NAMESPACE_MANAGER_H