ArkScript
A small, fast, functional and scripting language for video games
ScopeResolver.hpp
Go to the documentation of this file.
1/**
2 * @file ScopeResolver.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief Handle scope resolution at compile time
5 * @date 2024-11-30
6 *
7 * @copyright Copyright (c) 2024-2025
8 *
9 */
10
11#ifndef ARK_COMPILER_NAMERESOLUTION_SCOPERESOLVER_HPP
12#define ARK_COMPILER_NAMERESOLUTION_SCOPERESOLVER_HPP
13
14#include <string>
15#include <optional>
16#include <memory>
17#include <vector>
18#include <utility>
19
21
22namespace Ark::internal
23{
25 {
26 public:
27 /**
28 * @brief Create a ScopeResolver
29 * @details Kickstart by create a default global scope
30 */
32
33 ScopeResolver(const ScopeResolver&) = delete;
37
38 /**
39 * @brief Create a new scope
40 */
41 void createNew();
42
43 /**
44 * @brief Remove the last scope
45 */
46 void removeLastScope();
47
48 /**
49 * @brief Create a new namespace scope
50 * @param name
51 * @param with_prefix
52 * @param is_glob
53 * @param symbols
54 */
55 void createNewNamespace(const std::string& name, bool with_prefix, bool is_glob, const std::vector<std::string>& symbols);
56
57 /**
58 * @brief Register a Declaration in the current (last) scope
59 * @param name
60 * @param is_mutable
61 * @return std::string the fully qualified name assigned by the scope
62 */
63 std::string registerInCurrent(const std::string& name, bool is_mutable);
64
65 /**
66 * @brief Save the last scope as a namespace, by attaching it to the nearest namespace scope
67 * @details Also handle removing the scope from the scope pile.
68 */
70
71 /**
72 * @brief Checks the scopes in reverse order for 'name' and returns its mutability status
73 * @param name
74 * @return std::nullopt if the Declaration could not be found
75 * @return true if immutable
76 * @return false if mutable
77 */
78 [[nodiscard]] std::optional<bool> isImmutable(const std::string& name) const;
79
80 /**
81 * @brief Checks if any scope has 'name', in reverse order
82 * @param name
83 * @return
84 */
85 [[nodiscard]] bool isRegistered(const std::string& name) const;
86
87 /**
88 * @brief Checks if 'name' is in the current scope
89 *
90 * @param name
91 * @return
92 */
93 [[nodiscard]] bool isInScope(const std::string& name) const;
94
95 /**
96 * @brief Get a FQN from a variable name in the nearest scope it is declared in
97 *
98 * @param name
99 * @return std::string
100 */
101 [[nodiscard]] std::string getFullyQualifiedNameInNearestScope(const std::string& name) const;
102
103 /**
104 * @brief Checks if a name can be fully qualified (allows only unprefixed names to be resolved by glob namespaces or inside their own namespace)
105 *
106 * @param name
107 * @return std::pair<bool, std::string> if the name can be fully qualified, first element is true ; second element is the FQN
108 */
109 [[nodiscard]] std::pair<bool, std::string> canFullyQualifyName(const std::string& name);
110
111 /**
112 * @brief Return a non-owning raw pointer to the current scope
113 *
114 * @return StaticScope* non-owning pointer to the current scope
115 * @return nullptr if there are no scope
116 */
117 [[nodiscard]] StaticScope* currentScope() const;
118
119 private:
120 std::vector<std::unique_ptr<StaticScope>> m_scopes;
121 };
122}
123
124#endif // ARK_COMPILER_NAMERESOLUTION_SCOPERESOLVER_HPP
Static scopes (for functions, loops) and namespace scopes (for packages) definitions,...
ScopeResolver & operator=(ScopeResolver &&)=default
ScopeResolver & operator=(const ScopeResolver &)=delete
std::string registerInCurrent(const std::string &name, bool is_mutable)
Register a Declaration in the current (last) scope.
ScopeResolver()
Create a ScopeResolver.
void createNewNamespace(const std::string &name, bool with_prefix, bool is_glob, const std::vector< std::string > &symbols)
Create a new namespace scope.
void saveNamespaceAndRemove()
Save the last scope as a namespace, by attaching it to the nearest namespace scope.
std::string getFullyQualifiedNameInNearestScope(const std::string &name) const
Get a FQN from a variable name in the nearest scope it is declared in.
bool isRegistered(const std::string &name) const
Checks if any scope has 'name', in reverse order.
void createNew()
Create a new scope.
std::vector< std::unique_ptr< StaticScope > > m_scopes
ScopeResolver(ScopeResolver &&)=default
ScopeResolver(const ScopeResolver &)=delete
StaticScope * currentScope() const
Return a non-owning raw pointer to the current scope.
bool isInScope(const std::string &name) const
Checks if 'name' is in the current scope.
void removeLastScope()
Remove the last scope.
std::optional< bool > isImmutable(const std::string &name) const
Checks the scopes in reverse order for 'name' and returns its mutability status.
std::pair< bool, std::string > canFullyQualifyName(const std::string &name)
Checks if a name can be fully qualified (allows only unprefixed names to be resolved by glob namespac...