ArkScript
A small, fast, functional and scripting language for video games
Processor.hpp
Go to the documentation of this file.
1/**
2 * @file Processor.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief Handles the macros and their expansion in ArkScript source code
5 * @version 0.6
6 * @date 2021-02-18
7 *
8 * @copyright Copyright (c) 2021
9 *
10 */
11
12#ifndef COMPILER_MACROS_PROCESSOR_HPP
13#define COMPILER_MACROS_PROCESSOR_HPP
14
19
20#include <unordered_map>
21#include <string>
22#include <cinttypes>
23
24namespace Ark::internal
25{
26 /**
27 * @brief The class handling the macros definitions and calls, given an AST
28 *
29 */
31 {
32 public:
33 /**
34 * @brief Construct a new Macro Processor object
35 *
36 * @param debug the debug level
37 * @param options the options flags
38 */
39 MacroProcessor(unsigned debug, uint16_t options) noexcept;
40
41 /**
42 * @brief Send the complete AST (after the inclusions and stuff), and work on it
43 *
44 * @param ast
45 */
46 void feed(const Node& ast);
47
48 /**
49 * @brief Return the modified AST
50 *
51 * @return Node&
52 */
53 const Node& ast() const noexcept;
54
55 friend class MacroExecutor;
56
57 private:
58 unsigned m_debug; ///< The debug level
59 uint16_t m_options;
60 Node m_ast; ///< The modified AST
61 std::vector<MacroScope> m_macros; ///< Handling macros in a scope fashion
63 std::vector<std::string> m_predefined_macros; ///< Already existing macros, non-keywords, non-builtins
64 std::unordered_map<std::string, Node> m_defined_functions;
65
66 /**
67 * @brief Find the nearest macro matching a given name
68 *
69 * @param name
70 * @return const Node* nullptr if no macro was found
71 */
72 const Node* findNearestMacro(const std::string& name) const;
73
74 /**
75 * @brief Find the nearest macro matching a given name and delete it
76 *
77 * @param name
78 */
79 void deleteNearestMacro(const std::string& name);
80
81 /**
82 * @brief Check if a given symbol is a predefined macro or not
83 *
84 * @param symbol
85 * @return true
86 * @return false
87 */
88 bool isPredefined(const std::string& symbol);
89
90 /**
91 * @brief Recursively apply macros on a given node
92 *
93 * @param node
94 */
95 void recurApply(Node& node);
96
97 /**
98 * @brief Check if a given node is a list node, and starts with a Begin
99 *
100 * @param node
101 * @return true if it starts with a Begin
102 * @return false
103 */
104 bool hadBegin(const Node& node);
105
106 /**
107 * @brief Remove a begin block added by a macro
108 *
109 * @param node
110 * @param i
111 */
112 void removeBegin(Node& node, std::size_t& i);
113
114 /**
115 * @brief Check if a node can be evaluated at compile time
116 *
117 * @param node
118 * @return true
119 * @return false
120 */
121 bool isConstEval(const Node& node) const;
122
123 /**
124 * @brief Registers macros based on their type
125 * @details Validate macros and register them by their name
126 *
127 * @param node A node of type Macro
128 */
129 void registerMacro(Node& node);
130
131 /**
132 * @brief Registers a function definition node
133 *
134 * @param node
135 */
136 void registerFuncDef(Node& node);
137
138 /**
139 * @brief Register macros in scopes and apply them as needed
140 *
141 * @param node node on which to operate
142 * @param depth
143 */
144 void process(Node& node, unsigned depth);
145
146 /**
147 * @brief Apply a macro on a given node
148 *
149 * @param node
150 * @return true if a macro was applied
151 * @return false
152 */
153 bool applyMacro(Node& node);
154
155 /**
156 * @brief Unify a target node with a given map symbol => replacement node, recursively
157 *
158 * @param map
159 * @param target
160 * @param parent
161 * @param index position of target inside parent->list()
162 */
163 void unify(const std::unordered_map<std::string, Node>& map, Node& target, Node* parent, std::size_t index = 0);
164
165 /**
166 * @brief Evaluate only the macros
167 *
168 * @param node
169 * @param is_not_body true if the method is run on a non-body code (eg a condition of an if-macro)
170 * @return Node
171 */
172 Node evaluate(Node& node, bool is_not_body = false);
173
174 /**
175 * @brief Check if a node can be evaluated to true
176 *
177 * @param node
178 * @return true
179 * @return false
180 */
181 bool isTruthy(const Node& node);
182
183 /**
184 * @brief Throw a macro processing error
185 *
186 * @param message the error
187 * @param node the node in which there is an error
188 */
189 [[noreturn]] void throwMacroProcessingError(const std::string& message, const Node& node);
190 };
191}
192
193#endif
The base class for all MacroExecutors.
Defines tools to handle macro definitions.
AST node used by the parser, optimizer and compiler.
The Chain of Responsibility class for running nodes through MacroExecutors.
The class that initializes the MacroExecutors.
Definition: Pipeline.hpp:29
A class that applies macros in a Node.
Definition: Executor.hpp:28
The class handling the macros definitions and calls, given an AST.
Definition: Processor.hpp:31
void removeBegin(Node &node, std::size_t &i)
Remove a begin block added by a macro.
Definition: Processor.cpp:560
void process(Node &node, unsigned depth)
Register macros in scopes and apply them as needed.
Definition: Processor.cpp:133
void unify(const std::unordered_map< std::string, Node > &map, Node &target, Node *parent, std::size_t index=0)
Unify a target node with a given map symbol => replacement node, recursively.
Definition: Processor.cpp:218
const Node & ast() const noexcept
Return the modified AST.
Definition: Processor.cpp:46
MacroExecutorPipeline m_executor_pipeline
Definition: Processor.hpp:62
void recurApply(Node &node)
Recursively apply macros on a given node.
Definition: Processor.cpp:541
std::vector< std::string > m_predefined_macros
Already existing macros, non-keywords, non-builtins.
Definition: Processor.hpp:63
void registerMacro(Node &node)
Registers macros based on their type.
Definition: Processor.cpp:51
Node evaluate(Node &node, bool is_not_body=false)
Evaluate only the macros.
Definition: Processor.cpp:245
const Node * findNearestMacro(const std::string &name) const
Find the nearest macro matching a given name.
Definition: Processor.cpp:503
Node m_ast
The modified AST.
Definition: Processor.hpp:60
bool isTruthy(const Node &node)
Check if a node can be evaluated to true.
Definition: Processor.cpp:485
bool hadBegin(const Node &node)
Check if a given node is a list node, and starts with a Begin.
Definition: Processor.cpp:552
void throwMacroProcessingError(const std::string &message, const Node &node)
Throw a macro processing error.
Definition: Processor.cpp:621
std::unordered_map< std::string, Node > m_defined_functions
Definition: Processor.hpp:64
bool isConstEval(const Node &node) const
Check if a node can be evaluated at compile time.
Definition: Processor.cpp:580
bool isPredefined(const std::string &symbol)
Check if a given symbol is a predefined macro or not.
Definition: Processor.cpp:531
bool applyMacro(Node &node)
Apply a macro on a given node.
Definition: Processor.cpp:213
void feed(const Node &ast)
Send the complete AST (after the inclusions and stuff), and work on it.
Definition: Processor.cpp:30
std::vector< MacroScope > m_macros
Handling macros in a scope fashion.
Definition: Processor.hpp:61
void registerFuncDef(Node &node)
Registers a function definition node.
Definition: Processor.cpp:115
unsigned m_debug
The debug level.
Definition: Processor.hpp:58
void deleteNearestMacro(const std::string &name)
Find the nearest macro matching a given name and delete it.
Definition: Processor.cpp:516
A node of an Abstract Syntax Tree for ArkScript.
Definition: Node.hpp:29