ArkScript
A small, fast, functional and scripting language for video games
Optimizer.cpp
Go to the documentation of this file.
2
3namespace Ark::internal
4{
5 Optimizer::Optimizer(uint16_t options) noexcept :
6 m_options(options)
7 {}
8
9 void Optimizer::feed(const Node& ast)
10 {
11 m_ast = ast;
12
15 }
16
17 const Node& Optimizer::ast() const noexcept
18 {
19 return m_ast;
20 }
21
22 void Optimizer::throwOptimizerError(const std::string& message, const Node& node)
23 {
24 throw OptimizerError(makeNodeBasedErrorCtx(message, node));
25 }
26
28 {
29 // do not handle non-list nodes
31 return;
32
33 runOnGlobalScopeVars(m_ast, [this](Node& node, Node& parent [[maybe_unused]], int idx [[maybe_unused]]) {
34 m_sym_appearances[node.constList()[1].string()] = 0;
35 });
37
38 // logic: remove piece of code with only 1 reference, if they aren't function calls
39 runOnGlobalScopeVars(m_ast, [this](Node& node, Node& parent, int idx) {
40 std::string name = node.constList()[1].string();
41 // a variable was only declared and never used
42 if (m_sym_appearances.find(name) != m_sym_appearances.end() && m_sym_appearances[name] == 1 && parent.list()[idx].list()[2].nodeType() != NodeType::List)
43 parent.list().erase(parent.list().begin() + idx); // erase the node from the list
44 });
45 }
46
47 void Optimizer::runOnGlobalScopeVars(Node& node, const std::function<void(Node&, Node&, int)>& func)
48 {
49 int i = static_cast<int>(node.constList().size());
50 // iterate only on the first level, using reverse iterators to avoid copy-delete-move to nowhere
51 for (auto it = node.list().rbegin(); it != node.list().rend(); ++it)
52 {
53 i--;
54
55 if (it->constList().size() > 0 && it->constList()[0].nodeType() == NodeType::Keyword)
56 {
57 Keyword kw = it->constList()[0].keyword();
58
59 // eliminate nested begin blocks
60 if (kw == Keyword::Begin)
61 {
62 runOnGlobalScopeVars(*it, func);
63 // skip let/ mut detection
64 continue;
65 }
66 // check if it's a let/mut declaration
67 else if (kw == Keyword::Let || kw == Keyword::Mut)
68 func(*it, node, i);
69 }
70 }
71 }
72
74 {
75 if (node.nodeType() == NodeType::Symbol || node.nodeType() == NodeType::Capture)
76 {
77 std::string name = node.string();
78 // check if it's the name of something declared in global scope
79 if (m_sym_appearances.find(name) != m_sym_appearances.end())
80 m_sym_appearances[name]++;
81 }
82 else if (node.nodeType() == NodeType::List)
83 {
84 // iterate over children
85 for (std::size_t i = 0, end = node.constList().size(); i != end; ++i)
86 countOccurences(node.list()[i]);
87 }
88 }
89}
Optimizes a given ArkScript AST.
OptimizerError thrown by the AST optimizer.
Definition: Exceptions.hpp:107
A node of an Abstract Syntax Tree for ArkScript.
Definition: Node.hpp:29
NodeType nodeType() const noexcept
Return the node type.
Definition: Node.cpp:126
const std::string & string() const noexcept
Return the string held by the value (if the node type allows it)
Definition: Node.cpp:92
const std::vector< Node > & constList() const noexcept
Return the list of sub-nodes held by the node.
Definition: Node.cpp:119
std::vector< Node > & list() noexcept
Return the list of sub-nodes held by the node.
Definition: Node.cpp:114
void feed(const Node &ast)
Send the AST to the optimizer, then run the different optimization strategies on it.
Definition: Optimizer.cpp:9
void throwOptimizerError(const std::string &message, const Node &node)
Generate a fancy error message.
Definition: Optimizer.cpp:22
void remove_unused()
Iterate over the AST and remove unused top level functions and constants.
Definition: Optimizer.cpp:27
const Node & ast() const noexcept
Returns the modified AST.
Definition: Optimizer.cpp:17
Optimizer(uint16_t options) noexcept
Construct a new Optimizer.
Definition: Optimizer.cpp:5
void countOccurences(Node &node)
Count the occurences of each symbol in the AST, recursively.
Definition: Optimizer.cpp:73
void runOnGlobalScopeVars(Node &node, const std::function< void(Node &, Node &, int)> &func)
Run a given functor on the global scope symbols.
Definition: Optimizer.cpp:47
std::unordered_map< std::string, unsigned > m_sym_appearances
Definition: Optimizer.hpp:57
std::string makeNodeBasedErrorCtx(const std::string &message, const Node &node)
Construct an error message based on a given node.
Keyword
The different keywords available.
Definition: Common.hpp:59
constexpr uint16_t FeatureRemoveUnusedVars
Definition: Constants.hpp:48