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