ArkScript
A small, fast, functional and scripting language for video games
ASTLowerer.hpp
Go to the documentation of this file.
1/**
2 * @file ASTLowerver.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief ArkScript compiler is in charge of transforming the AST into IR
5 * @date 2020-10-27
6 *
7 * @copyright Copyright (c) 2020-2025
8 *
9 */
10
11#ifndef ARK_COMPILER_LOWERER_ASTLOWERER_HPP
12#define ARK_COMPILER_LOWERER_ASTLOWERER_HPP
13
14#include <vector>
15#include <string>
16#include <cinttypes>
17#include <optional>
18
19#include <Ark/Platform.hpp>
20#include <Ark/Logger.hpp>
26
27namespace Ark::internal
28{
29 class State;
30 class Welder;
31
32 /**
33 * @brief The ArkScript AST to IR compiler
34 *
35 */
36 class ARK_API ASTLowerer final
37 {
38 public:
39 /**
40 * @brief Construct a new ASTLowerer object
41 *
42 * @param debug the debug level
43 */
44 explicit ASTLowerer(unsigned debug);
45
46 /**
47 * @brief Start the compilation
48 *
49 * @param ast
50 */
51 void process(const Node& ast);
52
53 /**
54 * @brief Return the IR blocks (one per scope)
55 *
56 * @return const std::vector<Block>&
57 */
58 [[nodiscard]] const std::vector<IR::Block>& intermediateRepresentation() const noexcept;
59
60 /**
61 * @brief Return the symbol table pre-computed
62 *
63 * @return const std::vector<std::string>&
64 */
65 [[nodiscard]] const std::vector<std::string>& symbols() const noexcept;
66
67 /**
68 * @brief Return the value table pre-computed
69 *
70 * @return const std::vector<ValTableElem>&
71 */
72 [[nodiscard]] const std::vector<ValTableElem>& values() const noexcept;
73
74 private:
75 struct Page
76 {
77 std::size_t index;
78 bool is_temp;
79 };
80
82
83 // tables: symbols, values, plugins and codes
84 std::vector<std::string> m_symbols;
85 std::vector<ValTableElem> m_values;
86 std::vector<IR::Block> m_code_pages;
87 std::vector<IR::Block> m_temp_pages; ///< we need temporary code pages for some compilations passes
88 IR::label_t m_current_label = 0;
89
91
92 /**
93 * @brief helper functions to get a temp or finalized code page
94 *
95 * @param page page descriptor
96 * @return std::vector<IR::Block>&
97 */
98 IR::Block& page(const Page page) noexcept
99 {
100 if (!page.is_temp)
101 return m_code_pages[page.index];
102 return m_temp_pages[page.index];
103 }
104
105 /**
106 * @brief Checking if a symbol is an operator
107 *
108 * @param name symbol name
109 * @return std::optional<Instruction> operator instruction
110 */
111 static std::optional<Instruction> getOperator(const std::string& name) noexcept;
112
113 /**
114 * @brief Checking if a symbol is a builtin
115 *
116 * @param name symbol name
117 * @return std::optional<uint16_t> builtin number
118 */
119 static std::optional<uint16_t> getBuiltin(const std::string& name) noexcept;
120
121 /**
122 * @brief Checking if a symbol is a list instruction
123 *
124 * @param name
125 * @return std::optional<Instruction> list instruction
126 */
127 static std::optional<Instruction> getListInstruction(const std::string& name) noexcept;
128
129 /**
130 * Checks if a node is a list and has a keyboard as its first node, indicating if it's producing a value on the stack or not
131 * @param node node to check
132 * @return true if the node produces an output on the stack (fun, if, begin)
133 * @return false otherwise (let, mut, set, while, import, del)
134 */
135 static bool nodeProducesOutput(const Node& node);
136
137 /**
138 * @brief Check if a given instruction is unary (takes only one argument)
139 *
140 * @param inst
141 * @return true the instruction is unary
142 * @return false
143 */
144 static bool isUnaryInst(Instruction inst) noexcept;
145
146 /**
147 * @brief Check if a given instruction is ternary (takes three arguments)
148 *
149 * @param inst
150 * @return true the instruction is ternary
151 * @return false
152 */
153 static bool isTernaryInst(Instruction inst) noexcept;
154
155 /**
156 * @brief Display a warning message
157 *
158 * @param message
159 * @param node
160 */
161 static void warning(const std::string& message, const Node& node);
162
163 /**
164 * @brief Throw a nice error message
165 *
166 * @param message
167 * @param node
168 */
169 [[noreturn]] static void buildAndThrowError(const std::string& message, const Node& node);
170
171 /**
172 * @brief Compile an expression (a node) recursively
173 *
174 * @param x the Node to compile
175 * @param p the current page number we're on
176 * @param is_result_unused
177 * @param is_terminal
178 * @param var_name
179 */
180 void compileExpression(const Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name = "");
181
182 void compileSymbol(const Node& x, Page p, bool is_result_unused);
183 void compileListInstruction(const Node& c0, const Node& x, Page p, bool is_result_unused);
184 void compileIf(const Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name);
185 void compileFunction(const Node& x, Page p, bool is_result_unused, const std::string& var_name);
186 void compileLetMutSet(Keyword n, const Node& x, Page p);
187 void compileWhile(const Node& x, Page p);
188 void compilePluginImport(const Node& x, Page p);
189 void handleCalls(const Node& x, Page p, bool is_result_unused, bool is_terminal, const std::string& var_name);
190
191 /**
192 * @brief Register a given node in the symbol table
193 * @details Can throw if the table is full
194 *
195 * @param sym
196 * @return uint16_t
197 */
198 uint16_t addSymbol(const Node& sym);
199
200 /**
201 * @brief Register a given node in the value table
202 * @details Can throw if the table is full
203 *
204 * @param x
205 * @return uint16_t
206 */
207 uint16_t addValue(const Node& x);
208
209 /**
210 * @brief Register a page id (function reference) in the value table
211 * @details Can throw if the table is full
212 *
213 * @param page_id
214 * @param current A reference to the current node, for context
215 * @return std::size_t
216 */
217 uint16_t addValue(std::size_t page_id, const Node& current);
218 };
219}
220
221#endif
An entity in the IR is a bundle of information.
The different instructions used by the compiler and virtual machine.
Track locals at compile.
Internal logger.
#define ARK_API
Definition Module.hpp:28
AST node used by the parser, optimizer and compiler.
ArkScript configuration macros.
The basic value type handled by the compiler.
The ArkScript AST to IR compiler.
std::vector< ValTableElem > m_values
std::vector< IR::Block > m_temp_pages
we need temporary code pages for some compilations passes
std::vector< IR::Block > m_code_pages
std::vector< std::string > m_symbols
LocalsLocator m_locals_locator
IR::Block & page(const Page page) noexcept
helper functions to get a temp or finalized code page
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:30
std::vector< Entity > Block
Definition Entity.hpp:83
std::size_t label_t
Definition Entity.hpp:33
Keyword
The different keywords available.
Definition Common.hpp:75
Instruction
The different bytecodes are stored here.