ArkScript
A small, fast, functional and scripting language for video games
StaticScope.hpp
Go to the documentation of this file.
1/**
2 * @file StaticScope.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief
5 * @version 0.1
6 * @date 2024-11-30
7 *
8 * @copyright Copyright (c) 2024
9 *
10 */
11
12#ifndef ARK_COMPILER_NAMERESOLUTION_STATICSCOPE_HPP
13#define ARK_COMPILER_NAMERESOLUTION_STATICSCOPE_HPP
14
15#include <string>
16#include <optional>
17#include <memory>
18#include <vector>
19#include <ranges>
20#include <unordered_set>
21
22namespace Ark::internal
23{
25 {
26 std::string name; ///< End name, can be modified to be hidden
27 std::string original_name; ///< Original name, with the prefix, without hidden namespaces
29
30 bool operator==(const Declaration& other) const = default;
31 };
32}
33
34template <>
35struct std::hash<Ark::internal::Declaration>
36{
37 inline size_t operator()(const Ark::internal::Declaration& x) const noexcept
38 {
39 return std::hash<std::string> {}(x.original_name);
40 }
41};
42
43namespace Ark::internal
44{
46 {
47 public:
48 virtual ~StaticScope() = default;
49
50 /**
51 * @brief Add a Declaration to the scope, given a mutability status
52 * @param name
53 * @param is_mutable
54 */
55 virtual std::string add(const std::string& name, bool is_mutable);
56
57 /**
58 * @brief Try to return a Declaration from this scope with a given name.
59 * @param name
60 * @param extensive_lookup unused in StaticScope
61 * @return std::optional<Declaration> std::nullopt if the Declaration isn't in scope
62 */
63 [[nodiscard]] virtual std::optional<Declaration> get(const std::string& name, bool extensive_lookup);
64
65 /**
66 * @brief Given a Declaration name, compute its fully qualified name
67 * @param name
68 * @return std::string fully qualified name in the scope
69 */
70 [[nodiscard]] virtual std::string fullyQualifiedName(const std::string& name) const;
71
72 /**
73 * @brief Save a namespace scope to help with lookup
74 *
75 * @return true if the scope was saved, on NamespaceScope
76 * @return false on StaticScope
77 */
78 virtual bool saveNamespace(std::unique_ptr<StaticScope>&);
79
80 [[nodiscard]] virtual bool isNamespace() const;
81 [[nodiscard]] inline virtual bool withPrefix() const { return false; }
82 [[nodiscard]] inline virtual bool isGlob() const { return false; }
83 [[nodiscard]] inline virtual std::string prefix() const { return ""; }
84 [[nodiscard]] inline virtual bool hasSymbol(const std::string&) const { return false; }
85 [[nodiscard]] inline virtual bool recursiveHasSymbol(const std::string&) const { return false; }
86
87 private:
88 std::unordered_set<Declaration> m_vars {};
89 };
90
91 class NamespaceScope final : public StaticScope
92 {
93 public:
94 NamespaceScope(std::string name, bool with_prefix, bool is_glob, const std::vector<std::string>& symbols);
95
96 /**
97 * @brief Add a Declaration to the scope, given a mutability status
98 * @param name
99 * @param is_mutable
100 */
101 std::string add(const std::string& name, bool is_mutable) override;
102
103 /**
104 * @brief Try to return a Declaration from this scope with a given name.
105 * @param name
106 * @param extensive_lookup if true, use the additional saved namespaces
107 * @return std::optional<Declaration> std::nullopt if the Declaration isn't in scope
108 */
109 [[nodiscard]] std::optional<Declaration> get(const std::string& name, bool extensive_lookup) override;
110
111 /**
112 * @brief Given a Declaration name, compute its fully qualified name
113 * @param name
114 * @return std::string fully qualified name in the namespace
115 */
116 [[nodiscard]] std::string fullyQualifiedName(const std::string& name) const override;
117
118 /**
119 * @brief Save a namespace scope to help with lookup
120 *
121 * @return true if the scope was saved, on NamespaceScope
122 * @return false on StaticScope
123 */
124 bool saveNamespace(std::unique_ptr<StaticScope>&) override;
125
126 [[nodiscard]] bool isNamespace() const override;
127 [[nodiscard]] inline bool withPrefix() const override { return m_with_prefix; }
128 [[nodiscard]] inline bool isGlob() const override { return m_is_glob; }
129 [[nodiscard]] inline std::string prefix() const override { return m_namespace; }
130 [[nodiscard]] inline bool hasSymbol(const std::string& symbol) const override { return std::ranges::find(m_symbols, symbol) != m_symbols.end(); }
131 [[nodiscard]] inline bool recursiveHasSymbol(const std::string& symbol) const override
132 {
133 if (hasSymbol(symbol))
134 return true;
135 for (const auto& saved_scope : m_additional_namespaces)
136 {
137 if (saved_scope->recursiveHasSymbol(symbol))
138 return true;
139 }
140 return false;
141 }
142
143 private:
144 std::string m_namespace;
147 std::vector<std::string> m_symbols;
148 std::unordered_set<Declaration> m_vars {};
149 std::vector<std::unique_ptr<StaticScope>> m_additional_namespaces;
150 };
151}
152
153#endif // ARK_COMPILER_NAMERESOLUTION_STATICSCOPE_HPP
bool recursiveHasSymbol(const std::string &symbol) const override
bool saveNamespace(std::unique_ptr< StaticScope > &) override
Save a namespace scope to help with lookup.
std::string fullyQualifiedName(const std::string &name) const override
Given a Declaration name, compute its fully qualified name.
std::unordered_set< Declaration > m_vars
bool isGlob() const override
bool hasSymbol(const std::string &symbol) const override
std::optional< Declaration > get(const std::string &name, bool extensive_lookup) override
Try to return a Declaration from this scope with a given name.
bool withPrefix() const override
bool isNamespace() const override
NamespaceScope(std::string name, bool with_prefix, bool is_glob, const std::vector< std::string > &symbols)
std::string prefix() const override
std::vector< std::string > m_symbols
std::string add(const std::string &name, bool is_mutable) override
Add a Declaration to the scope, given a mutability status.
std::vector< std::unique_ptr< StaticScope > > m_additional_namespaces
std::unordered_set< Declaration > m_vars
virtual bool withPrefix() const
virtual std::string prefix() const
virtual bool hasSymbol(const std::string &) const
virtual std::optional< Declaration > get(const std::string &name, bool extensive_lookup)
Try to return a Declaration from this scope with a given name.
virtual bool recursiveHasSymbol(const std::string &) const
virtual bool saveNamespace(std::unique_ptr< StaticScope > &)
Save a namespace scope to help with lookup.
virtual bool isNamespace() const
virtual std::string add(const std::string &name, bool is_mutable)
Add a Declaration to the scope, given a mutability status.
virtual ~StaticScope()=default
virtual bool isGlob() const
virtual std::string fullyQualifiedName(const std::string &name) const
Given a Declaration name, compute its fully qualified name.
std::string name
End name, can be modified to be hidden.
std::string original_name
Original name, with the prefix, without hidden namespaces.
bool operator==(const Declaration &other) const =default
size_t operator()(const Ark::internal::Declaration &x) const noexcept