ArkScript
A small, fast, functional and scripting language for video games
Value.hpp
Go to the documentation of this file.
1/**
2 * @file Value.hpp
3 * @author Default value type handled by the virtual machine
4 * @brief
5 * @version 0.3
6 * @date 2020-10-27
7 *
8 * @copyright Copyright (c) 2020-2021
9 *
10 */
11
12#ifndef ARK_VM_VALUE_HPP
13#define ARK_VM_VALUE_HPP
14
15#include <vector>
16#include <variant>
17#include <string> // for conversions
18#include <cinttypes>
19#include <iostream>
20#include <memory>
21#include <functional>
22#include <utility>
23#include <Ark/String.hpp> // our string implementation
24#include <array>
25
28#include <Ark/Platform.hpp>
29#include <Ark/Profiling.hpp>
30
31namespace Ark
32{
33 class VM;
34
35 // Note from the creator: we can have at most 0b01111111 (127) different types
36 // because type index is stored on the 7 right most bits of a uint8_t in the class Value.
37 // Order is also important because we are doing some optimizations to check ranges
38 // of types based on their integer values.
39 enum class ValueType
40 {
41 List = 0,
42 Number = 1,
43 String = 2,
44 PageAddr = 3,
45 CProc = 4,
46 Closure = 5,
47 User = 6,
48
49 Nil = 7,
50 True = 8,
51 False = 9,
52 Undefined = 10,
53 Reference = 11,
54 InstPtr = 12,
55
56 Any = 99
57 };
58
59 const std::array<std::string, 13> types_to_str = {
60 "List", "Number", "String", "Function",
61 "CProc", "Closure", "UserType", "Nil",
62 "Bool", "Bool", "Undefined", "Reference",
63 "InstPtr"
64 };
65
66// for debugging purposes only
67#ifdef ARK_PROFILER_COUNT
68 extern unsigned value_creations, value_copies, value_moves;
69#endif
70
72 {
73 public:
74 using ProcType = Value (*)(std::vector<Value>&, VM*); // std::function<Value (std::vector<Value>&, VM*)>
75 using Iterator = std::vector<Value>::iterator;
76 using ConstIterator = std::vector<Value>::const_iterator;
77
78 using Value_t = std::variant<
79 double, // 8 bytes
80 String, // 16 bytes
81 internal::PageAddr_t, // 2 bytes
82 ProcType, // 8 bytes
83 internal::Closure, // 24 bytes
84 UserType, // 24 bytes
85 std::vector<Value>, // 24 bytes
86 Value* // 8 bytes
87 >; // +8 bytes overhead
88 // total 32 bytes
89
90 /**
91 * @brief Construct a new Value object
92 *
93 */
94 Value() noexcept;
95
96 /**
97 * @brief Construct a new Value object
98 *
99 * @param type the value type which is going to be held
100 */
101 explicit Value(ValueType type) noexcept;
102
103 /**
104 * @brief Construct a new Value object
105 * @details Use at your own risks. Asking for a value type N and putting a non-matching value
106 * will result in errors at runtime.
107 *
108 * @tparam T
109 * @param type value type wanted
110 * @param value value needed
111 */
112 template <typename T>
113 Value(ValueType type, T&& value) noexcept :
114 m_const_type(static_cast<uint8_t>(type)),
115 m_value(std::move(value))
116 {}
117
118#ifdef ARK_PROFILER_COUNT
119 Value(const Value& val) noexcept;
120 Value(Value&& other) noexcept;
121 Value& operator=(const Value& other) noexcept;
122#endif
123
124 /**
125 * @brief Construct a new Value object as a Number
126 *
127 * @param value
128 */
129 explicit Value(int value) noexcept;
130
131 /**
132 * @brief Construct a new Value object as a Number
133 *
134 * @param value
135 */
136 explicit Value(float value) noexcept;
137
138 /**
139 * @brief Construct a new Value object as a Number
140 *
141 * @param value
142 */
143 explicit Value(double value) noexcept;
144
145 /**
146 * @brief Construct a new Value object as a String
147 *
148 * @param value
149 */
150 explicit Value(const std::string& value) noexcept;
151
152 /**
153 * @brief Construct a new Value object as a String
154 *
155 * @param value
156 */
157 explicit Value(const String& value) noexcept;
158
159 /**
160 * @brief Construct a new Value object as a String
161 *
162 * @param value
163 */
164 explicit Value(const char* value) noexcept;
165
166 /**
167 * @brief Construct a new Value object as a Function
168 *
169 * @param value
170 */
171 explicit Value(internal::PageAddr_t value) noexcept;
172
173 /**
174 * @brief Construct a new Value object from a C++ function
175 *
176 * @param value
177 */
178 explicit Value(Value::ProcType value) noexcept;
179
180 /**
181 * @brief Construct a new Value object as a List
182 *
183 * @param value
184 */
185 explicit Value(std::vector<Value>&& value) noexcept;
186
187 /**
188 * @brief Construct a new Value object as a Closure
189 *
190 * @param value
191 */
192 explicit Value(internal::Closure&& value) noexcept;
193
194 /**
195 * @brief Construct a new Value object as a UserType
196 *
197 * @param value
198 */
199 explicit Value(UserType&& value) noexcept;
200
201 /**
202 * @brief Construct a new Value object as a reference to an internal object
203 *
204 * @param ref
205 */
206 explicit Value(Value* ref) noexcept;
207
208 /**
209 * @brief Return the value type
210 *
211 * @return ValueType
212 */
213 inline ValueType valueType() const noexcept;
214
215 /**
216 * @brief Check if a function is held
217 *
218 * @return true on success
219 * @return false on failure
220 */
221 inline bool isFunction() const noexcept;
222
223 /**
224 * @brief Return the stored number
225 *
226 * @return double
227 */
228 inline double number() const;
229
230 /**
231 * @brief Return the stored string
232 *
233 * @return const String&
234 */
235 inline const String& string() const;
236
237 /**
238 * @brief Return the stored list
239 *
240 * @return const std::vector<Value>&
241 */
242 inline const std::vector<Value>& constList() const;
243
244 /**
245 * @brief Return the stored user type
246 *
247 * @return const UserType&
248 */
249 inline const UserType& usertype() const;
250
251 /**
252 * @brief Return the stored list as a reference
253 *
254 * @return std::vector<Value>&
255 */
256 std::vector<Value>& list();
257
258 /**
259 * @brief Return the stored string as a reference
260 *
261 * @return String&
262 */
263 String& stringRef();
264
265 /**
266 * @brief Return the stored user type as a reference
267 *
268 * @return UserType&
269 */
270 UserType& usertypeRef();
271
272 /**
273 * @brief Return the stored internal object reference
274 *
275 * @return Value*
276 */
277 Value* reference() const;
278
279 /**
280 * @brief Add an element to the list held by the value (if the value type is set to list)
281 *
282 * @param value
283 */
284 void push_back(const Value& value);
285
286 /**
287 * @brief Add an element to the list held by the value (if the value type is set to list)
288 *
289 * @param value
290 */
291 void push_back(Value&& value);
292
293 friend ARK_API std::ostream& operator<<(std::ostream& os, const Value& V) noexcept;
294 friend ARK_API_INLINE bool operator==(const Value& A, const Value& B) noexcept;
295 friend ARK_API_INLINE bool operator<(const Value& A, const Value& B) noexcept;
296 friend ARK_API_INLINE bool operator!(const Value& A) noexcept;
297
298 friend class Ark::VM;
299
300 private:
301 uint8_t m_const_type; ///< First bit if for constness, right most bits are for type
302 Value_t m_value;
303
304 // private getters only for the virtual machine
305
306 /**
307 * @brief Return the page address held by the value
308 *
309 * @return internal::PageAddr_t
310 */
311 inline internal::PageAddr_t pageAddr() const;
312
313 /**
314 * @brief Return the C Function held by the value
315 *
316 * @return const ProcType&
317 */
318 inline const ProcType& proc() const;
319
320 /**
321 * @brief Return the closure held by the value
322 *
323 * @return const internal::Closure&
324 */
325 inline const internal::Closure& closure() const;
326
327 /**
328 * @brief Return a reference to the closure held by the value
329 *
330 * @return internal::Closure&
331 */
332 internal::Closure& refClosure();
333
334 /**
335 * @brief Check if the value is const or not
336 *
337 * @return true
338 * @return false
339 */
340 inline bool isConst() const noexcept;
341
342 /**
343 * @brief Set the Const object
344 *
345 * @param value
346 */
347 inline void setConst(bool value) noexcept;
348 };
349
350#include "inline/Value.inl"
351}
352
353#endif
Subtype of the value type, handling closures.
ArkScript configuration macros.
#define ARK_API_INLINE
Definition: Platform.hpp:51
#define ARK_API
Definition: Platform.hpp:41
Subtype of the value, capable of handling any C++ type.
A class to be use C++ objects in ArkScript.
Definition: UserType.hpp:50
The ArkScript virtual machine, executing ArkScript bytecode.
Definition: VM.hpp:46
Value(*)(std::vector< Value > &, VM *) ProcType
Definition: Value.hpp:74
std::variant< double, String, internal::PageAddr_t, ProcType, internal::Closure, UserType, std::vector< Value >, Value * > Value_t
Definition: Value.hpp:87
std::vector< Value >::iterator Iterator
Definition: Value.hpp:75
ValueType valueType() const noexcept
Return the value type.
std::vector< Value >::const_iterator ConstIterator
Definition: Value.hpp:76
Closure management.
Definition: Closure.hpp:40
uint16_t PageAddr_t
Definition: Closure.hpp:33
Definition: Builtins.hpp:21
ValueType
Definition: Value.hpp:40
const std::array< std::string, 13 > types_to_str
Definition: Value.hpp:59