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