ArkScript
A small, lisp-inspired, functional scripting language
Entity.hpp
Go to the documentation of this file.
1/**
2 * @file Entity.hpp
3 * @author Lexy Plateau (lexplt.dev@gmail.com)
4 * @brief An entity in the IR is a bundle of information
5 * @date 2024-10-05
6 *
7 * @copyright Copyright (c) 2024-2026
8 *
9 */
10
11#ifndef ARK_COMPILER_INTERMEDIATEREPRESENTATION_ENTITY_HPP
12#define ARK_COMPILER_INTERMEDIATEREPRESENTATION_ENTITY_HPP
13
14#include <cinttypes>
15#include <vector>
16#include <string>
17#include <optional>
18#include <algorithm>
19
22
24{
25 enum class Kind
26 {
27 Label,
28 Goto,
30 Opcode,
33 };
34
35 using label_t = std::size_t;
36
37 /// The maximum value an argument can have when an IR entity has two arguments
38 constexpr uint16_t MaxValueForDualArg = 0x0fff;
39 constexpr uint16_t MaxValueForSmallNumber = 0x0800;
41
42 constexpr std::string_view AnonymousBlockName = "#anonymous";
43
44 class Entity
45 {
46 public:
47 /**
48 * @brief Create a new IR Entity
49 *
50 * @param kind kind of entity (label, jump, instruction...)
51 */
52 explicit Entity(Kind kind);
53
54 /**
55 * @brief Create a new IR Entity
56 *
57 * @param inst instruction
58 * @param arg optional argument, default to 0
59 */
60 explicit Entity(Instruction inst, uint16_t arg = 0);
61
62 /**
63 * @brief Create a new IR Entity
64 *
65 * @param inst instruction that takes two arguments
66 * @param primary_arg first argument on 12 bits
67 * @param secondary_arg second argument on 12 bits
68 */
69 Entity(Instruction inst, uint16_t primary_arg, uint16_t secondary_arg);
70
71 /**
72 * @brief Create a new IR Entity
73 *
74 * @param inst instruction that takes three arguments
75 * @param inst2 first argument on 8 bits
76 * @param inst3 second argument on 8 bits
77 * @param inst4 third argument on 8 bits
78 */
79 Entity(Instruction inst, uint8_t inst2, uint8_t inst3, uint8_t inst4);
80
81 void replaceInstruction(Instruction replacement);
82
83 void replaceLabel(label_t replacement);
84
85 /**
86 * @brief Create a new Label IR Entity
87 *
88 * @param value value for the label
89 * @return Entity
90 */
91 static Entity Label(label_t value);
92
93 /**
94 * @brief Create a new Goto IR Entity
95 *
96 * @param label label the goto relates to
97 * @param inst jump instruction to use, default to JUMP
98 * @return Entity
99 */
100 static Entity Goto(const Entity& label, Instruction inst = Instruction::JUMP);
101
102 /**
103 * @brief Create a new Goto IR Entity
104 *
105 * @param label label the goto relates to
106 * @param inst jump instruction to use
107 * @param primary_arg argument for the jump instruction
108 * @return Entity
109 */
110 static Entity GotoWithArg(const Entity& label, Instruction inst, uint16_t primary_arg);
111
112 /**
113 * @brief Create a new Goto IR Entity
114 *
115 * @param label label the goto relates to
116 * @param cond true to use POP_JUMP_IF_TRUE, false to use POP_JUMP_IF_FALSE
117 * @return Entity
118 */
119 static Entity GotoIf(const Entity& label, bool cond);
120
121 /**
122 * @brief Return the bytecode representation of the IR Entity if it's an Opcode
123 *
124 * @return Word
125 */
126 [[nodiscard]] Word bytecode() const;
127
128 /**
129 * @brief Check if the Entity has a label attached
130 *
131 * @return bool
132 */
133 [[nodiscard]] bool hasLabel() const
134 {
135 switch (m_kind)
136 {
137 case Kind::Label:
138 [[fallthrough]];
139 case Kind::Goto:
140 [[fallthrough]];
142 return true;
143
144 case Kind::Opcode:
145 [[fallthrough]];
147 [[fallthrough]];
149 return false;
150 }
151
152 return false;
153 }
154
155 /**
156 * @brief Return the label of the IR Entity
157 *
158 * @return label_t
159 */
160 [[nodiscard]] label_t label() const { return m_label; }
161
162 /**
163 * @brief Return the kind of IR Entity
164 * @see Kind
165 * @return Kind
166 */
167 [[nodiscard]] Kind kind() const { return m_kind; }
168
169 /**
170 * @brief Return the underlying instruction of the IR Entity
171 *
172 * @return Instruction
173 */
174 [[nodiscard]] Instruction inst() const { return m_inst; }
175
176 /**
177 * @brief Return the primary argument of the IR Entity (can be 0 if the argument isn't used)
178 * @details The argument is on 16 bits for standard instructions ; for super instructions, only the first 12 bits are used
179 * @return uint16_t
180 */
181 [[nodiscard]] uint16_t primaryArg() const { return m_primary_arg; }
182
183 /**
184 * @brief Return the second argument of the IR Entity
185 * @details The argument is for super instructions, where only the first 12 bits are used
186 * @return uint16_t
187 */
188 [[nodiscard]] uint16_t secondaryArg() const { return m_secondary_arg; }
189
190 /**
191 * @brief Return the third argument of the IR Entity
192 * @details The argument is for special super instructions, where only the first 8 bits are used (for all arguments)
193 * @return uint16_t
194 */
195 [[nodiscard]] uint16_t tertiaryArg() const { return m_tertiary_arg; }
196
197 /**
198 * @brief Set the source location for an IR Entity, which is used to generate the file loc table
199 *
200 * @param filename
201 * @param line
202 */
203 void setSourceLocation(const std::string& filename, std::size_t line);
204
205 void setRelatedResourceId(std::optional<uint16_t> id);
206
207 [[nodiscard]] bool hasValidSourceLocation() const { return !m_metadata.source_file.empty(); }
208
209 [[nodiscard]] const std::string& filename() const { return m_metadata.source_file; }
210
211 [[nodiscard]] std::size_t sourceLine() const { return m_metadata.source_line; }
212
213 /**
214 * @brief Return the related constant/symbol id an IR Entity refers to (only populated for LOAD_FAST_BY_INDEX, CALL_SYMBOL_BY_INDEX, CALL_SYMBOL, and CALL)
215 *
216 * @return std::optional<uint16_t>
217 */
218 [[nodiscard]] std::optional<uint16_t> relatedResourceId() const { return m_metadata.related_res_id; }
219
220 private:
223
225 uint16_t m_primary_arg { 0 };
226 uint16_t m_secondary_arg { 0 };
227 uint16_t m_tertiary_arg { 0 };
228
229 struct
230 {
231 std::string source_file;
232 std::size_t source_line { 0 };
233 std::optional<uint16_t> related_res_id; ///< Used by a few instructions to know the original symbol/constant id and deoptimize when necessary
235 };
236
237 /**
238 * @brief Block of IR entities, with attached metadata
239 */
240 struct Block
241 {
242 using vec_t = std::vector<Entity>;
243
244 struct Metadata
245 {
246 std::optional<std::string> name;
247 std::size_t argument_count { 0 };
248 std::size_t addr { 0 };
249 bool is_closure { false };
250 bool is_recursive { false };
251 bool is_simple { false }; ///< Calls only builtin and operators, no user functions/C++ functions
252 bool is_mutating_args { false };
255
256 /**
257 * @brief Create a new empty IR::Block with the same metadata as the source block
258 *
259 * @param source source block
260 * @return Block
261 */
262 static Block InitWithMetadata(const Block& source)
263 {
264 return Block {
265 .metadata = source.metadata,
266 .data = {}
267 };
268 }
269
270 [[nodiscard]] std::string debugName() const
271 {
272 return metadata.name.value_or(std::string(AnonymousBlockName));
273 }
274
275 [[nodiscard]] std::string metadataRepr() const
276 {
277 std::string flags;
279 flags += "recursive";
281 flags += std::string(flags.empty() ? "" : " ") + "simple";
283 flags += std::string(flags.empty() ? "" : " ") + "mutating";
284
286 flags += std::string(flags.empty() ? "" : " ") + "closure";
287 else
288 flags += std::string(flags.empty() ? "" : " ") + "function";
289 return flags;
290 }
291
292 [[nodiscard]] std::size_t instructionCount() const
293 {
294 const auto length = std::ranges::count_if(data, [](const auto& a) {
295 return a.kind() != IR::Kind::Label;
296 });
297
298 if (length <= 0)
299 return 0;
300 return static_cast<std::size_t>(length);
301 }
302 };
303}
304
305#endif // ARK_COMPILER_INTERMEDIATEREPRESENTATION_ENTITY_HPP
The different instructions used by the compiler and virtual machine.
Describe an instruction and its immediate argument.
uint16_t secondaryArg() const
Return the second argument of the IR Entity.
Definition Entity.hpp:188
std::optional< uint16_t > related_res_id
Used by a few instructions to know the original symbol/constant id and deoptimize when necessary.
Definition Entity.hpp:233
Kind kind() const
Return the kind of IR Entity.
Definition Entity.hpp:167
label_t label() const
Return the label of the IR Entity.
Definition Entity.hpp:160
bool hasLabel() const
Check if the Entity has a label attached.
Definition Entity.hpp:133
uint16_t tertiaryArg() const
Return the third argument of the IR Entity.
Definition Entity.hpp:195
Entity(Kind kind)
Create a new IR Entity.
Definition Entity.cpp:5
Instruction inst() const
Return the underlying instruction of the IR Entity.
Definition Entity.hpp:174
std::size_t sourceLine() const
Definition Entity.hpp:211
void replaceLabel(label_t replacement)
Definition Entity.cpp:30
static Entity GotoIf(const Entity &label, bool cond)
Create a new Goto IR Entity.
Definition Entity.cpp:62
void setRelatedResourceId(std::optional< uint16_t > id)
Definition Entity.cpp:88
bool hasValidSourceLocation() const
Definition Entity.hpp:207
uint16_t primaryArg() const
Return the primary argument of the IR Entity (can be 0 if the argument isn't used)
Definition Entity.hpp:181
void setSourceLocation(const std::string &filename, std::size_t line)
Set the source location for an IR Entity, which is used to generate the file loc table.
Definition Entity.cpp:82
Word bytecode() const
Return the bytecode representation of the IR Entity if it's an Opcode.
Definition Entity.cpp:67
const std::string & filename() const
Definition Entity.hpp:209
void replaceInstruction(Instruction replacement)
Definition Entity.cpp:25
std::optional< uint16_t > relatedResourceId() const
Return the related constant/symbol id an IR Entity refers to (only populated for LOAD_FAST_BY_INDEX,...
Definition Entity.hpp:218
struct Ark::internal::IR::Entity::@0 m_metadata
constexpr uint16_t MaxValueForSmallNumber
Definition Entity.hpp:39
constexpr uint16_t MaxValueForDualArg
The maximum value an argument can have when an IR entity has two arguments.
Definition Entity.hpp:38
std::size_t label_t
Definition Entity.hpp:35
constexpr std::string_view AnonymousBlockName
Definition Entity.hpp:42
Instruction
The different bytecodes are stored here.
std::optional< std::string > name
Definition Entity.hpp:246
bool is_simple
Calls only builtin and operators, no user functions/C++ functions.
Definition Entity.hpp:251
Block of IR entities, with attached metadata.
Definition Entity.hpp:241
std::size_t instructionCount() const
Definition Entity.hpp:292
static Block InitWithMetadata(const Block &source)
Create a new empty IR::Block with the same metadata as the source block.
Definition Entity.hpp:262
std::string metadataRepr() const
Definition Entity.hpp:275
struct Ark::internal::IR::Block::Metadata metadata
std::vector< Entity > vec_t
Definition Entity.hpp:242
std::string debugName() const
Definition Entity.hpp:270